Recyclerview意外地点击了项目

时间:2017-10-09 09:10:23

标签: java android android-recyclerview onclick

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

我有一个活动创建arrayList并将数据添加到其中,然后将其传递给我的recyclerview适配器。在adapter我编写的代码中,用户无法选择多于图像。现在问题在于,当我选择第一个项目然后滚动recyclerview时,我看到最后三个项目中的一个被选中。这种情况只发生在第一行和最后三个项目中。

我能为此做些什么?

我的活动:

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选择,但这也没有帮助。

3 个答案:

答案 0 :(得分:1)

这是因为Recycler视图在OnBindViewHolder中回收视图。要解决这个问题。

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

private mItemSelected=-1;

然后在视图内部添加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();
            }
        });

    }

  }
}

答案 1 :(得分:0)

  

替换此代码

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

  

或者您可以创建一个全局变量来存储单击的位置,并在第二次单击后更改其可见性

答案 2 :(得分:-2)

看看这是否有帮助:https://stackoverflow.com/a/46641850/4469112我刚刚解释了如何正确设置点击监听器到回收站视图的适配器和视图持有者。重要的是将侦听器设置为视图持有者(而不是直接设置到视图),然后让视图持有者将自己设置为传递视图的侦听器。请记住,视图已被回收,并且内容在运行时绑定到该视图(当您在案例中滚动时),这就是您将选择“转移”到其他项目的原因。