Android-RecyclerView重复以编程方式添加的图像视图

问题描述 投票:1回答:3

在我的项目中,我需要根据Web服务的响应在每行中添加不同数量的ImageView,我设法做到这一点,但是当我在recyclerView上滚动时,这些行中的ImageView会重复。

我的应用程序的想法是能够创建和共享连击(用于视频游戏的输入集)。这是我的适配器代码。

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (viewType == TYPE_COMBO) {
        View row = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent,false);
        ComboViewHolder comboViewHolder = new ComboViewHolder(row);
        return comboViewHolder;
    } else {
        View row = LayoutInflater.from(parent.getContext()).inflate(R.layout.progress_footer, parent, false);
        FooterViewHolder footerViewHolder = new FooterViewHolder(row);
        return footerViewHolder;
    }
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (holder instanceof ComboViewHolder) {
        ComboViewHolder comboViewHolder = (ComboViewHolder) holder;
        ComboImp comboImp = (ComboImp) data.get(position);
        ComboConverter comboConverter = new ComboConverter();
        comboConverter.convertToPS4(comboImp.getCombo());
        LinearLayout LinearLayout = new LinearLayout(mContext);
        LinearLayout.LayoutParams imageViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        int[] comboItems = comboConverter.convertToPS4(comboImp.getCombo());
        PairingFunction pairingFunction = new PairingFunction();
        for (int i = 0; i < comboItems.length; i++) {
            int id = pairingFunction.pair(i + 1, position + 1);
            comboViewHolder.imageView = new ImageView(mContext);
            comboViewHolder.imageView.setId(id);
            comboViewHolder.imageView.setImageResource(0);
            comboViewHolder.imageView.setLayoutParams(imageViewParams);
            comboViewHolder.imageView.setImageResource(comboConverter.getPs4Picture(Control.getByCode(comboItems[i])));
            linearLayout.addView(comboViewHolder.imageView);
        }
        comboViewHolder.linearLayout.addView(linearLayout);
    }
}


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


public static class ComboViewHolder extends RecyclerView.ViewHolder{
    private TextView combo,postDate;
    private View circleView;
    private LinearLayout linearLayout;
    private ImageView imageView;
    public ComboViewHolder(View itemView) {
        super(itemView);

        linearLayout = (LinearLayout)itemView.findViewById(R.id.LinearRow);
        linearLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                imageView.setImageResource(R.drawable.ps4_square_30x30);
            }
        });
    }
    public TextView getCombo() {
        return combo;
    }
    public TextView getPostDate() {
        return postDate;
    }

    public View getCircleView() {
        return circleView;
    }

    public View getImageView() {
        return imageView;
    }
    public LinearLayout getLinearLayout(){return linearLayout;}
}

至于XML文件是一个简单的LinearLayout,其中没有任何内容。

我使用配对功能为创建的每个ImageView设置了唯一的ID,这并不完美(具有足够的行数和ImageView整数将最大化),但现在可以使用

android android-recyclerview recycler-adapter
3个回答
0
投票

您需要在顶部的onBindViewHolder()方法中添加这样的行

comboViewHolder.linearLayout.removeAllViews();

0
投票

以编程方式添加的视图和Recycler / Grid / List视图是不好的组合。它们确实与回收有关,因为您是将它们添加到视图中,但是回收时它们不会被移除。为了使它们起作用,每次调用onBindViewHolder时,您都必须删除所有以编程方式添加的视图并读取它们。这与视图回收这种想法非常相反,因为它在时间上非常昂贵,因此实际上不建议这样做。

唯一的想法是将自己的回收逻辑写入布局,以便您从单独的回收池中手动回收添加的视图。这是可行的,但真正的脖子痛。

成为一个好人-这是我的LinearLayout替代品,用于回收再利用。它的效率仍然不是100%(需要在行之间共享才能更好,我有一天会做到这一点),但是它至少会最小化在回收布局中添加新行的性能影响。随意调整它以使其与RelativeLayout一起使用,看起来就像您需要的一样:

public class RecycledLinearLayout extends LinearLayout {

    public interface RecyledLinearLayoutAdapter<ItemType, HolderType> {
        View createView(ViewGroup parent);
        HolderType createHolder(View view);
        void assignToView(View view, HolderType holder, ItemType item);
    }

    private List<View> mRecycledTaskViews;
    private List<Object> mRecycledTaskHolders;
    private RecyledLinearLayoutAdapter mAdapter;

    public RecycledLinearLayout(Context context) {
        super(context);
        init(context, null, 0);
    }

    public RecycledLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public RecycledLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr);
    }

    public void init(Context context, AttributeSet attrs, int defStyleAttr) {
        mRecycledTaskViews = new ArrayList<>();
        mRecycledTaskHolders = new ArrayList<>();
    }

    public void setAdapter(RecyledLinearLayoutAdapter adapter) {
        mAdapter = adapter;
    }

    public void setItems(List items) {
        removeAllViews();
        if(mAdapter == null || items == null) {
            return;
        }
        for(int i = mRecycledTaskViews.size(); i < items.size(); i++) {
            View view = mAdapter.createView(this);
            mRecycledTaskViews.add(view);
            mRecycledTaskHolders.add(mAdapter.createHolder(view));
        }
        for(int i=0; i < items.size(); i++) {
            Object item = items.get(i);
            View currentView = mRecycledTaskViews.get(i);
            Object currentHolder = mRecycledTaskHolders.get(i);
            mAdapter.assignToView(currentView, currentHolder, item);
            addView(currentView);
        }
    }

}

0
投票

尝试一下...

   for (int i = 0; i < comboItems.length; i++) {
              int id = pairingFunction.pair(i + 1, position + 1);
              ImageView imageView = new ImageView(mContext);
              imageView.setId(id);
              imageView.setImageResource(0);
              imageView.setLayoutParams(imageViewParams);
              imageView.setImageResource(comboConverter.getPs4Picture(Control.getByCode(comboItems[i])));
              relativeLayout.addView(imageView);
    }
© www.soinside.com 2019 - 2024. All rights reserved.