3

Basically I wanted to add one TextView into a RecyclerView as the header section, but at the same time I also wanted to remove this header under the condition that a string is null. In such case, only regular ViewItems display.

Here is my code:

public class HeaderAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private static final int TYPE_HEADER = 0; private static final int TYPE_ITEM = 1; String[] data; public HeaderAdapter(String[] data) { this.data = data; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == TYPE_ITEM) { //inflate your layout and pass it to view holder return new VHItem(null); } else if (viewType == TYPE_HEADER) { //inflate your layout and pass it to view holder return new VHHeader(null); } throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly"); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof VHItem) { String dataItem = getItem(position); //cast holder to VHItem and set data } else if (holder instanceof VHHeader) { //cast holder to VHHeader and set data for header. } } @Override public int getItemCount() { return data.length + 1; } @Override public int getItemViewType(int position) { if (isPositionHeader(position)) return TYPE_HEADER; return TYPE_ITEM; } private boolean isPositionHeader(int position) { return position == 0; } private String getItem(int position) { return data[position - 1]; } class VHItem extends RecyclerView.ViewHolder { TextView title; public VHItem(View itemView) { super(itemView); } } class VHHeader extends RecyclerView.ViewHolder { Button button; public VHHeader(View itemView) { super(itemView); } } } 
1
  • I would use this library instead: github.com/eyeem/RecyclerViewTools. You can just wrap your adapter with another that gives you the functionality you want. Like WrapAdapter wrapAdapter = new WrapAdapter(adapter); then wrapAdapter.addHeader(view); and wrapAdapter.removeHeader(adapter);` Commented Dec 19, 2015 at 19:52

1 Answer 1

1

The crude and easy way would be just to hide the first item with yourInflatedLayout.setVisibility(View.GONE) or set it to zero dimensions with yourInflatedLayout.setLayoutParams(new ViewGroup.LayoutParams(0,0)) after checking for the desired condition (an empty string in your case) – though in doing so your view would still be inflated, in vain.

The check would be just a simple condition like this (from your code snippet – assuming that you also add your own way to inflate the layout, since in your code you just pass null to the ViewHolder's constructor):

 } else if (viewType == TYPE_HEADER) { //inflate your layout and pass it to view holder yourInflatedLayout = LayoutInflater .from(yourContext) .inflate(R.layout.your_layout, parent, false); // here you perform the check if (yourCheckedString == null) { yourInflatedLayout.setVisibility(View.GONE); } return new VHHeader(yourInflatedLayout); } } 

The better way (according to me) would be to handle the problem in the adapter's logic. Something like this (just to illustrate):

// you'll have to introduce a way to find out whether the desired string is null – a method is just one way to do this private boolean isStringNull() { return yourCheckedString == null; } @Override public int getItemCount() { // if the string is null and, we won't display the "header" item and we thus don't want to increment the item count by 1 return data.length + (isStringNull() ? 0 : 1); } @Override public int getItemViewType(int position) { // we want to display the header only if the string is not null, so we need to incorporate this requirement into the condition if (isPositionHeader(position) && !isStringNull()) return TYPE_HEADER; return TYPE_ITEM; } private boolean isPositionHeader(int position) { return position == 0; } private String getItem(int position) { // we've already specified that the item count in the adapter won't be incremented if the string is null, so we have to reflect the change also here to avoid going out of the bounds of our data array return data[position - (isStringNull() ? 0 : 1)]; } 
Sign up to request clarification or add additional context in comments.

Comments