Replace Recyclerview with LinearLayout

901 views Asked by At

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:

problem

while i want it each row to have 3 tiles like this:

wanted result

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?

1

There are 1 answers

5
Rahul Chaudhary On BEST ANSWER

You can use a layout for inner RecyclerView and add inflate a layout dynamically.

 @Override
public void onBindViewHolder(RecentErrorsAdapter.ViewHolder holder, int position) {

    try {


        ArrayList<String> innerArrayList = new ArrayList<String>();
        innerArrayList = mDataset.get(position).getInnerDataList();

        for (int i = 0; i < innerArrayList.size(); i++) {



                LayoutInflater inflater = null;
                inflater = (LayoutInflater) context.getApplicationContext()
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                View mLinearView = inflater.inflate(R.layout.your_layout, null);
                /**
                 * getting id of row.xml
                 */
                TextView textName = (TextView) mLinearView
                        .findViewById(R.id.txt_name);
                textName.setText(innerArrayList.get(i));


                holder.lstProgramName.addView(mLinearView);

        }


    } catch (Exception e) {
        e.printStackTrace();
    }
}