2017-10-09 93 views
1

我在android系统编程一个简单的游戏,我遇到了一个问题recyclerview。我需要帮助,Tnx :)Recyclerview意外的onclick项目

我有一个活动,创建一个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选择他们,但没有帮助过。

+0

RecyclerView回收其视图。当你选择一些东西的时候,为选定的视图的数据模型使用一些标志,并在你的onBIndViewHolder中检查该标志是否为真,然后显示选定的UI,否则显示。 –

回答

1

这是因为回收视图回收在OnBindViewHolder.To认为解决这个问题。

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

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的构造函数中的上面添加。

编辑:选中此更新code.Hope它可以帮助你。

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

    } 

    } 
} 
+0

我没有getAdapterPosition方法,我该如何实现它? –

+0

查看更新的代码。从onCreateViewHolder中删除view.setonClickListener。隐藏和显示应该在onBindViewHolder中完成,正如我上面显示的 – Anonymous

+0

谢谢但我应该在哪里定义SelectedCardView和CV_Prev,如果我删除createViewHolder中的点击侦听器? –

-2

看看这有助于:https://stackoverflow.com/a/46641850/4469112我刚才解释了如何正确设置上点击听众回收视图的适配器和观点的持有者。重要的部分是将侦听器设置为视图持有者(并且不直接指向视图),然后让视图持有者将自己设置为侦听器以传递视图。请记住,视图被回收并且内容在运行时绑定到它(当您滚动您的案例时),这就是为什么您将选择“转移”到其他项目。

0

替换此代码

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

,或者你可以创建一个全局变量来存储点击位置和后第二次点击

更改其可见