java - Recyclerview 意外地 onclick 项目

标签 java android android-recyclerview onclick

我正在 Android 中编写一个简单的游戏,并且遇到了 recyclerview 的问题。我需要帮助,tnx:)

我有一个 Activity ,它创建一个 arrayList 并向其中添加我的数据,然后将其传递给我的 recyclerview 的适配器。在适配器中,我编写了用户只能选择图像的代码。现在,当我选择第一个项目然后滚动 recyclerview 时,问题就出现了,我看到最后三个项目之一被选中。这种情况仅发生在第一个订单项和最后三个项目上。

我能为此做什么?

我的 Activity :

public class page_register extends AppCompatActivity {

    Activity _A;
    Context _C;

    private RecyclerView recyclerView1, recyclerView2;
    private AdsAdapter adapter1;
    private Avatar2Adapter adapter2;

    private ArrayList<Ads> adsArrayList;

    TextView Tv1, Tv2;
    EditText ET1, ET2;
    Button BT_First, BT_Second;
    ImageButton BT_Back;
    ImageView img_first, img_second;
    CardView cardView1, cardView2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.page_register);
        M_UI.SetOffKeyboard(this);
        M_Font.Initial(this);

        _A = this;
        _C = this;

        Initial();


        adsArrayList = new ArrayList<>();
        adsArrayList.add(new Ads(R.drawable.a1));
        adsArrayList.add(new Ads(R.drawable.a2));
        adsArrayList.add(new Ads(R.drawable.a3));
        adsArrayList.add(new Ads(R.drawable.a4));
        adsArrayList.add(new Ads(R.drawable.a5));
        adsArrayList.add(new Ads(R.drawable.a6));
        adsArrayList.add(new Ads(R.drawable.a7));
        adsArrayList.add(new Ads(R.drawable.a8));
        adsArrayList.add(new Ads(R.drawable.a9));
        adsArrayList.add(new Ads(R.drawable.a10));
        adsArrayList.add(new Ads(R.drawable.a11));
        adsArrayList.add(new Ads(R.drawable.a12));
        adsArrayList.add(new Ads(R.drawable.a13));
        adsArrayList.add(new Ads(R.drawable.a14));
        adsArrayList.add(new Ads(R.drawable.a15));
        adsArrayList.add(new Ads(R.drawable.a16));             
        adsArrayList.add(new Ads(R.drawable.a17));
        adsArrayList.add(new Ads(R.drawable.a18));
        adsArrayList.add(new Ads(R.drawable.a19));
        adsArrayList.add(new Ads(R.drawable.a20));
        adsArrayList.add(new Ads(R.drawable.a21));
        //--------------------------------------------

        adapter1 = new AdsAdapter(adsArrayList, this, _C, _A, recyclerView1, 0);
        adapter2 = new Avatar2Adapter(adsArrayList, this, _C, _A, recyclerView2, 0);

        RecyclerView.LayoutManager layoutManager1 = new GridLayoutManager(_C, 3);
        RecyclerView.LayoutManager layoutManager2 = new GridLayoutManager(_C, 3);
        recyclerView1.setLayoutManager(layoutManager1);
        recyclerView2.setLayoutManager(layoutManager2);

        recyclerView1.setAdapter(adapter1);
        recyclerView2.setAdapter(adapter2);
    }     

    public void Initial() {
        recyclerView1 = (RecyclerView) findViewById(R.id.recycler_view1);
        recyclerView2 = (RecyclerView) findViewById(R.id.recycler_view2);    

    }
}

和我的适配器:

public class AdsAdapter extends RecyclerView.Adapter<AdsAdapter.AdsViewHolder> {

    private ArrayList<Ads> dataList;

    Context _C1;
    Activity _A1;

    RecyclerView r;

    int SelectedPos = 0;

    int id_prev;
    CardView CV_Prev = null;

    public AdsAdapter(ArrayList<Ads> dataList, FragmentActivity activity, Context _C, Activity _A, RecyclerView recyclerView, int i) {
        this.dataList = dataList;

        _A1 = _A;
        _C1 = _C;
        r = recyclerView;

    }


    @Override
    public AdsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        final View view = layoutInflater.inflate(R.layout.avatars, parent, false);


        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View SelectCardView) {

                try {

                    if (CV_Prev != null) {
                        CV_Prev.findViewById(R.id.img_select).setVisibility(View.INVISIBLE);
                    }
                    SelectCardView.findViewById(R.id.img_select).setVisibility(View.VISIBLE);



                    CV_Prev = (CardView) SelectCardView;

                } catch (Exception e) {
                    Toast.makeText(_C1, e.getMessage(), Toast.LENGTH_SHORT).show();
                }
            }
        });

        return new AdsViewHolder(view);
    }

    @Override
    public void onBindViewHolder(AdsViewHolder holder, int position) {

         holder.CV_item.setTag(position);
        //------------------------------------------------------------------
        holder.img_avatar.setImageResource(dataList.get(position).getImage());


    }


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


    class AdsViewHolder extends RecyclerView.ViewHolder {

        ImageView img_avatar;
        CardView CV_item;

        AdsViewHolder(View itemView) {
            super(itemView);
            //-----------------------------------------------------------
            img_avatar = (ImageView) itemView.findViewById(R.id.img_avatar);
            CV_item = (CardView) itemView.findViewById(R.id.cardView);

        }

    }
}

我的观点:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cardView"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="#00ffffff"
    android:layoutDirection="ltr"
    android:paddingLeft="5dp"
    android:paddingRight="5dp"
    card_view:cardBackgroundColor="#B2EBF2"
    card_view:cardCornerRadius="5dp"
    card_view:cardElevation="5dp"
    card_view:cardUseCompatPadding="true">

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">


        <ImageView
            android:id="@+id/img_avatar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#00ffffff"
            card_view:srcCompat="@drawable/a1" />

        <ImageView
            android:id="@+id/img_select"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:visibility="invisible"
            card_view:srcCompat="@mipmap/ic_check_circle_black_48dp" />


    </RelativeLayout>


</android.support.v7.widget.CardView>

我的模型:

public class Ads {

    private int image;



    public Ads(int image) 

      {
        this.image = image;
      }



    public void setImage(int image) {this.image = image;}

    public int getImage() {return image;}

  }

下图显示了我的意思:

enter image description here

*** 我尝试为每张卡片和图像设置 ID,并通过 ID 选择它们,但这也没有帮助。

最佳答案

发生这种情况是因为回收器 View 回收了OnBindViewHolder中的 View 。要解决这个问题。

创建一个全局变量来存储点击位置。

private mItemSelected=-1;

然后在viewholder中添加clickListener和onClick存储被点击项目的位置。

class AdsViewHolder extends RecyclerView.ViewHolder {

    ImageView img_avatar;
    CardView CV_item;
    AdsViewHolder(View itemView) {
        super(itemView);
        //-----------------------------------------------------------
        img_avatar = (ImageView) itemView.findViewById(R.id.img_avatar);
        CV_item = (CardView) itemView.findViewById(R.id.cardView);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mItemSelected=getAdapterPosition();
                notifyDataSetChanged();
            }
        });

    }

}

并在 OnBindViewHolder 内部,

if(mItemSelected==position){

//code for image selected.
  holder.CV_item.setVisibility(View.VISIBLE);

}else{

//code for image unselected.
  holder.CV_item.setVisibility(View.INVISIBLE);

}   

同时删除已在 createViewholder 中添加的点击监听器,而是将其添加到上面添加的 AdsViewHolder 构造函数中。

编辑:检查此更新的代码。希望它对您有所帮助。

public class AdsAdapter extends RecyclerView.Adapter<AdsAdapter.AdsViewHolder> {

private ArrayList<Ads> dataList;
Context _C1;
Activity _A1;
RecyclerView r;
int SelectedPos = 0;
int id_prev;
CardView CV_Prev = null;
private int mItemSelected=-1;

public AdsAdapter(ArrayList<Ads> dataList, FragmentActivity activity, Context _C, Activity _A, RecyclerView recyclerView, int i) {
    this.dataList = dataList;
    _A1 = _A;
    _C1 = _C;
    r = recyclerView;

}


@Override
public AdsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
    final View view = layoutInflater.inflate(R.layout.avatars, parent, false);
    return new AdsViewHolder(view);
}

@Override
public void onBindViewHolder(AdsViewHolder holder, int position) {

 holder.CV_item.setTag(position);
holder.img_avatar.setImageResource(dataList.get(position).getImage());
    if(mItemSelected==position){

     //code for image selected. 
        holder.CV_item.setVisibility(View.VISIBLE);

    }else{

    //code for image unselected. 
        holder.CV_item.setVisibility(View.INVISIBLE);

    }

}

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


class AdsViewHolder extends RecyclerView.ViewHolder {

    ImageView img_avatar;
    CardView CV_item;
    AdsViewHolder(View itemView) {
        super(itemView);
        //-----------------------------------------------------------
        img_avatar = (ImageView) itemView.findViewById(R.id.img_avatar);
        CV_item = (CardView) itemView.findViewById(R.id.cardView);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mItemSelected=getAdapterPosition();
                notifyDataSetChanged();
            }
        });

    }

  }
}

关于java - Recyclerview 意外地 onclick 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46642700/

相关文章:

java - zip4j 如何解压目录

android - 无法在 Android Studio 上打开本地终端(在 Mac 上)

android - 使用jlayer在Android上进行慢速MP3解码

Android - 在webview中登录后提取cookies

android - 找不到 getAdapterPosition() 作为方法

android - Android中展开recyclerView时如何旋转图像

java - 将一个对象序列化为多个不同的xml

java - 从位图 rgb_565 转换为 Mat

java - 在列表中存储多种对象类型

java - 如何找出回收站 View 捕捉到的项目?