Java RelativeLayout无法强制转换到我的自定义listview
因此,我正在编写一个自定义listview&adapter,以便在列表视图中显示我自己的自定义项行。我有一个功能列表视图,它具有在选择模式之间切换的功能,并且通过列表视图行xml文件中的自定义相对布局具有可检查列表行项目。现在,我正在尝试添加拖放功能,以使用android v3.0及更高版本的目标代码访问列表视图项。我在这个网站上发现了这个拖放的优秀实现,现在我正在将它添加到我的项目中 当我编译我的项目时,我得到了一个cast异常错误,正如我的文章标题中所述,我很难克服它。我无法确定是我的自定义相对布局实现了可检查,还是拖放的自定义列表视图等。这是我的日志输出Java RelativeLayout无法强制转换到我的自定义listview,java,android,android-layout,android-widget,Java,Android,Android Layout,Android Widget,因此,我正在编写一个自定义listview&adapter,以便在列表视图中显示我自己的自定义项行。我有一个功能列表视图,它具有在选择模式之间切换的功能,并且通过列表视图行xml文件中的自定义相对布局具有可检查列表行项目。现在,我正在尝试添加拖放功能,以使用android v3.0及更高版本的目标代码访问列表视图项。我在这个网站上发现了这个拖放的优秀实现,现在我正在将它添加到我的项目中 当我编译我的项目时,我得到了一个cast异常错误,正如我的文章标题中所述,我很难克服它。我无法确定是我的自定义
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类中的error'ing部分,我可以更改结果,但在相对布局类型和列表视图之间仍然存在强制转换异常错误。我谈到的这一部分是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;
}
final ListView lv = (ListView) parent; // DOES NOT LIKE THIS STATEMENT CODE
我的列表视图行布局
<?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>
我的可检查相对论课堂
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));
}
}
}
公共类CheckableRelativeLayout扩展RelativeLayout实现可检查{
检查私有布尔值;
私有列表可检查视图;
公共CheckableRelativeLayout(上下文上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
初始化(ATTR);
}
公共CheckableRelativeLayout(上下文、属性集属性){
超级(上下文,attrs);
初始化(ATTR);
}
公共CheckableRelativeLayout(上下文上下文,int-checkableId){
超级(上下文);
初始化(空);
}
/*
*@see android.widget.checked#isChecked()
*/
公共布尔值已检查(){
返回检查;
}
/*
*@see android.widget.Checkable#setChecked(布尔值)
*/
公共void setChecked(布尔值已检查){
this.isChecked=isChecked;
for(可检查的c:可检查的视图){
c、 设置已检查(已检查);
}
}
/*
*@see android.widget.Checkable#toggle()
*/
公共无效切换(){
this.isChecked=!this.isChecked;
for(可检查的c:可检查的视图){
c、 切换();
}
}
@凌驾
充气时受保护的空隙(){
超级充气();
final int childCount=this.getChildCount();
对于(int i=0;i
}
以及DragsortListView的自定义listview布局
<?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" />
有人能向我指出我的错误吗?我被卡住了
谢谢
保罗。好的,我发现问题了!但也引发了另一个问题。问题是MyListViewAdapter类中的这一行
@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;
}
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语句,用于何时启用拖放支持模式,但这似乎是一个解决方法。有什么想法吗?
View parent
传递到getView
的参数不是包含列表的ListView
,它只是convertView
的父级(即,用于充气)。它基本上不是一个列表视图
对象,这就是为什么您在尝试转换它时会得到一个ClassCastException
,因为它不能转换为列表视图
。您应该将ListView
对象传递到Adapter
subcass的构造函数中,然后在getView
中使用它。在我的例子中ClassCastException
是因为在我的自定义视图.xml
(我用来膨胀MyCustomView
)中定义了它的id
:
android:id="@+id/myCustomView"
然后在my_activity.xml
中,我再次定义了它的id
:
<com.example.app.views.custom.MyCustomView
android:id="@+id/myCustomView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
从
my_custom_view.xml
中删除id
参数解决了问题。你能试试看这是否有效:mAdapter.getView(position,null,null)我想知道你是应该使用mAdapter.getView()还是应该调用list.getChildAt(index)…?试过mAdapter.getView(position,null,null)但是当你说list.getChildAt(index)时,你指的是list。是否应该以某种方式引用我的listview?到目前为止我还没有成功。