3

In my app I am trying to use two layout in the recyclerView everything is ok until I try the app and it crashes saying:
Attempt to invoke virtual method 'void android.widget.TextView.setText(int)' on a null object reference.
The error is in this line and every time I try to setText in the first layout:

groupsViewHolder.fTeamName.setText(R.string.russia);

the second layout is working fine but the first one is not.
What I want is to solve the error and if there is any better way than using switch many times. Thank you for your help.
here is my code:

MatchesAdapter.java:

public class MatchesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

final private ListItemClickListener mOnClickListener;
private Context context;


private int mNumberItems;

public MatchesAdapter(Context context, int numberOfItems, ListItemClickListener listener) {
    mNumberItems = numberOfItems;
    mOnClickListener = listener;
    this.context = context;
}

@Override
public int getItemViewType(int position) {
    return position;
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
    Context context = viewGroup.getContext();
    LayoutInflater inflater = LayoutInflater.from(context);
    if (viewType >= 0 && viewType <= 47) {
        int layoutIdForListItem = R.layout.matches_groups_item;
        View view = inflater.inflate(layoutIdForListItem, viewGroup, false);
        Log.e("QQ","Groups");
        return new GroupsViewHolder(view);
    } else {
        int layoutIdForListItem = R.layout.matches_rounds_item;
        View view = inflater.inflate(layoutIdForListItem, viewGroup, false);
        Log.e("QQ","Rounds");
        return new RoundsViewHolder(view);
    }

}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder mainHolder, int position) {
 mainHolder;
        String[] array = context.getResources().getStringArray(R.array.times);
        final int itemType = getItemViewType(position);
        if (itemType >= 0 && itemType <= 47) {
            GroupsViewHolder groupsViewHolder = (GroupsViewHolder) mainHolder;
            groupsViewHolder.bind(position);
            switch (position) {
                case 0:
                    groupsViewHolder.listItemDate.setText(array[position]);
                    groupsViewHolder.fTeamName.setText(R.string.russia);
                    groupsViewHolder.sTeamName.setText(R.string.saudi_arabia);
                    break;
                case 1:
                   groupsViewHolder.listItemDate.setText(array[position]);
                    groupsViewHolder.fTeamName.setText(R.string.egypt);                    
                    groupsViewHolder.sTeamName.setText(R.string.uruguay);
                    break;
//.... many cases until case 47 then
} else {
            RoundsViewHolder roundsViewHolder = (RoundsViewHolder) mainHolder;
            roundsViewHolder.bind(position);
            switch (position) {
                 case 48:
                roundsViewHolder.listItemTitle.setText(R.string.round16);
                roundsViewHolder.listItemDate.setText(array[position]);
                roundsViewHolder.fTeamName.setText(R.string.group_a_winner);
                roundsViewHolder.sTeamName.setText(R.string.group_b_runner_up);
                break;
            case 49:
                roundsViewHolder.listItemTitle.setText(R.string.round16);
                roundsViewHolder.listItemDate.setText(array[position]);
                roundsViewHolder.fTeamName.setText(R.string.group_c_winner);
                roundsViewHolder.sTeamName.setText(R.string.group_d_runner_up);
                break;

// until the end of cases then
    @Override
public int getItemCount() {
    return mNumberItems;
}

public interface ListItemClickListener {
    void onListItemClick(int clickedItemIndex);
}

class GroupsViewHolder extends RecyclerView.ViewHolder
        implements OnClickListener {

TextView listItemDate, listItemMatchNumber, fTeamName, sTeamName;
View fTeamView;
View sTeamView;

public GroupsViewHolder(View itemView) {
    super(itemView);

listItemDate = itemView.findViewById(R.id.match_date);
listItemMatchNumber = itemView.findViewById(R.id.match_number);
fTeamView = itemView.findViewById(R.id.groups_match_t1);
fTeamName = fTeamView.findViewById(R.id.match_team_name_for_groups);
sTeamView = itemView.findViewById(R.id.groups_match_t2);
sTeamName = sTeamView.findViewById(R.id.match_team_name_for_groups);
itemView.setOnClickListener(this);

}

void bind(int listIndex) {
    listItemMatchNumber.setText(String.valueOf(listIndex + 1));
}

@Override
public void onClick(View v) {
    int clickedPosition = getAdapterPosition();
    mOnClickListener.onListItemClick(clickedPosition);
}

}

class RoundsViewHolder extends RecyclerView.ViewHolder
        implements OnClickListener {
    TextView listItemTitle, listItemDate, listItemMatchNumber, fTeamName, sTeamName;
    View fTeamView;
    View sTeamView;

public RoundsViewHolder(View itemView) {
    super(itemView);

listItemTitle = itemView.findViewById(R.id.round_card_title);
listItemDate = itemView.findViewById(R.id.round_match_date);
listItemMatchNumber = itemView.findViewById(R.id.round_match_number);
fTeamView = itemView.findViewById(R.id.round_match_t1);
fTeamName = fTeamView.findViewById(R.id.match_team_name);
sTeamView = itemView.findViewById(R.id.round_match_t2);
sTeamName = sTeamView.findViewById(R.id.match_team_name);
itemView.setOnClickListener(this);

}

void bind(int listIndex) {
    listItemMatchNumber.setText(String.valueOf(listIndex + 1));
}


@Override
public void onClick(View v) {
    int clickedPosition = getAdapterPosition();
    mOnClickListener.onListItemClick(clickedPosition);
}}}

matches_groups_item.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<android.support.v7.widget.CardView
    android:id="@+id/mathes_card"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="3dp"
    card_view:cardCornerRadius="4dp">

    <TextView
        android:id="@+id/match_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="5dp"
        android:textColor="@color/red"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/match_date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="30dp"
        android:text="@string/select_winner" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/tv_informer"
        android:layout_marginTop="45dp"
        android:baselineAligned="false"
        android:orientation="horizontal">

        <include
            android:id="@+id/groups_match_t1"
            layout="@layout/team_no_buttons"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginStart="20dp" />

        <include
            android:id="@+id/groups_match_t2"
            layout="@layout/team_no_buttons"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>

team_no_button.xml:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/match_team_name_for_groups"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal" />

matches_rounds_items.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<android.support.v7.widget.CardView
    android:id="@+id/mathes_card"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="3dp"
    card_view:cardCornerRadius="4dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/round_card_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="5dp"
                android:textColor="@color/red"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/round_match_number"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="5dp"
                android:textColor="@color/red"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/round_match_date"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="5dp"
                android:text="@string/select_winner" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="4dp"
            android:baselineAligned="false"
            android:orientation="horizontal">

            <include
                android:id="@+id/round_match_t1"
                layout="@layout/team_no_buttons_shirts"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="20dp"
                android:layout_marginStart="20dp" />

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="2"
                android:gravity="center_horizontal"
                android:text="@string/vs" />

            <include
                android:id="@+id/round_match_t2"
                layout="@layout/team_no_buttons_shirts"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="20dp"
                android:layout_marginRight="20dp" />
        </LinearLayout>
    </LinearLayout>
</android.support.v7.widget.CardView>

team_no_buttons_shirts.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">


<TextView
    android:id="@+id/match_team_name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:textSize="20sp" />

Logcat:

06-26 11:58:13.111 4407-4407/sy.aya.ayaworldcup2018 E/QQ: Groups
06-26 11:58:13.114 4407-4407/sy.aya.ayaworldcup2018 D/AndroidRuntime: Shutting down VM
06-26 11:58:13.128 4407-4407/sy.aya.ayaworldcup2018 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: sy.aya.ayaworldcup2018, PID: 4407
    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(int)' on a null object reference
        at sy.aya.ayaworldcup2018.MatchesAdapter.onBindViewHolder(MatchesAdapter.java:72)
        at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6673)
        at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6714)
        at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5647)
        at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5913)
        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5752)
        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5748)
        at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2232)
        at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1559)
        at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1519)
        at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:614)
        at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3812)
        at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3529)
        at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:4082)
        at android.view.View.layout(View.java:19679)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:19679)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:19679)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:443)
        at android.view.View.layout(View.java:19679)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:19679)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
        at android.view.View.layout(View.java:19679)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at com.android.internal.policy.DecorView.onLayout(DecorView.java:761)
        at android.view.View.layout(View.java:19679)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2511)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2227)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1407)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6783)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
        at android.view.Choreographer.doCallbacks(Choreographer.java:723)
        at android.view.Choreographer.doFrame(Choreographer.java:658)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6499)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:440)
06-26 11:58:13.129 4407-4407/sy.aya.ayaworldcup2018 E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
        at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:108)
Zacktamondo
  • 1,891
  • 3
  • 17
  • 33
  • Please share full stack trace – Empty Brain Jun 26 '18 at 08:51
  • Thank you for your reply I tried this :https://stackoverflow.com/a/7841448/7592874 but I got the same error is there something I should do? – Zacktamondo Jun 26 '18 at 08:59
  • If you are using android studio stack trace for any error should be in the logcat by default – Empty Brain Jun 26 '18 at 09:04
  • @EmptyBrain added the logcat to the code thank you. – Zacktamondo Jun 26 '18 at 09:08
  • can you at least tell us the line of code that is causing the issue – Tim Jun 26 '18 at 09:11
  • show both layout every time. –  Jun 26 '18 at 09:11
  • 1
    Please for better performance: create a global variable `private String[] array;` and init it in the constructor `array = context.getResources().getStringArray(R.array.times);` – SamyB Jun 26 '18 at 09:12
  • groupsViewHolder.fTeamName.setText(R.string.russia); this is the line causing the problem every time I try to set the text in the first layout. – Zacktamondo Jun 26 '18 at 09:18
  • @SamyB thank you for the advice. – Zacktamondo Jun 26 '18 at 09:19
  • @EmptyBrain all the strings are in the strings.xml and I tried to put a string without referring to string.xml and still the same error. – Zacktamondo Jun 26 '18 at 09:22
  • @Zacktamondo `Attempt to invoke virtual method 'void android.widget.TextView.setText(int)' on a null object reference`. This error means you are trying to set text on a null object. `The referencing object is not a texview object`. `roundsViewHolder.fTeamName` fTeamName is not a textview object – Empty Brain Jun 26 '18 at 09:41
  • @EmptyBrain It is you can see that in the code I just used almost the same code for both ViewHolder the second layout works like charm but the first one doesn't. – Zacktamondo Jun 26 '18 at 09:44
  • are you have two layout @layout/team_no_buttons and @layout/team_no_button ? – GianhTran Jun 26 '18 at 09:47
  • @gianhtran no just one layout and I included it twice. – Zacktamondo Jun 26 '18 at 09:49

2 Answers2

3

As @Cheticamp said, the id (groups_match_t1) you specified in <include /> tag will override the id (match_team_name_for_groups) in the team_no_buttons.xml, so you can only find the view with id groups_match_t1, so this line:

fTeamView = itemView.findViewById(R.id.groups_match_t1);

will find a view, and it's actually the TextView itself, then:

fTeamName = fTeamView.findViewById(R.id.match_team_name_for_groups);

will return null, because there is no TextView inside the fTeamView. So you can just use:

fTeamName = itemView.findViewById(R.id.groups_match_t1);

to get the TextView, and just remove the fTeamView.

And because the team_no_buttons_shirts.xml has an extra LinearLayout, the id match_team_name will not be override, so:

fTeamView = itemView.findViewById(R.id.round_match_t1);

will return the LinearLayout, and

fTeamName = fTeamView.findViewById(R.id.match_team_name);

will find the correct TextView which is a child of the LinearLayout.

Also, Tor Norbye wrote:

The <include> tag is not a real view, so findByView will not find it. The @id attribute (and any other attributes you've set on the include tag) gets applied on the root tag of the included layout instead. So your activity.getView(R.id.included1) should in fact be the <TextView> itself.

Hong Duan
  • 4,234
  • 2
  • 27
  • 50
2

You are overriding the layout id match_team_name_for_groups with the id from the include statement groups_match_t1 or groups_match_t2 (not sure which one), so when you do a findViewById() you aren't seeing the id that is in the included file but the one from the include statement itself.

From the documentation:

You can also override all the layout parameters (any android:layout_* attributes) of the included layout's root view by specifying them in the tag.

Cheticamp
  • 61,413
  • 10
  • 78
  • 131