2017-10-09 88 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);

,或者你可以創建一個全局變量來存儲點擊位置和後第二次點擊

更改其可見