【问题标题】:Replace Recyclerview with LinearLayout用 LinearLayout 替换 Recyclerview
【发布时间】:2017-01-05 12:44:47
【问题描述】:

当我尝试使用嵌套的RecyclerView 时,我遇到了一个内存小问题,它崩溃了,因为它没有回收视图,因此内存不足。所以我必须采用另一种解决方案。我创建了自己的布局,它接受这样的适配器:

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();
        }
    }
}

当我像这样使用它时:

tileHolder = (GameCategoriesTileViewHolder) holder;
section = (Section) items.get(position);
tileHolder.customTileLayout.setAdapter(new GameTileAdapter(section.getGames(), context, R.layout.row_small_tile));

到目前为止一切正常,但有一个问题。问题是它看起来像这样:

虽然我希望每行有 3 个这样的图块:

如果我将子布局指定为与结果类似,因为它是同一个项目,它只填充第一个图块,接下来的 2 个为空白。

我的适配器:

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();
    }
}

关于如何获得结果的任何想法?

【问题讨论】:

    标签: android android-linearlayout listadapter


    【解决方案1】:

    您可以为内部 RecyclerView 使用布局并动态添加布局。

     @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();
        }
    }
    

    【讨论】:

    • 我不认为你理解这个问题。我的问题不是如何添加视图,而是如何以编程方式将线性布局分隔为 3 列
    • 如果你想连续添加 3 个项目,你可以创建一个包含水平 3 个元素的线性布局,如果你想分离线性布局,请在布局底部添加一个视图
    • 在线性布局中添加水平方向,但如果一部分足够大,您应该在水平滚动视图中使用线性布局
    • 如果我添加一个线性布局水平方向,那么只有水平行中的第一项被填充。我希望水平行中的所有项目都具有相同的布局
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多