溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

RecyclerView中如何解決使用CheckBox出現(xiàn)勾選混亂的問(wèn)題

發(fā)布時(shí)間:2021-07-12 14:18:50 來(lái)源:億速云 閱讀:158 作者:小新 欄目:移動(dòng)開發(fā)

這篇文章給大家分享的是有關(guān)RecyclerView中如何解決使用CheckBox出現(xiàn)勾選混亂的問(wèn)題的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

首先當(dāng)然是創(chuàng)建一個(gè)項(xiàng)目,然后在activity_main中添加一個(gè)RecyclerView控件,當(dāng)然,在這之前,我們需要先添加RecyclerView的依賴,如下圖:

RecyclerView中如何解決使用CheckBox出現(xiàn)勾選混亂的問(wèn)題

然后 開始編輯activity_main:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout  
  xmlns:android="http://schemas.android.com/apk/res/android" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" 
  android:orientation="vertical"> 
   
  <android.support.v7.widget.RecyclerView 
    android:id="@+id/id_recycler_view" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
     
  </android.support.v7.widget.RecyclerView> 
</LinearLayout>

接下來(lái)為這個(gè)RecyclerView創(chuàng)建一個(gè)item布局文件,命名為item_recyclerview,并添加一個(gè)CheckBox空間,代碼如下:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout  
  xmlns:android="http://schemas.android.com/apk/res/android" 
  android:orientation="vertical"  
  android:layout_width="match_parent" 
  android:layout_height="60dp" 
  android:gravity="center_vertical"> 
 
  <CheckBox 
    android:id="@+id/id_check_box" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_marginLeft="10dp" 
    android:text="CheckBox"/> 
</LinearLayout>

接下來(lái)要編輯MainActivity了,包括從布局文件中找到剛才的RecyclerView控件,然后為其設(shè)置Adapter等,過(guò)程不再詳細(xì)敘述,編輯后的代碼如下:

public class MainActivity extends AppCompatActivity { 
 
  private RecyclerView recyclerView; 
  private MyAdapter myAdapter; 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
 
    recyclerView = (RecyclerView) findViewById(R.id.id_recycler_view); 
    myAdapter = new MyAdapter(); 
    recyclerView.setLayoutManager(new LinearLayoutManager(this)); 
    recyclerView.setAdapter(myAdapter); 
  } 
 
 
 
  private class MyAdapter extends RecyclerView.Adapter { 
 
    private List<String> content; 
 
    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
      View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_recyclerview, parent, false); 
      return new MyViewHolder(view); 
    } 
 
    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 
      MyViewHolder myViewHolder = (MyViewHolder) holder; 
      myViewHolder.checkBox.setText(content.get(position)); 
 
    } 
 
    @Override 
    public int getItemCount() { 
      content = new ArrayList<>(); 
      for (int i = 0; i < 100; i++) { 
        content.add("CheckBox" + i); 
      } 
      return content.size(); 
    } 
  } 
 
 
  private class MyViewHolder extends RecyclerView.ViewHolder { 
 
    private CheckBox checkBox; 
 
    public MyViewHolder(View itemView) { 
      super(itemView); 
      checkBox = (CheckBox) itemView.findViewById(R.id.id_check_box); 
    } 
  } 
}

可以看到,我們?yōu)檫@個(gè)RecyclerView設(shè)置了100個(gè)item,每個(gè)item里面都含有一個(gè)CheckBox,這時(shí)候運(yùn)行這個(gè)應(yīng)用,勾選出現(xiàn)的屏幕上的某一個(gè)或者多個(gè)CheckBox之后,當(dāng)你向下拉的時(shí)候,問(wèn)題出現(xiàn)了,你會(huì)發(fā)現(xiàn)下面會(huì)有很多的CheckBox也被選中了。下面我們就來(lái)著手解決這個(gè)問(wèn)題,其實(shí)要解決也很簡(jiǎn)單,可以定義一個(gè)boolean類型的數(shù)組或者列表,用它來(lái)控制CheckBox的選中狀態(tài),當(dāng)某個(gè)CheckBox被選中的時(shí)候?qū)⑵溥x中狀態(tài)記錄在數(shù)組或列表中,當(dāng)某個(gè)CheckBox滾動(dòng)到屏幕上的時(shí)候,再用數(shù)組或列表中對(duì)應(yīng)的值把它的選中狀態(tài)改回來(lái)就好了,修改后的代碼如下:

public class MainActivity extends AppCompatActivity { 
 
  private RecyclerView recyclerView; 
  private MyAdapter myAdapter; 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
 
    recyclerView = (RecyclerView) findViewById(R.id.id_recycler_view); 
    myAdapter = new MyAdapter(); 
    recyclerView.setLayoutManager(new LinearLayoutManager(this)); 
    recyclerView.setAdapter(myAdapter); 
  } 
 
 
 
  private class MyAdapter extends RecyclerView.Adapter { 
 
    private List<String> content; 
    private boolean[] flag = new boolean[100];//此處添加一個(gè)boolean類型的數(shù)組 
 
    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
      View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_recyclerview, parent, false); 
      return new MyViewHolder(view); 
    } 
 
    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { 
      MyViewHolder myViewHolder = (MyViewHolder) holder; 
      myViewHolder.checkBox.setText(content.get(position)); 
       
      myViewHolder.checkBox.setOnCheckedChangeListener(null);//先設(shè)置一次CheckBox的選中監(jiān)聽器,傳入?yún)?shù)null 
      myViewHolder.checkBox.setChecked(flag[position]);//用數(shù)組中的值設(shè)置CheckBox的選中狀態(tài) 
       
      //再設(shè)置一次CheckBox的選中監(jiān)聽器,當(dāng)CheckBox的選中狀態(tài)發(fā)生改變時(shí),把改變后的狀態(tài)儲(chǔ)存在數(shù)組中 
      myViewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
        @Override 
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) { 
          flag[position] = b; 
        } 
      }); 
    } 
 
    @Override 
    public int getItemCount() { 
      content = new ArrayList<>(); 
      for (int i = 0; i < 100; i++) { 
        content.add("CheckBox" + i); 
      } 
      return content.size(); 
    } 
  } 
 
 
  private class MyViewHolder extends RecyclerView.ViewHolder { 
 
    private CheckBox checkBox; 
 
    public MyViewHolder(View itemView) { 
      super(itemView); 
      checkBox = (CheckBox) itemView.findViewById(R.id.id_check_box); 
    } 
  } 
}

比較這兩段代碼,我們會(huì)發(fā)現(xiàn),首先我們定義了一個(gè)長(zhǎng)度為100的數(shù)組,然后設(shè)置CheckBox的選中監(jiān)聽器,把null作為參數(shù)傳進(jìn)去,然后用數(shù)組中的值設(shè)置對(duì)應(yīng)CheckBox的選中狀態(tài),最后再一次設(shè)置CheckBox的選中監(jiān)聽器,把CheckBox的選中狀態(tài)儲(chǔ)存在數(shù)組中的相應(yīng)位置中。再次運(yùn)行,發(fā)現(xiàn)問(wèn)題已解決。

下面我們來(lái)討論一下,如果要在RecyclerView的外面再添加一個(gè)CheckBox,用外面的CheckBox來(lái)控制RecyclerView中的CheckBox的全選和取消全選,要如何實(shí)現(xiàn)呢?

其實(shí)也很簡(jiǎn)單,只要用這個(gè)CheckBox來(lái)控制之前所定義的數(shù)組的指就好了。

首先來(lái)修改一下activity_main,代碼如下:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
  xmlns:android="http://schemas.android.com/apk/res/android" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" 
  android:orientation="vertical"> 
   
  <LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="60dp" 
    android:gravity="center_vertical"> 
    <CheckBox 
      android:id="@+id/id_select_all" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="10dp" 
      android:text="SelectAll"/> 
  </LinearLayout> 
 
  <android.support.v7.widget.RecyclerView 
    android:id="@+id/id_recycler_view" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
 
  </android.support.v7.widget.RecyclerView> 
</LinearLayout>

我們?cè)赗ecyclerView的外面添加了一個(gè)CheckBox,用這個(gè)CheckBox來(lái)控制RecyclerView中的CheckBox的全選,接下來(lái)修改MainActivity:

public class MainActivity extends AppCompatActivity { 
 
  private CheckBox selectAll; 
  private RecyclerView recyclerView; 
  private MyAdapter myAdapter; 
  private boolean []flag;//把flag數(shù)組定義為全局變量 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
 
    selectAll = (CheckBox) findViewById(R.id.id_select_all); 
    recyclerView = (RecyclerView) findViewById(R.id.id_recycler_view); 
    flag = new boolean[100];//初始化flag 
    myAdapter = new MyAdapter(); 
    recyclerView.setLayoutManager(new LinearLayoutManager(this)); 
    recyclerView.setAdapter(myAdapter); 
 
    //設(shè)置外面CheckBox的選中監(jiān)聽器,把它的選中狀態(tài)賦值給其他的所有CheckBox,然后更新RecyclerView的Adapter 
    selectAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
      @Override 
      public void onCheckedChanged(CompoundButton compoundButton, boolean b) { 
        for (int i = 0; i < 100; i++) { 
          flag[i] = b; 
        } 
        myAdapter.notifyDataSetChanged(); 
      } 
    }); 
  } 
 
 
 
  private class MyAdapter extends RecyclerView.Adapter { 
 
    private List<String> content; 
//    private boolean[] flag = new boolean[100]; 
 
    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
      View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_recyclerview, parent, false); 
      return new MyViewHolder(view); 
    } 
 
    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { 
      MyViewHolder myViewHolder = (MyViewHolder) holder; 
      myViewHolder.checkBox.setText(content.get(position)); 
      myViewHolder.checkBox.setOnCheckedChangeListener(null); 
      myViewHolder.checkBox.setChecked(flag[position]); 
      myViewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
        @Override 
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) { 
          flag[position] = b; 
        } 
      }); 
 
 
    } 
 
    @Override 
    public int getItemCount() { 
      content = new ArrayList<>(); 
      for (int i = 0; i < 100; i++) { 
        content.add("CheckBox" + i); 
      } 
      return content.size(); 
    } 
  } 
 
 
  private class MyViewHolder extends RecyclerView.ViewHolder { 
 
    private CheckBox checkBox; 
 
    public MyViewHolder(View itemView) { 
      super(itemView); 
      checkBox = (CheckBox) itemView.findViewById(R.id.id_check_box); 
    } 
  } 
}

這里我們先把記錄CheckBox選中狀態(tài)的數(shù)組定義為全局變量,然后設(shè)置外面的CheckBox的監(jiān)聽器,把它的選中狀態(tài)賦值給其他的所有CheckBox,緊接著更新一下RecyclerView的Adapter就可以了

這里我們?cè)谟懻撘幌翿ecyclerView的另外一個(gè)問(wèn)題,就是當(dāng)要?jiǎng)h除某個(gè)子項(xiàng)的時(shí)候會(huì)出現(xiàn)刪除紊亂的情況,為了說(shuō)明這個(gè)問(wèn)題,我們

先來(lái)嘗試實(shí)踐一下,修改item_recyclerview:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
  xmlns:android="http://schemas.android.com/apk/res/android" 
  android:layout_width="match_parent" 
  android:layout_height="60dp" 
  android:gravity="center_vertical"> 
 
  <CheckBox 
    android:id="@+id/id_check_box" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_marginLeft="10dp" 
    android:text="CheckBox"/> 
   
  <Button 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentRight="true" 
    android:layout_marginRight="10dp" 
    android:text="delete"/> 
</RelativeLayout>

我們?cè)黾恿艘粋€(gè)Button,接下來(lái)設(shè)置這個(gè)Button,當(dāng)它被點(diǎn)擊的時(shí)候就刪除它所在位置的item,修改MainActivity如下,主要修改的是Adapter部分,其他部分的代碼就不貼了:

private class MyAdapter extends RecyclerView.Adapter { 
 
//    private List<String> content; 
//    private boolean[] flag = new boolean[100]; 
 
    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
      View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_recyclerview, parent, false); 
      return new MyViewHolder(view); 
    } 
 
    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { 
      final MyViewHolder myViewHolder = (MyViewHolder) holder; 
      myViewHolder.checkBox.setText(content.get(position)); 
      myViewHolder.checkBox.setOnCheckedChangeListener(null); 
      myViewHolder.checkBox.setChecked(flag[position]); 
      myViewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
        @Override 
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) { 
          flag[position] = b; 
        } 
      }); 
      //設(shè)置監(jiān)聽器,當(dāng)按鈕被點(diǎn)擊是,刪除它所在的item 
      myViewHolder.button.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View view) { 
          content.remove(position); 
          notifyItemRemoved(position); 
        } 
      }); 
 
 
    } 
 
    @Override 
    public int getItemCount() { 
//      content = new ArrayList<>(); 
//      for (int i = 0; i < 100; i++) { 
//        content.add("CheckBox" + i); 
//      } 
      return content.size(); 
    } 
  } 
 
 
  private class MyViewHolder extends RecyclerView.ViewHolder { 
 
    private CheckBox checkBox; 
    private Button button;//定義刪除按鈕 
 
    public MyViewHolder(View itemView) { 
      super(itemView); 
      checkBox = (CheckBox) itemView.findViewById(R.id.id_check_box); 
      button = (Button) itemView.findViewById(R.id.id_delete); 
    } 
  }

這是點(diǎn)擊Button,我們會(huì)發(fā)現(xiàn),問(wèn)題出現(xiàn)了,第一次可以正常刪除,第二次刪除的item卻是我們點(diǎn)擊的Button所在的下一個(gè)item,后面的刪除也會(huì)各種混亂,這是因?yàn)楹瘮?shù)里面的傳入的參數(shù)position,它是在進(jìn)行onBind操作時(shí)確定的,在刪除單項(xiàng)后,已經(jīng)出現(xiàn)在畫面里的項(xiàng)不會(huì)再有調(diào)用onBind機(jī)會(huì),這樣它保留的position一直是未進(jìn)行刪除操作前的postion值,對(duì)于尚未進(jìn)入畫面的單項(xiàng)來(lái)說(shuō),它會(huì)使用新的position值(好吧這段是抄的,其實(shí)我也不太懂啥意思),解決方法如下:

myViewHolder.button.setOnClickListener(new View.OnClickListener() { 
  @Override 
  public void onClick(View view) { 
    content.remove(position); 
    notifyItemRemoved(position); 
    notifyItemRangeChanged(position, content.size());//對(duì)于被刪掉的位置及其后range大小范圍內(nèi)的view進(jìn)行重新onBindViewHolder 
  } 
});

只要加一行代碼就好了,這行代碼的作用就是對(duì)于被刪掉的位置及其后range大小范圍內(nèi)的view進(jìn)行重新onBindViewHolder

感謝各位的閱讀!關(guān)于“RecyclerView中如何解決使用CheckBox出現(xiàn)勾選混亂的問(wèn)題”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI