我是Android的新手,我正在使用 ListView 。慢慢滚动 ListView 时没问题。但是当我快速滚动它时,会发生应用程序崩溃。
任何人都可以帮助我吗?
堆栈追踪:
FATAL EXCEPTION: main
Process: com.beco.ibeco, PID: 1764
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.beco.ibeco.app.account.ProfileFragmentNew$HelpListAdapter.getView(ProfileFragmentNew.java:417)
at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:220)
at android.widget.AbsListView.obtainView(AbsListView.java:2346)
at android.widget.ListView.makeAndAddView(ListView.java:1876)
at android.widget.ListView.fillDown(ListView.java:702)
at android.widget.ListView.fillGap(ListView.java:666)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5106)
at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3463)
at android.widget.AbsListView.onTouchMove(AbsListView.java:3878)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:3691)
at android.view.View.dispatchTouchEvent(View.java:9306)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2548)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2241)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2405)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1737)
at android.app.Activity.dispatchTouchEvent(Activity.java:2820)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:63)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:63)
at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2366)
at android.view.View.dispatchPointerEvent(View.java:9526)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4262)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4128)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3669)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3722)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3688)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3814)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3696)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3871)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3669)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3722)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3688)
at android.view.ViewRootI
代码:
private class HelpListAdapter extends ArrayAdapter {
private Holder holder;
private Context context;
public HelpListAdapter(Context context, int resource) {
super(context, resource);
this.context = context;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
holder = new Holder();
if (position == 3) {
view = View.inflate(getContext(), R.layout.list_item_with_expandable_new, null);
holder.expandableListView = (ExpandableListView) view.findViewById(R.id.expand_list);
holder.containerList = (LinearLayout) view.findViewById(R.id.container_expandable_list);
} else {
view = View.inflate(getContext(), R.layout.list_item_text, null);
holder.textView = (TextView) view.findViewById(R.id.text);
}
view.setTag(holder);
} else {
holder = (Holder) view.getTag();
}
if (position != 3) {
holder.textView.setText(mHelpLabels.get(position));
Drawable[] iconLeft = {Util.getCustomDrawableColor(getActivity(),R.drawable.ic_favorite_18dp,R.color.beco_logout_red, PorterDuff.Mode.SRC_ATOP),
Util.getCustomDrawableColor(getActivity(), R.drawable.ic_checkin_18dp, R.color.beco_logout_red, PorterDuff.Mode.DST_IN),
Util.getCustomDrawableColor(getActivity(), R.drawable.ic_faq, R.color.beco_white, PorterDuff.Mode.DST_IN),
Util.getCustomDrawableColor(getActivity(), R.drawable.ic_feedback, R.color.beco_white, PorterDuff.Mode.DST_IN),
Util.getCustomDrawableColor(getActivity(), R.drawable.ic_feedback, R.color.beco_white, PorterDuff.Mode.DST_IN),
Util.getCustomDrawableColor(getActivity(), R.drawable.ic_share_app, R.color.beco_white, PorterDuff.Mode.DST_IN),
Util.getCustomDrawableColor(getActivity(), R.drawable.ic_privacy, R.color.beco_white, PorterDuff.Mode.DST_IN),
Util.getCustomDrawableColor(getActivity(), R.drawable.ic_terms, R.color.beco_white, PorterDuff.Mode.DST_IN),
Util.getCustomDrawableColor(getActivity(), R.drawable.ic_faq, R.color.beco_white, PorterDuff.Mode.DST_IN),
Util.getCustomDrawableColor(getActivity(), R.drawable.ic_beco_settings, R.color.beco_white, PorterDuff.Mode.DST_IN),
Util.getCustomDrawableColor(getActivity(), R.drawable.ic_beco_settings, R.color.beco_white, PorterDuff.Mode.DST_IN),
};
holder.textView.setCompoundDrawablesWithIntrinsicBounds(iconLeft[position], null, null, null);
} else {
holder.expandableListView.setAdapter(new ExpandableListAdapter(context, mHelpLabels.get(position), view));
holder.expandableListView.setOnGroupClickListener((parentExpand, v, groupPosition, id) -> {
setListViewHeight(parentExpand, groupPosition);
return false;
});
}
return view;
}
class Holder {
TextView textView;
ExpandableListView expandableListView;
LinearLayout containerList;
}
private void setListViewHeight(ExpandableListView listView, int group) {
ExpandableListAdapter listAdapter = (ExpandableListAdapter) listView.getExpandableListAdapter();
int height = 0;
int groupCount = 0;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.EXACTLY);
View groupItem = listAdapter.getGroupView(groupCount, false, null, listView);
groupItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
height += groupItem.getMeasuredHeight();
if (((listView.isGroupExpanded(groupCount)) && (groupCount != group))
|| ((!listView.isGroupExpanded(groupCount)) && (groupCount == group))) {
for (int j = 0; j < listAdapter.getChildrenCount(groupCount); j++) {
View listItem = listAdapter.getChildView(groupCount, j, false, null, listView);
listItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
height += listItem.getMeasuredHeight();
}
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
if (height < 10)
height = 200;
params.height = height;
listView.setLayoutParams(params);
listView.requestLayout();
}
class ExpandableListAdapter extends BaseExpandableListAdapter {
Context context;
String title;
View viewParent;
ExpandableListAdapter(Context context, String title, View view) {
this.context = context;
this.title = title;
this.viewParent = view;
}
@Override
public String getChild(int groupPosition, int childPosititon) {
return mContactLabels.get(childPosititon);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View view, ViewGroup parent) {
if (view == null) {
LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = infalInflater.inflate(R.layout.list_item_text, null);
}
Drawable[] iconLeft = {Util.getCustomDrawableColor(getActivity(), R.drawable.ic_email, R.color.beco_icon_tint_color, PorterDuff.Mode.SRC_ATOP),
Util.getCustomDrawableColor(getActivity(), R.drawable.ic_phone_black, R.color.beco_icon_tint_color, PorterDuff.Mode.DST_IN)};
TextView textView = (TextView) view.findViewById(R.id.text);
textView.setText(mContactLabels.get(childPosition));
textView.setCompoundDrawablesWithIntrinsicBounds(iconLeft[childPosition], null, null, null);
textView.setOnClickListener(v -> {
switch (childPosition) {
case 0:
Intent intentEmail = new Intent(Intent.ACTION_SENDTO);
intentEmail.setData(Uri.fromParts("mailto", mContactLabels.get(childPosition), null));
intentEmail.putExtra(Intent.EXTRA_SUBJECT, "Contact beCo");
startActivity(intentEmail);
break;
case 1:
Intent intentCall = new Intent(Intent.ACTION_DIAL);
intentCall.setData(Uri.parse("tel:" + mContactLabels.get(childPosition)));
startActivity(intentCall);
break;
}
});
return view;
}
@Override
public int getChildrenCount(int groupPosition) {
return mContactLabels.size();
}
@Override
public Object getGroup(int groupPosition) {
return mContactLabels.get(groupPosition);
}
@Override
public int getGroupCount() {
return 1;
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View view, ViewGroup parent) {
if (view == null) {
LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = infalInflater.inflate(R.layout.list_item_text, null);
}
TextView contact = (TextView) view.findViewById(R.id.text);
contact.setText(title);
Drawable iconLeft = Util.getCustomDrawableColor(getActivity(), R.drawable.ic_contact_blue, R.color.beco_white, PorterDuff.Mode.DST_IN);
contact.setCompoundDrawablesWithIntrinsicBounds(null,null,iconLeft,null);
LinearLayout border = (LinearLayout) viewParent.findViewById(R.id.container_expandable_list);
Drawable iconRight = Util.getCustomDrawableColor(getActivity(), R.drawable.ic_keyboard_arrow_down_black, R.color.beco_black, PorterDuff.Mode.DST_IN);
if (isExpanded) {
border.setBackgroundResource(R.drawable.border);
iconRight = Util.getCustomDrawableColor(getActivity(), R.drawable.ic_keyboard_arrow_up_black, R.color.beco_black, PorterDuff.Mode.DST_IN);
contact.setTextColor(ContextCompat.getColor(getActivity(), R.color.beco_primary));
contact.setCompoundDrawablesWithIntrinsicBounds(null, null, iconRight, null);
} else {
border.setBackgroundResource(0);
contact.setTextColor(ContextCompat.getColor(getActivity(), R.color.beco_label_color));
contact.setCompoundDrawablesWithIntrinsicBounds(null, null, iconRight, null);
}
return view;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
}
答案 0 :(得分:1)
您的问题在于处理不同类型的观点:
有了这个:
if (position == 3) {
view = View.inflate(getContext(), R.layout.list_item_with_expandable_new, null);
holder.expandableListView = (ExpandableListView) view.findViewById(R.id.expand_list);
holder.containerList = (LinearLayout) view.findViewById(R.id.container_expandable_list);
} else {
view = View.inflate(getContext(), R.layout.list_item_text, null);
holder.textView = (TextView) view.findViewById(R.id.text);
}
您可以创建两种类型的视图,但不要告诉适配器您有两种类型的视图。因此,当涉及到回收时,任何这些视图都可以用于另一个。
您需要帮助适配器改变getItemViewType(int position)
:
@Override
public int getItemViewType (int position) {
return position == 3 ? 0 : 1;
}
@Override
public int getViewTypeCount() {
return 2;
}
这样,listview知道不会为任何其他项重用视图创建位置3。
答案 1 :(得分:0)
由于以编程方式设置listview高度,问题可能是 ;当它这样做时,在持有视图的同时重绘了项目中的视图。在位置3的情况下,位置4的视图符号将具有对文本视图的空引用,从而导致其崩溃。
我建议你不要在ListView(或GridView)中对项目使用不同的布局。我曾经遇到过同样的问题,导致布局出现问题。相反,只使用一个布局;如果你需要隐藏一些元素,比如TextView,你可以通过编程方式进行:
holder.textview.setVisibility(View.INVISIBLE); //or View.GONE
还有一些与ExpandableListViews相关的好教程:
http://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/
http://theopentutorials.com/tutorials/android/listview/android-expandable-list-view-example/
答案 2 :(得分:0)
在getView中替换此代码:
@modal.data.description