Adam Gardner Adam Gardner -4 years ago 116
Android Question

Null RecyclerView when calling it from another RecyclerView

I have a RecyclerView that is displaying my CardView correctly. That CardView also contains a RecyclerView and I am trying to get that to show with hard coded data. The problem is I am getting null on the .setHasFixedSize(true) or any line after the second RecyclerView is declared.

I am calling the second RecyclerView after the first one is created...I think.

public class MainActivity extends AppCompatActivity {
TextView mWeatherTemp, mWeatherDescript;
Context context;
private ArrayList days;
private GridLayoutManager gridLayoutManager;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
Toolbar mToolbar = (Toolbar) findViewById(R.id.mMainToolbar);
setSupportActionBar(mToolbar);
mToolbar.setBackgroundColor(ContextCompat.getColor(this, R.color.weather_cool));

mWeatherTemp = (TextView) findViewById(R.id.tvWeatherTemp);
mWeatherDescript = (TextView) findViewById(R.id.tvWeatherText);

Typeface robotDisplay3 = Typeface.createFromAsset(context.getAssets(),
"font/Roboto-Regular.ttf");
mWeatherTemp.setTypeface(robotDisplay3);
initCardView();

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.settings, menu);
return super.onCreateOptionsMenu(menu);
}

public void initCardView() {
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.mMainRV);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);
days = new ArrayList();
days.add("TODAY");
days.add("TOMORROW");
RecyclerView.Adapter adapter = new HomeRecyclerAdapter(days);
recyclerView.setAdapter(adapter);

initHourlyGrid();
}

public void initHourlyGrid() {
List<HourlyForcast> listItem = getAllItemList();
gridLayoutManager = new GridLayoutManager(getApplicationContext(), 4);
RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.hourlyRecycler);
mRecyclerView.setHasFixedSize(true); //getting error here but happens if I comment this out, I am calling this method after the first RecyclerView method is called. So not sure whats going on.
mRecyclerView.setLayoutManager(gridLayoutManager);
RecyclerView.Adapter mAdapter = new HourlyForcastAdapter(getApplicationContext(), listItem);
mRecyclerView.setAdapter(mAdapter);
}

private List<HourlyForcast> getAllItemList() {
List<HourlyForcast> allHours = new ArrayList<>();
allHours.add(new HourlyForcast("4:00 PM", "8°", R.mipmap.ic_launcher));
allHours.add(new HourlyForcast("5:00 PM", "6°", R.mipmap.ic_launcher));
allHours.add(new HourlyForcast("6:00 PM", "5°", R.mipmap.ic_launcher));
allHours.add(new HourlyForcast("7:00 PM", "3°", R.mipmap.ic_launcher));
allHours.add(new HourlyForcast("8:00 PM", "3°", R.mipmap.ic_launcher));
allHours.add(new HourlyForcast("9:00 PM", "3°", R.mipmap.ic_launcher));
allHours.add(new HourlyForcast("10:00 PM", "4°", R.mipmap.ic_launcher));
allHours.add(new HourlyForcast("11:00 PM", "60°", R.mipmap.ic_launcher));

return allHours;
}
}

public class HourlyForcastAdapter extends RecyclerView.Adapter<HourlyForcastAdapter.HourlyViewHolder> {
private List<HourlyForcast> itemList;
private Context context;

public HourlyForcastAdapter(Context context, List<HourlyForcast> itemList) {
this.itemList = itemList;
this.context = context;
}

@Override
public HourlyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.hourly_single, parent, false);
return new HourlyViewHolder(view);
}

@Override
public void onBindViewHolder(HourlyViewHolder holder, int position) {
holder.mTimeText.setText(itemList.get(position).getTime());
holder.mDegreeText.setText(itemList.get(position).getDegrees());
holder.mWeatherIcon.setImageResource(itemList.get(position).getImageID());
}

@Override
public int getItemCount() {
return itemList.size();
}

public static class HourlyViewHolder extends RecyclerView.ViewHolder {
TextView mTimeText, mDegreeText;
ImageView mWeatherIcon;

public HourlyViewHolder(View itemView) {
super(itemView);
mTimeText = (TextView) itemView.findViewById(R.id.timePlaceHolder);
mDegreeText = (TextView) itemView.findViewById(R.id.degreePlaceHolder);
mWeatherIcon = (ImageView) itemView.findViewById(R.id.weatherIconHolder);
}
}
}


public class HomeRecyclerAdapter extends RecyclerView.Adapter<HomeRecyclerAdapter.ViewHolder> {
private ArrayList<String> dates;
Context context;

public HomeRecyclerAdapter(ArrayList<String> dates) {
this.dates = dates;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int i) {
context = parent.getContext();
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.hourly_cardview, parent, false);
return new ViewHolder(view);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Typeface titleStyle = Typeface.createFromAsset(context.getAssets(),
"font/Roboto-Medium.ttf");
holder.mDate.setTypeface(titleStyle);
holder.mDate.setText(dates.get(position));
}

@Override
public int getItemCount() {
return dates.size();
}

public static class ViewHolder extends RecyclerView.ViewHolder {
private TextView mDate;

ViewHolder(View view) {
super(view);
mDate = (TextView) view.findViewById(R.id.tvDate);
}
}
}

Answer Source

You cannot use findViewById to get the View in the adapter of the outer RecyclerView. To init the sub RecyclerView in the HomeRecyclerAdapter can solve this problem.

like this

```

@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                               int viewType) {
    gridLayoutManager = new GridLayoutManager(getApplicationContext(), 4);

    RecyclerView recyclerView = (RecyclerView)  LayoutInflater.from(parent.getContext())
                           .inflate(R.layout. hourlyRecycler, parent, false);
    recyclerView.setHasFixedSize(true); 
    recyclerView.setLayoutManager(gridLayoutManager);
    RecyclerView.Adapter adapter = new HourlyForcastAdapter(getApplicationContext(), listItem);
    recyclerView.setAdapter(mAdapter);      

    // or move above code into ViewHolder
    ViewHolder vh = new ViewHolder(v);
    return vh;
}

```

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download