我在下面粘贴了我的代码,概念是我有3种不同类型的listview项目,可以通过viewholder类看到。现在当我滚动列表视图时,它会在freeTextHolder = (ViewHolderFreeText) rowView.getTag();
上崩溃,因为_position
与所需的itemList
对象不匹配,该位置会显示其"free text"
所以if (itemList.get(_position).getType().compareTo(Question.TYPE_CATEGORY) == 0)
获得了真,但rowView.getTag()
显示了一个复选框,因此_position
1增加了所需的位置,然后崩溃了。
@Override
public View getView(final int _position, View _convertView,
ViewGroup _parent) {
View rowView = _convertView;
if (itemList.get(_position).getType().compareTo(Question.TYPE_CATEGORY) == 0) {
ViewHolderBranch branchHolder = new ViewHolderBranch();
// Compartment for Branch
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.listview_branch, _parent,
false);
branchHolder.hTextTitle = (TextView) rowView
.findViewById(R.id.textTitleB);
branchHolder.hTextDetail = (TextView) rowView
.findViewById(R.id.textDetailB);
branchHolder.hIcon = (ImageView) rowView
.findViewById(R.id.imageArrow);
rowView.setTag(branchHolder);
} else {
branchHolder = (ViewHolderBranch) rowView.getTag();
}
branchHolder.hTextTitle.setText(itemList.get(_position).getText());
if (itemList.get(_position).isIsReadCode())
branchHolder.hTextDetail.setText(itemList.get(_position)
.getReadCode());
else
branchHolder.hTextDetail.setText(" ");
branchHolder.hIcon
.setImageResource(android.R.drawable.ic_media_play);
// return rowView;
}
else if (itemList.get(_position).getType()
.compareTo(Question.TYPE_CHECKBOX) == 0) {
// Compartment for Checkboxes
ViewHolderCheckbox checkboxHolder = new ViewHolderCheckbox();
// Compartment for Branch
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.listview_checkbox, _parent,
false);
checkboxHolder.hTextTitle = (TextView) rowView
.findViewById(R.id.textTitleCB);
checkboxHolder.hTextDetail = (TextView) rowView
.findViewById(R.id.textDetailCB);
checkboxHolder.hCheckBox = (CheckBox) rowView
.findViewById(R.id.checkBox);
rowView.setTag(checkboxHolder);
} else {
checkboxHolder = (ViewHolderCheckbox) rowView.getTag();
}
checkboxHolder.hTextTitle
.setText(itemList.get(_position).getText());
if (itemList.get(_position).isIsReadCode())
checkboxHolder.hTextDetail.setText(itemList.get(_position)
.getReadCode());
else
checkboxHolder.hTextDetail.setText(" ");
checkboxHolder.hCheckBox.setChecked(itemList.get(_position)
.isChecked());
// return rowView;
}
if (itemList.get(_position).getType().compareTo(Question.TYPE_FREETEXT) == 0) {
ViewHolderFreeText freeTextHolder = new ViewHolderFreeText();
// Compartment for Branch
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.listview_button, _parent,
false);
freeTextHolder.hTextTitle = (TextView) rowView
.findViewById(R.id.textTitleBtn);
freeTextHolder.hTextDetail = (TextView) rowView
.findViewById(R.id.textDetailBtn);
freeTextHolder.hIcon = (ImageView) rowView
.findViewById(R.id.imagePlusBtn);
rowView.setTag(freeTextHolder);
} else {
freeTextHolder = (ViewHolderFreeText) rowView.getTag();
}
freeTextHolder.hTextTitle.setText(itemList.get(_position).getText());
if (itemList.get(_position).isIsReadCode())
freeTextHolder.hTextDetail.setText(itemList.get(_position)
.getReadCode());
else
freeTextHolder.hTextDetail.setText(" ");
freeTextHolder.hIcon
.setImageResource(android.R.drawable.ic_input_add);
// return rowView;
}
return rowView;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return itemList.size();
}
@Override
public Object getItem(int _position) {
// TODO Auto-generated method stub
return _position;
}
@Override
public long getItemId(int _position) {
// TODO Auto-generated method stub
return _position;
}
和视图持有人类
静态类ViewHolderBranch { TextView hTextTitle; TextView hTextDetail; ImageView hIcon; }
static class ViewHolderFreeText
{
TextView hTextTitle;
TextView hTextDetail;
ImageView hIcon;
}
// View Holder for Checkbox Items
/**
* Class for holding different view items
*
*/
static class ViewHolderCheckbox {
TextView hTextTitle;
TextView hTextDetail;
CheckBox hCheckBox;
}
微量
09-23 15:36:29.105: D/AndroidRuntime(8908): Shutting down VM 09-23 15:36:29.105: W/dalvikvm(8908): threadid=1: thread exiting with
uncaught exception (group=0x40014760) 09-23 15:36:29.326:
E/AndroidRuntime(8908): FATAL EXCEPTION: main 09-23 15:36:29.326:
E/AndroidRuntime(8908): java.lang.ClassCastException:
com.techmelo.ws.CustomizeLViewAdapter$ViewHolderBranch cannot be cast
to com.techmelo.ws.CustomizeLViewAdapter$ViewHolderFreeText 09-23
15:36:29.326: E/AndroidRuntime(8908): at
com.techmelo.ws.CustomizeLViewAdapter.getView(CustomizeLViewAdapter.java:157)
09-23 15:36:29.326: E/AndroidRuntime(8908): at
android.widget.AbsListView.obtainView(AbsListView.java:1943) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.widget.ListView.makeAndAddView(ListView.java:1756) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.widget.ListView.fillDown(ListView.java:656) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.widget.ListView.fillGap(ListView.java:620) 09-23 15:36:29.326:
E/AndroidRuntime(8908): at
android.widget.AbsListView.trackMotionScroll(AbsListView.java:4350)
09-23 15:36:29.326: E/AndroidRuntime(8908): at
android.widget.AbsListView.onTouchEvent(AbsListView.java:2892) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.widget.ListView.onTouchEvent(ListView.java:3566) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.view.View.dispatchTouchEvent(View.java:4600) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1488)
09-23 15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1256) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1494)
09-23 15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1269) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1494)
09-23 15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1269) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1494)
09-23 15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1269) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1494)
09-23 15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1269) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1494)
09-23 15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1269) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1494)
09-23 15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1269) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1494)
09-23 15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1269) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1700)
09-23 15:36:29.326: E/AndroidRuntime(8908): at
com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1270)
09-23 15:36:29.326: E/AndroidRuntime(8908): at
android.app.Activity.dispatchTouchEvent(Activity.java:2277) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1680)
09-23 15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2272) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.view.ViewRoot.handleMessage(ViewRoot.java:1958) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.os.Handler.dispatchMessage(Handler.java:99) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
android.os.Looper.loop(Looper.java:126) 09-23 15:36:29.326:
E/AndroidRuntime(8908): at
android.app.ActivityThread.main(ActivityThread.java:3997) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
java.lang.reflect.Method.invokeNative(Native Method) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
java.lang.reflect.Method.invoke(Method.java:491) 09-23 15:36:29.326:
E/AndroidRuntime(8908): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
09-23 15:36:29.326: E/AndroidRuntime(8908): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599) 09-23
15:36:29.326: E/AndroidRuntime(8908): at
dalvik.system.NativeStart.main(Native Method) 09-23 15:36:39.334:
W/ActivityThread(9001): Application com.techmelo.ws is waiting for the
debugger on port 8100... 09-23 15:36:39.345: I/System.out(9001):
Sending WAIT chunk 09-23 15:36:39.364: I/dalvikvm(9001): Debugger is
active 09-23 15:36:39.554: I/System.out(9001): Debugger has connected
09-23 15:36:39.554: I/System.out(9001): waiting for debugger to
settle... 09-23 15:36:39.808: I/System.out(9001): waiting for debugger
to settle... 09-23 15:36:40.014: I/System.out(9001): waiting for
debugger to settle... 09-23 15:36:40.216: I/System.out(9001): waiting
for debugger to settle... 09-23 15:36:40.416: I/System.out(9001):
waiting for debugger to settle... 09-23 15:36:40.647:
I/System.out(9001): waiting for debugger to settle... 09-23
15:36:40.884: I/System.out(9001): waiting for debugger to settle...
09-23 15:36:41.085: I/System.out(9001): waiting for debugger to
settle... 09-23 15:36:41.299: I/System.out(9001): waiting for debugger
to settle... 09-23 15:36:41.524: I/System.out(9001): waiting for
debugger to settle... 09-23 15:36:41.755: I/System.out(9001): debugger
has settled (1390) 09-23 15:36:42.994: D/dalvikvm(9001): GC_FOR_ALLOC
freed 63K, 4% free 6386K/6599K, paused 45ms 09-23 15:36:43.004:
I/dalvikvm-heap(9001): Grow heap (frag case) to 6.820MB for
513744-byte allocation 09-23 15:36:43.284: D/dalvikvm(9001):
GC_CONCURRENT freed <1K, 4% free 6888K/7111K, paused 29ms+2ms 09-23
15:36:46.084: V/TLINE(9001): new: android.text.TextLine@40719db0 09-23
15:36:47.904: V/TLINE(9001): new: android.text.TextLine@4072b720 09-23
15:37:11.404: D/dalvikvm(9001): threadid=1: still suspended after undo
(sc=1 dc=1) 09-23 15:37:11.414: D/dalvikvm(9001): GC_CONCURRENT freed
117K, 4% free 7263K/7495K, paused 13ms+8ms
答案 0 :(得分:2)
发生异常是因为您的不同代码分支(对于不同类型的行)可能都处理重用的行视图,该视图具有与之关联的任何类型的标记对象。
最佳解决方案是覆盖Adapter
的{{1}}和getItemViewType(int)
方法,以指定您拥有多少种不同类型的项目视图,并将这些视图映射到列表位置。这将简化getViewTypeCount()
中的逻辑,让getView(...)
以不同的视图类型处理行回收池。
您可以将ListView
中的测试更改为:
getView(...)
其中if (getItemViewType(_position) == TYPE_CATEGORY) {
// code for categories
}
是您的Adapter子类知道的TYPE_CATEGORY
。