繁体   English   中英

RecyclerView Adapter在奇怪的位置插入行

[英]RecyclerView Adapter inserting rows in weird positions

我的MainActivity内部有一个Fragment ,其中包含由RecyclerView填充的RecyclerView.Adapter RecyclerView使row_layout.xml文件膨胀,该文件具有一个EditText和一个ImageButton ,如下所示:

在此处输入图片说明

该按钮最初加载有“添加”图像。 单击后,我的适配器将执行以下操作:

package com.fragments.homework04;

    import android.support.v7.widget.RecyclerView;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.EditText;
    import android.widget.ImageView;

    import java.util.ArrayList;

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
        public static int positionAdapter;

        private ArrayList<ItemData> itemsData;
        AdapterButtonInterface mListener;

        public MyAdapter(ArrayList<ItemData> itemsData, AdapterButtonInterface adapterButtonInterface) {
            this.itemsData = itemsData;
            try{
                mListener = adapterButtonInterface;
            }
            catch(ClassCastException e){
                throw new ClassCastException("Class does not implement interface!");
            }
        }

        public static class ViewHolder extends RecyclerView.ViewHolder {

            public EditText txtIngredients;
            public ImageView imgViewIcon;

            public ViewHolder(View itemLayoutView) {
                super(itemLayoutView);
                txtIngredients = itemLayoutView.findViewById(R.id.etIngredientName);
                imgViewIcon = itemLayoutView.findViewById(R.id.btnAddRemoveIngredient);
            }
        }

        @Override
        public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout, null);
            Log.d("itemsSizeAdapter", String.valueOf(itemsData.size()));
            ViewHolder viewHolder = new ViewHolder(itemLayoutView);
            return viewHolder;
        }

        @Override
        public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
            viewHolder.imgViewIcon.setTag(itemsData.get(position).getTag());
            viewHolder.imgViewIcon.setImageResource(itemsData.get(position).getImageUrl());
            viewHolder.imgViewIcon.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    positionAdapter = viewHolder.getAdapterPosition();
                    if(itemsData.get(position).getTag().contains("Add")){
                        if(getItemCount() < 5){
                            itemsData.get(position).setIngredientValue(viewHolder.txtIngredients.getText().toString());
                            mListener.addBtnClicked(positionAdapter, getItemCount(), itemsData.get(position).getIngredientValue());
                        }
                    }
                    else{
                        if(getItemCount() > 0){
                            Log.d("adapterPosition:", String.valueOf(position));
                            mListener.removeBtnClicked(positionAdapter, getItemCount());
                        }
                    }
                }
            });
        }

        // Return the size of your itemsData (invoked by the layout manager)
        @Override
        public int getItemCount() {
            return itemsData.size();
        }

        public interface AdapterButtonInterface{
            void addBtnClicked(int position, int itemCount, String ingredientValue);
            void removeBtnClicked(int position, int itemCount);
        }
    }

基本上在接口中调用该方法,该方法由我的片段实现。 在我的片段中,我正在这样做:

ArrayList<ItemData> itemsData;
public void addBtnClicked(int position, int itemCount, String ingredientValue) {
    if(itemCount == 4){ 
    //Requirement that there can only be 5 rows at any time.
    //Hence when itemCount == 4, we are adding the 5th row and it needs to be a remove instead of add
        itemsData.add(position + 1, new ItemData("Remove" + itemCount, R.mipmap.remove_ing, ""));
    }
    else{
        itemsData.add(position + 1, new ItemData("Add" + itemCount, R.mipmap.add_ing, ""));
    }
    //When the row is added, the EditText's value isn't stored anywhere
    //So I am adding it to the arraylist I have
    itemsData.get(position).setIngredientValue(ingredientValue);
    itemsData.get(position).setImageUrl(R.mipmap.remove_ing);
    itemsData.get(position).setTag("Remove");
    mAdapter.notifyDataSetChanged();
}

@Override
public void removeBtnClicked(int position, int itemCount) {
    Log.d("listenerPosition:", String.valueOf(position));
    itemsData.remove(position);
    if(itemCount == 5){
        itemsData.get(3).setImageUrl(R.mipmap.add_ing);
        itemsData.get(3).setTag("Add3");
    }
    mAdapter.notifyDataSetChanged();
}

其中很大一部分效果很好。 应用加载时,我看到一个EditText和一个ImageButton。 当我第一次单击ImageButton时,它将在第二个EditText和第二个ImageButton的下面添加它。

但是,第二次单击按钮时出现了问题。 第三行插入在RecyclerView的顶部而不是底部。 我已经存在的第一和第二行(与EditText的内容一起)被下推,而我新添加的行位于回收站的顶部。

当我单击新插入的第一行上的“删除”按钮时,它甚至变得更奇怪。 它删除一行(按预期方式),并清除我所有的EditTexts(WHY)。

如果有人可以看看并告诉我我在哪里犯错,我将不胜感激。 如果需要,我可以提供更多代码。

您可以在ViewHolder指定该位置为final位置,以便可以在onClick()处理程序中引用该位置。 由于该变量是final变量,因此无论ViewHolder可能处于任何新位置,它都不会改变。 代替使用final变量,请尝试使用getAdapterPosition()

getAdapterPosition

int getAdapterPosition()

返回此ViewHolder表示的项目的Adapter位置。

这可能不是您的问题,但请尝试一下。

在适配器中使用这两种方法

@Override
    public long getItemId(int position) {
        return super.getItemId(position);
    }

    @Override
    public int getItemViewType(int position) {
        return super.getItemViewType(position);
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM