0

そのため、カスタムリストビューとアダプタをコーディングして、リストビューに独自のカスタムアイテム行を表示しています。選択モードを切り替える機能を備えた機能リストビューがあり、リストビュー行xmlファイルのカスタム相対レイアウトを介してチェック可能なリスト行アイテムがあります。今、私はドラッグアンドドロップ機能を追加して、Androidv3.0以降のターゲットコードでリストビューアイテムを再利用しようとしています。ドラッグアンドドロップの優れた実装についてこのサイトで この投稿に出くわし、現在プロジェクトに追加しています。Githubソースはこちら

プロジェクトをコンパイルすると、投稿のタイトルに記載されているキャスト例外エラーが発生し、それを乗り越えるのに問題があります。チェック可能を実装するカスタム相対レイアウトなのか、ドラッグアンドドロップ用のカスタムリストビューなのかがわかりません。これがログ出力です。

08-02 09:53:37.065: W/dalvikvm(16119): threadid=1: thread exiting with uncaught exception (group=0x40c6f1f8)
08-02 09:53:37.090: E/AndroidRuntime(16119): FATAL EXCEPTION: main
08-02 09:53:37.090: E/AndroidRuntime(16119): java.lang.ClassCastException: android.widget.RelativeLayout cannot be cast to au.drp.mylistview.draganddrop.DragSortListView
08-02 09:53:37.090: E/AndroidRuntime(16119):    at au.drp.mylistview.MyListViewAdapter.getView(MyListViewAdapter.java:62)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at au.drp.mylistview.draganddrop.DragSortListView$AdapterWrapper.getView(DragSortListView.java:270)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.widget.AbsListView.obtainView(AbsListView.java:2424)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.widget.ListView.makeAndAddView(ListView.java:1781)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.widget.ListView.fillDown(ListView.java:679)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.widget.ListView.fillFromTop(ListView.java:739)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.widget.ListView.layoutChildren(ListView.java:1632)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at au.drp.mylistview.draganddrop.DragSortListView.layoutChildren(DragSortListView.java:961)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.widget.AbsListView.onLayout(AbsListView.java:2254)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.view.View.layout(View.java:11467)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.view.ViewGroup.layout(ViewGroup.java:4237)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.view.View.layout(View.java:11467)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.view.ViewGroup.layout(ViewGroup.java:4237)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1644)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1502)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.widget.LinearLayout.onLayout(LinearLayout.java:1415)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.view.View.layout(View.java:11467)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.view.ViewGroup.layout(ViewGroup.java:4237)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.view.View.layout(View.java:11467)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.view.ViewGroup.layout(ViewGroup.java:4237)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1721)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2678)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.os.Looper.loop(Looper.java:137)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at android.app.ActivityThread.main(ActivityThread.java:4514)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at java.lang.reflect.Method.invokeNative(Native Method)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at java.lang.reflect.Method.invoke(Method.java:511)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
08-02 09:53:37.090: E/AndroidRuntime(16119):    at dalvik.system.NativeStart.main(Native Method)

ただし、DragSortListViewクラスのエラーセクションを変更することで、結果を変更できますが、相対レイアウトタイプとリストビューの間で例外キャストエラーが発生することがわかりました。私が話しているこのセクションは、DragSortListViewクラスの次のgetViewコードです。そして、私が変更しようとしたのは、RelativeLayout変数型であり、CheckableRelativelayoutにキャストします。

注:コード「//このステートメントコードが好きではありません」の私のコメントはエラー行です

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

  RelativeLayout v;
  View child;

  //Log.d("mobeta", "getView: position="+position+" convertView="+convertView);
  if (convertView != null) {

    v = (RelativeLayout) convertView;
    View oldChild = v.getChildAt(0);

    //child = super.getView(position, oldChild, v);
    child = mAdapter.getView(position, oldChild, v);
    if (child != oldChild) {
      // shouldn't get here if user is reusing convertViews properly
      v.removeViewAt(0);
      v.addView(child);
      // check that tags are equal too?
      v.setTag(child.findViewById(R.id.drag));
    }

  } else {
    AbsListView.LayoutParams params =
      new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    v = new RelativeLayout(getContext());
    v.setLayoutParams(params);
    child = mAdapter.getView(position, null, v);  //DOES NOT LIKE THIS STATEMENT CODE
    v.addView(child);

    v.setTag(child.findViewById(R.id.drag));
  }

そして、これが私のアダプタクラスのgetViewです

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // This is how you would determine if this particular item is checked
    // when the view gets created
    // --       
    final DragSortListView lv = (DragSortListView) parent;  // DOES NOT LIKE THIS STATEMENT CODE
    final boolean isChecked = lv.isItemChecked(position);

    // Get the listview Choice Mode
    //
    final int selectionMode = lv.getChoiceMode();

    // The item we want to get the view for
    // --
    Item currentItem = getItem(position);

    // Re-use the view if possible (recycle)
    // --
    ViewHolder holder = null;
    //final View mView = mInflator.inflate(R.layout.listview_row, null);
    if (convertView == null) {
        convertView = mInflator.inflate(R.layout.listview_row, null);
        holder = new ViewHolder();
        holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
        holder.txtDescription = (TextView) convertView.findViewById(R.id.description);
        holder.txtSessionCount = (TextView) convertView.findViewById(R.id.session_count);
        holder.listThumbnailImage = (ImageView) convertView.findViewById(R.id.list_image);
        holder.listStatusIndicatorImage = (ImageView) convertView.findViewById(R.id.drag);
        holder.Checkbox = (InertCheckBox) convertView.findViewById(R.id.inertCheckBox);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder)convertView.getTag();
    }
    // End recycler
    //

    holder.txtTitle.setText(currentItem.getTitle());
    holder.txtDescription.setText(currentItem.getDescription());
    holder.txtSessionCount.setText(currentItem.getSessionCount());
    holder.listThumbnailImage.setImageBitmap((Bitmap) currentItem.getThumbnailImage());

    // Now the Status ImageView and/or the InertCheckBox view
    switch (selectionMode) {
    case ListView.CHOICE_MODE_NONE:
        holder.Checkbox.setVisibility(InertCheckBox.INVISIBLE);
        holder.listStatusIndicatorImage.setVisibility(ImageView.VISIBLE);

        holder.listStatusIndicatorImage.setAdjustViewBounds(true);
        holder.listStatusIndicatorImage.setMaxHeight(48);
        holder.listStatusIndicatorImage.setMaxWidth(48);
        if (!dndMode) {
            holder.listStatusIndicatorImage.setImageBitmap((Bitmap) currentItem.getListIndicatorImage());

        } else {
            holder.listStatusIndicatorImage.setImageResource(R.drawable.list_icon_reorder_holo_dark);
        }   
        holder.listStatusIndicatorImage.setScaleType(ScaleType.CENTER_INSIDE);
        break;
    case ListView.CHOICE_MODE_SINGLE: case ListView.CHOICE_MODE_MULTIPLE:
        MyListViewAdapter.dndMode = false;
        holder.listStatusIndicatorImage.setVisibility(ImageView.INVISIBLE);
        holder.Checkbox.setVisibility(InertCheckBox.VISIBLE);
        if (!chkbxDelete) {
            holder.Checkbox.setButtonDrawable(R.drawable.checkbox);
        } else {
            holder.Checkbox.setButtonDrawable(R.drawable.checkboxdelete);
        }
        holder.Checkbox.setChecked(isChecked);
        break;
    }           

    return convertView;
}

リストビューの行レイアウト

<?xml version="1.0" encoding="utf-8"?>
<au.drp.mylistview.widget.CheckableRelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:drp="http://schemas.android.com/apk/res/au.drp.mylistview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/list_selector"
android:orientation="horizontal"
android:padding="2dip" >

<!-- ListRow Left side Thumbnail image -->

<LinearLayout
    android:id="@+id/thumbnail"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_marginRight="5dip"
    android:gravity="center_vertical"
    android:padding="3dip" >

    <ImageView
        android:id="@+id/list_image"
        android:layout_width="50dip"
        android:layout_height="50dip"
        android:src="@drawable/icon" >
    </ImageView>
</LinearLayout>

<!-- Title Of Exercise -->
<TextView
    android:id="@+id/title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignTop="@+id/thumbnail"
    android:layout_toLeftOf="@+id/inertCheckBox"
    android:layout_toRightOf="@+id/thumbnail"
    android:text="This is the Title - Testing 1 2 3 "
    android:textColor="#ffffffff"
    android:textSize="18dip"
    android:textStyle="bold"
    android:typeface="sans" />

<TextView
    android:id="@+id/description"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/title"
    android:layout_toLeftOf="@+id/inertCheckBox"
    android:layout_toRightOf="@id/thumbnail"
    android:text="this is the description - Testing 1 2 3"
    android:textColor="#ffcccccc"
    android:textSize="14dip" />

<TextView
    android:id="@+id/session_count"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:gravity="right"
    android:text="100"
    android:textColor="#ffcccccc"
    android:textSize="10dip"
    android:textStyle="bold" />
<ImageView
    android:id="@+id/drag"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@id/inertCheckBox"
    android:layout_alignLeft="@id/inertCheckBox"
    android:layout_alignParentRight="true"
    android:layout_alignTop="@id/inertCheckBox"
    android:layout_below="@id/session_count"
    android:layout_centerVertical="false"
    android:adjustViewBounds="true"
    android:maxHeight="32dip"
    android:maxWidth="32dip"
    android:scaleType="center"
    android:src="@drawable/arrow_32_holo_dark"
    android:visibility="visible" />
<au.drp.mylistview.widget.InertCheckBox
    android:id="@+id/inertCheckBox"
    style="@drawable/checkbox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_below="@id/session_count"
    android:button="@drawable/checkbox"
    android:checked="true"
    android:clickable="false"
    android:focusable="false"
    android:focusableInTouchMode="false" />

</au.drp.mylistview.widget.CheckableRelativeLayout>

私のCheckableRelativeLayoutクラス

public class CheckableRelativeLayout extends RelativeLayout implements Checkable {

private boolean isChecked;
private List<Checkable> checkableViews;

public CheckableRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    initialise(attrs);
}

public CheckableRelativeLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialise(attrs);
}

public CheckableRelativeLayout(Context context, int checkableId) {
    super(context);
    initialise(null);
}

/*
 * @see android.widget.Checkable#isChecked()
 */
public boolean isChecked() {
    return isChecked;
}

/*
 * @see android.widget.Checkable#setChecked(boolean)
 */
public void setChecked(boolean isChecked) {
    this.isChecked = isChecked;
    for (Checkable c : checkableViews) {
        c.setChecked(isChecked);
    }
}

/*
 * @see android.widget.Checkable#toggle()
 */
public void toggle() {
    this.isChecked = !this.isChecked;
    for (Checkable c : checkableViews) {
        c.toggle();
    }
}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();

    final int childCount = this.getChildCount();
    for (int i = 0; i < childCount; ++i) {
        findCheckableChildren(this.getChildAt(i));
    }
}

/**
 * Read the custom XML attributes
 */
private void initialise(AttributeSet attrs) {
    this.isChecked = false;
    this.checkableViews = new ArrayList<Checkable>(5);
}

/**
 * Add to our checkable list all the children of the view that implement the
 * interface Checkable
 */
private void findCheckableChildren(View v) {
    if (v instanceof Checkable) {
        this.checkableViews.add((Checkable) v);
    }

    if (v instanceof ViewGroup) {
        final ViewGroup vg = (ViewGroup) v;
        final int childCount = vg.getChildCount();
        for (int i = 0; i < childCount; ++i) {
            findCheckableChildren(vg.getChildAt(i));
        }
    }
}

}

そして、DragsortListViewのカスタムリストビューレイアウト

<?xml version="1.0" encoding="utf-8"?>
<au.drp.mylistview.draganddrop.DragSortListView
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:dslv="http://schemas.android.com/apk/res/au.drp.mylistview"
  android:id="@android:id/list"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:paddingTop="20dp"
  android:paddingBottom="20dp"
  dslv:collapsed_height="5dp"
  dslv:drag_scroll_start="0.33"
  dslv:max_drag_scroll_speed="0.5"
  dslv:float_background_color="#000000"
  dslv:remove_mode="none"
  dslv:track_drag_scroll="false" />

誰かが私のエラーを私に指摘することができますか?ハマった。

ありがとう、

ポール。

4

3 に答える 3

0

わかりました。問題が見つかりました。しかし、別の問題を提起します。問題は MyListViewAdapter クラスのこの行です

 final ListView lv = (ListView) parent;  // DOES NOT LIKE THIS STATEMENT CODE

これをコメントアウトすると、lv を使用するすべてのアプリが実行され、ドラッグ アンド ドロップが機能します。しかし、問題は、リスト ビューの項目がチェックされているかどうかを判断する方法です。これは、ビューがチェックされているかどうかを取得する方法です

    // This is how you would determine if this particular item is checked
    // when the view gets created
    // --       
    final ListView lv = (ListView) parent;  // DOES NOT LIKE THIS STATEMENT CODE
    final boolean isChecked = lv.isItemChecked(position);

    // Get the listview Choice Mode
    //
    final int selectionMode = lv.getChoiceMode();

ドラッグ アンド ドロップ サポート モードが有効になっている場合は、コードの周りに if ステートメントを追加できると思いますが、それは回避策のようです。何か案は?

于 2012-08-02T11:51:06.440 に答える
0

View parentに渡されるパラメータは、リストを含むものでgetViewはなく、ListView単なる親ですconvertView(つまり、インフレートするため)。これは基本的にListViewオブジェクトではありません。ClassCastExceptionそのため、キャストしようとすると が取得されます。これは、 にキャストできないためListViewです。ListViewオブジェクトをAdaptersublcass のコンストラクターに渡してから、getView..

于 2012-11-19T13:46:45.553 に答える