i am having a small problem with memory when i tried to used nested RecyclerView
and it crashed because it was not recycling views and as a result it run out of memory. So i have to go with another solution. I have created my own layout which accepts a Adapter like this:
public class CustomTileLayout extends LinearLayout {
private Adapter mAdapter;
private Observer mObserver = new Observer();
public CustomTileLayout(Context context) {
super(context);
}
public CustomTileLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public Adapter getAdapter() {
return mAdapter;
}
public void setAdapter(Adapter mAdapter) {
if (mAdapter != null)
mAdapter.unregisterDataSetObserver(mObserver);
this.mAdapter = mAdapter;
mAdapter.registerDataSetObserver(mObserver);
mObserver.onChanged();
}
private class Observer extends DataSetObserver {
@Override
public void onChanged() {
final List<View> oldViews = new ArrayList<View>(getChildCount());
for (int i = 0; i < getChildCount(); i++)
oldViews.add(getChildAt(i));
final Iterator<View> iter = oldViews.iterator();
removeAllViews();
for (int i = 0; i < mAdapter.getCount(); i++) {
View convertView = iter.hasNext() ? iter.next() : null;
View newView = mAdapter.getView(i, convertView, CustomTileLayout.this);
addView(newView);
}
super.onChanged();
}
@Override
public void onInvalidated() {
removeAllViews();
super.onInvalidated();
}
}
}
and while i use it like:
tileHolder = (GameCategoriesTileViewHolder) holder;
section = (Section) items.get(position);
tileHolder.customTileLayout.setAdapter(new GameTileAdapter(section.getGames(), context, R.layout.row_small_tile));
Everything works fine so far but there is a problem. The problem is that it looks like this:
while i want it each row to have 3 tiles like this:
If i specify the child layout to be like the result since it is the same item it only populates the 1st tile and the next 2 are blank.
My adapter:
public class GameTileAdapter implements ListAdapter {
private List<Game> games;
private Context context;
private int resLayout = R.layout.row_small_tile;
private boolean isFavoriteFragmentView = false;
private PopupMenu popupMenu;
public GameTileAdapter(List<Game> games, Context context, int resLayout) {
this.games = games;
this.context = context;
this.resLayout = resLayout;
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
}
@Override
public int getCount() {
return games.size();
}
@Override
public Object getItem(int position) {
return games.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
SingleItemViewHolder holder;
if (itemView == null){
LayoutInflater vi;
vi = LayoutInflater.from(context);
itemView = vi.inflate(resLayout, parent, false);
holder = new SingleItemViewHolder(itemView);
holder.game_name.setText(games.get(position).getName());
if (games.get(position).getImageUri().isEmpty()){
holder.game_imageuri.setImageResource(R.drawable.ic_image_placeholder);
}else {
Picasso.with(context).load(games.get(position).getImageUri()).into(holder.game_imageuri);
}
holder.itemLineColor.setBackgroundColor(GameManager.getmInstance(context).getGameColor(games.get(position)));
}else {
holder = (SingleItemViewHolder)itemView.getTag();
}
return itemView;
}
@Override
public boolean areAllItemsEnabled() {
return true;
}
@Override
public boolean isEnabled(int position) {
return true;
}
private static class SingleItemViewHolder{
CardView cv;
TextView game_name;
TextView game_is_new;
TextView game_jackpot;
ImageView game_imageuri;
View itemLineColor;
Button favorite_button;
Button menu_button;
SingleItemViewHolder(View itemView) {
cv = (CardView)itemView.findViewById(R.id.root_layout);
game_name = (TextView)itemView.findViewById(R.id.game_name_text);
game_is_new = (TextView)itemView.findViewById(R.id.game_new_ribbon);
game_jackpot = (TextView)itemView.findViewById(R.id.game_jackpot_ribbon);
game_imageuri = (ImageView)itemView.findViewById(R.id.game_imageuri);
itemLineColor = (View)itemView.findViewById(R.id.single_line_color);
favorite_button = (Button)itemView.findViewById(R.id.favButton);
menu_button = (Button)itemView.findViewById(R.id.menu_button_tile);
}
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return games.size();
}
@Override
public boolean isEmpty() {
return games.isEmpty();
}
}
Any ideas of how i can get the result?
You can use a layout for inner RecyclerView and add inflate a layout dynamically.