Question

Here is my adapter code; keep in mind for the ListView I am returning two types of views. (LogCat under code`)

public class ItemAdapter extends ArrayAdapter<Item> {
   private LayoutInflater inflater;

  public ItemAdapter(Context context, ArrayList<Item> userItemObjectList) {
      super(context, R.layout.item_row_layout, userItemObjectList);

      inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}

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

class ViewHolder {
    TextView t1;
    TextView t2;
    TextView t3;
    TextView t4;
    TextView t6;
}

@Override
public int getItemViewType(int pos) {
    Item i = getItem(pos);
    String season = i.season;
    if (!season.equals(lastSeason)) {
        return 1;
    } else {
        return 0;
    }
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    int rowType = getItemViewType(position);

    if (convertView == null) {
        holder = new ViewHolder();

        if (rowType == 0) {
            convertView = inflater.inflate(R.layout.item_row_layout, parent,
                    false);

            holder.t1 = (TextView) convertView.findViewById(R.id.itemName);
            holder.t3 = (TextView) convertView
                    .findViewById(R.id.tvReviewTotalForItem);
            holder.t4 = (TextView) convertView
                    .findViewById(R.id.tvPercentageItems);
            holder.t6 = (TextView) convertView
                    .findViewById(R.id.tvItemRowReviewLabel);

            convertView.setTag(holder);

        } else if (rowType == 1) {

           convertView = inflater.inflate(R.layout.row_season, parent,
                    false);

            holder.t2 = (TextView) convertView.findViewById(R.id.seasonNumber);

            convertView.setTag(holder);
        }

    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    Item i = getItem(position);
    String episode = i.item;
    String rating = i.ratings;
    String review = i.reviews;

    if (rowType == 1) {

        String season = i.season;
        lastSeason = season;
        holder.t2.setText("Season " + lastSeason);

    } else if (rowType == 0) {

        holder.t1.setText(episode); // THIS IS WHERE NULL TEXTVIEW IS FOUND
        holder.t3.setText(review);
        holder.t4.setText(rating);
        holder.t4.setText(rating);

    }


    return convertView;
}

}

Here is my LogCat:

07-28 09:50:02.689: E/AndroidRuntime(7685): Process: com.---.---, PID: 7685
07-28 09:50:02.689: E/AndroidRuntime(7685): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
07-28 09:50:02.689: E/AndroidRuntime(7685):     at com.---.---.ItemAdapter.getView(ItemAdapter.java:181)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:220)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.widget.AbsListView.obtainView(AbsListView.java:2255)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.widget.ListView.makeAndAddView(ListView.java:1790)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.widget.ListView.fillDown(ListView.java:691)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.widget.ListView.fillGap(ListView.java:655)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5143)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3243)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.widget.AbsListView.onTouchMove(AbsListView.java:3587)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.widget.AbsListView.onTouchEvent(AbsListView.java:3431)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.View.dispatchTouchEvent(View.java:7706)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2210)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1945)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2068)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1515)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.app.Activity.dispatchTouchEvent(Activity.java:2458)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2016)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.View.dispatchPointerEvent(View.java:7886)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3947)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3826)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3392)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3442)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3411)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3518)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3419)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3575)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3392)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3442)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3411)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3419)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3392)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5532)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5512)
07-28 09:50:02.689: E/AndroidRuntime(7685):     at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:548

I have confirmed, through logging, that the null TextView is in rowType 0. It is null when convertView is NOT null (so it happens when it is recycling the views).

Was it helpful?

Solution

I had once similar problem, i solved it by creating separate ViewHolders for each layout:

    @Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    ViewHolder2 holder2;
    int rowType = getItemViewType(position);

    if (convertView == null) {


        if (rowType == 0) {
            holder = new ViewHolder();
            convertView = inflater.inflate(R.layout.item_row_layout, parent,
                    false);

            holder.t1 = (TextView) convertView.findViewById(R.id.itemName);
            holder.t3 = (TextView) convertView
                    .findViewById(R.id.tvReviewTotalForItem);
            holder.t4 = (TextView) convertView
                    .findViewById(R.id.tvPercentageItems);
            holder.t6 = (TextView) convertView
                    .findViewById(R.id.tvItemRowReviewLabel);

            convertView.setTag(holder, R.layout.item_row_layout);

        } else if (rowType == 1) {
           holder2 = new ViewHolder2();
           convertView = inflater.inflate(R.layout.row_season, parent,
                    false);

            holder2.t2 = (TextView) convertView.findViewById(R.id.seasonNumber);

            convertView.setTag(holder, R.layout.row_season);
        }

    } else {
        if (rowType == 0) {
            holder = (ViewHolder) convertView.getTag(R.layout.item_row_layout);
        } else if (rowType == 1) {
            holder2 = (ViewHolder2) convertView.getTag(R.layout.row_season);
        }
    }

    Item i = getItem(position);
    String episode = i.item;
    String rating = i.ratings;
    String review = i.reviews;

    if (rowType == 1) {

        String season = i.season;
        lastSeason = season;
        holder2.t2.setText("Season " + lastSeason);

    } else if (rowType == 0) {

        holder.t1.setText(episode); // THIS IS WHERE NULL TEXTVIEW IS FOUND
        holder.t3.setText(review);
        holder.t4.setText(rating);
        holder.t4.setText(rating);

    }


    return convertView;
}

Viewholders:

static class ViewHolder {
    TextView t1;
    TextView t3;
    TextView t4;
    TextView t6;
}

static class ViewHolder2 {
    TextView t2;
}

OTHER TIPS

You said that the rowType is 1 (through the debug) but the null appears inside the If statement where the rowType is 0 (you have a comment in the first line of that If indicating it).

you must have set text to textView before it has been initialise

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top