-1

I'm a newbie to Android, and I'm using a ListView. No problem when scrolling the ListView slowly. But when I scroll it quickly, app crash occurs.

Can anyone help me?

Stack trace:

 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

Code:

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;
        }
    }
}
Pang
  • 9,564
  • 146
  • 81
  • 122
vm345
  • 813
  • 12
  • 28
  • Check your stack trace and see the issue in your code on the line number mentioned. In your `getView` method, it isn't able to find the TextView.. it is coming as null so when you are trying to set the some value on this text view, it is throwing null pointer exception ... You may refer [here] (http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it/218510#218510) – Paras Mar 31 '17 at 12:03

3 Answers3

1

Your problem lies with the handling of different types of views:

With this:

        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);
        }

You create 2 types of views, but you don't tell the adapter that you have 2 types of views. So when it comes to recycling, any of those views can be used for the other.

You need to help you adapter make the difference with getItemViewType(int position):

@Override
public int getItemViewType (int position) {
    return position == 3 ? 0 : 1;
}

@Override
public int getViewTypeCount() {
    return 2;
}

This way, the listview knows not to reuse the view create for position 3 for any other item.

njzk2
  • 38,969
  • 7
  • 69
  • 107
0

The problem is probably arising due to setting the listview height programmatically; when it does that, the views from the items are redrawed while holding the viewholders. In the case of position 3, the viewholder of a position 4 will have null reference to the textview, causing it to crash.

I suggest you to not use different layouts for items in a ListView (or GridView). I once had the same problem you had, causing the layouts to appear broken. Instead, use only one layout; if you need to hide some elements, like a TextView, you can do it programmatically:

holder.textview.setVisibility(View.INVISIBLE); //or View.GONE 

There are some good tutorials related to ExpandableListViews too:

http://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/

http://theopentutorials.com/tutorials/android/listview/android-expandable-list-view-example/

Alexandre
  • 565
  • 3
  • 9
0

Replace this code in getView :

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);
        } else {
            view = View.inflate(getContext(), R.layout.list_item_text, null);
        }
        view.setTag(holder);
    } else {
        holder = (Holder) view.getTag();
    }

    if (position != 3) {
        holder.textView = (TextView) view.findViewById(R.id.text);
        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 = (ExpandableListView) view.findViewById(R.id.expand_list);
        holder.containerList = (LinearLayout) view.findViewById(R.id.container_expandable_list);
        holder.expandableListView.setAdapter(new ExpandableListAdapter(context, mHelpLabels.get(position), view));
        holder.expandableListView.setOnGroupClickListener((parentExpand, v, groupPosition, id) -> {
            setListViewHeight(parentExpand, groupPosition);
            return false;
        });
    }

    return view;
}
Imene Noomene
  • 3,035
  • 5
  • 18
  • 34