<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Android中RecyclerView+CheckBox的使用

          共 5980字,需瀏覽 12分鐘

           ·

          2021-11-08 11:40

          1、需求前言


          需要做一個(gè)勾選列表,提供不同的選項(xiàng)給用戶進(jìn)行勾選,并將結(jié)果保存在本地

          效果圖:


          2、實(shí)現(xiàn)思路


          采用Recycleview+Checkbox的方式 每個(gè)recycleview的每個(gè)item就是一個(gè)選項(xiàng),可以勾選,再次點(diǎn)擊取消勾選


          進(jìn)入勾選頁(yè)面時(shí),先讀取本地的設(shè)置,每個(gè)item設(shè)置是否已經(jīng)勾選


          難點(diǎn):recycleview的holder復(fù)用導(dǎo)致勾選混亂


          3、實(shí)現(xiàn)


          3.1 布局


          這里采用極簡(jiǎn)的方式快速實(shí)現(xiàn),所以布局非常簡(jiǎn)單,xml文件就不貼出來(lái)了
          這是item的布局,我使用了RelativeLayout,但其實(shí)可以使用LinearLayout
          左邊一個(gè)TextView 右邊一個(gè)CheckBox



          然后activity的布局就一個(gè)RecyclerView就可以

                   android:id="@+id/recyclerView_product_type"        android:layout_width="match_parent"        android:layout_height="match_parent"        tools:listitem="@layout/item_preference_product"        />


          3.2 Activity和Adapter的代碼實(shí)現(xiàn)


          我盡量注釋清楚,以下代碼是從項(xiàng)目中摘取出來(lái)的代碼,保留靈魂,舍棄整體。不能直接使用,但是如果讀懂了代碼的話,是可以很輕松的自己實(shí)現(xiàn)的。


          3.2.1 Adapter

          public class ProdectTypeAdapter extends DefaultAdapter {
          /**Set是用于保存已經(jīng)勾選的商品列表 * SharedPreferences能保存的列表只能是Set類型 * 所以這里采用Set來(lái)記錄勾選的商品列表 * SharedPreferences需要保存更復(fù)雜的bean對(duì)象的話可以轉(zhuǎn)換為JSON的字符串來(lái)保存 * */ //mProductPreferences之前已經(jīng)勾選的商品列表 在打開(kāi)界面時(shí)我們需要默認(rèn)勾選上 Set mProductPreferences;
          //ischoose 商品名稱以及對(duì)應(yīng)是否已經(jīng)勾選 Map ischoose = new HashMap<>();
          public ProdectTypeAdapter(List infos, Set mProductPreferences) { super(infos); this.mProductPreferences = mProductPreferences; }

          @Override public BaseHolder getHolder(View v, int viewType) { //這里根據(jù)所有的商品名稱和mProductPreferences作比較 //如果mProductPreferences存在則已勾選 否則不勾選 比較結(jié)果存入ischoose for (ProductTypeBean productTypeBean : getInfos()) { if (mProductPreferences.contains(productTypeBean.getProductTypeId())) { ischoose.put(productTypeBean.getProductTypeId(), true); } else { ischoose.put(productTypeBean.getProductTypeId(), false); }
          } ProdectTypeHolder holder = new ProdectTypeHolder(v, ischoose);
          //?。?!這句代碼非常關(guān)鍵 這里禁止holder的復(fù)用 直接杜絕了勾選混淆的可能性 //代價(jià)是如果選項(xiàng)特別巨大,會(huì)導(dǎo)致recycleview滑動(dòng)卡頓 但一般是不會(huì)有太多選項(xiàng)的 holder.setIsRecyclable(false);
          return holder; }
          @Override public int getLayoutId(int viewType) { return R.layout.item_preference_product; }//holder中填充每個(gè)item的數(shù)據(jù) class ProdectTypeHolder extends BaseHolder {
          @BindView(R.id.tv_product_name) TextView productName;//顯示每個(gè)商品名稱 @BindView(R.id.checkbox_product) CheckBox checkbox;//每個(gè)商品的選擇框 Map ischoose;

          public ProdectTypeHolder(View itemView, Map ischoose) { super(itemView); this.ischoose = ischoose; } //setData填充每個(gè)item的數(shù)據(jù) @Override public void setData(ProductTypeBean data, int position) { //顯示商品名稱 productName.setText(data.getVatRatio() + "%" + itemView.getContext().getString(data.getDescRes())); //剛開(kāi)始啟動(dòng) 勾選框是否默認(rèn)已勾選(根據(jù)ischoose) checkbox.setChecked(ischoose.get(data.getProductTypeId())); //我們不需要勾選框的監(jiān)聽(tīng) 所以設(shè)置不可點(diǎn)擊 checkbox.setClickable(false); } }}


          3.2.2 Activity

          public class ProductTypePreferenceSettingActivity extends BaseActivity {    //SharedPreferences存儲(chǔ)對(duì)象 用于將選擇結(jié)果保存到本地內(nèi)存    @Inject    SharedPreferences mSharedPreferences;
          @BindView(R.id.recyclerView_product_type) RecyclerView recyclerView;
          ProdectTypeAdapter mAdapter;//recycleview適配器 LinearLayoutManager mManager;//recycleview的布局管理器 用于單獨(dú)獲取item中的checkbox對(duì)象 List allProductType;//所有的可以勾選的商品列表
          /**Set是用于保存已經(jīng)勾選的商品列表 * SharedPreferences能保存的列表只能是Set類型 * 所以這里采用Set來(lái)記錄勾選的商品列表 * SharedPreferences需要保存更復(fù)雜的bean對(duì)象的話可以轉(zhuǎn)換為JSON的字符串來(lái)保存 * */ Set mProductPreferences = new HashSet<>();//之前已經(jīng)勾選了并保存在本地的商品
          @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_product_type_preference_setting); //所有的可以勾選的商品列表 allProductType = Constants.allProductTypeList; //讀取本地保存的已經(jīng)勾選的商品 mProductPreferences = mSharedPreferences.getStringSet(Constants.PRODUCTPREFERENCES, mProductPreferences); //實(shí)例化適配器 mAdapter = new ProdectTypeAdapter(allProductType, mProductPreferences); //實(shí)例化布局管理器 這里是線性布局 mManager = new LinearLayoutManager(this); //設(shè)置布局 recyclerView.setLayoutManager(mManager); //設(shè)置適配器 recyclerView.setAdapter(mAdapter); //設(shè)置recycleview中每個(gè)item的監(jiān)聽(tīng) mAdapter.setOnItemClickListener(new DefaultAdapter.OnRecyclerViewItemClickListener() { @Override public void onItemClick(View view, int viewType, Object data, int position) { //根據(jù)點(diǎn)擊的位置獲取到item的布局文件 View itemview = mManager.findViewByPosition(position); LinearLayout layout = (LinearLayout) itemview; //獲取到每個(gè)item中的checkbox對(duì)象 CheckBox checkbox = (CheckBox) layout.findViewById(R.id.checkbox_product); //根據(jù)點(diǎn)擊的位置讀取到商品對(duì)象 ProductTypeBean product = allProductType.get(position); //進(jìn)一步讀取到商品的id String productId = product.getProductTypeId();
          //如果這個(gè)商品已經(jīng)勾選了 設(shè)置checkbox為未勾選 從mProductPreferences移除 //反之 將checkbox設(shè)置為已勾選 加入mProductPreferences if (mProductPreferences.contains(productId)) { mProductPreferences.remove(productId); checkbox.setChecked(false); } else { mProductPreferences.add(productId); checkbox.setChecked(true); }
          }
          }); }
          @Override protected void onDestroy() { //退出時(shí) 進(jìn)行保存寫(xiě)入 mSharedPreferences.edit().putStringSet(Constants.PRODUCTPREFERENCES, mProductPreferences).commit(); setResult(RESULT_OK); super.onDestroy(); }}


          到這里我們就基本上完成了多選列表,再次強(qiáng)調(diào),以上代碼不可直接使用,但是注釋寫(xiě)的非常清楚,可以看懂了,根據(jù)自己的業(yè)務(wù)需求來(lái)實(shí)現(xiàn)。


          這只是最簡(jiǎn)單的多選框,如果要加入一鍵全選 ,一鍵取消 ,單選,反選等等,可以自己擴(kuò)展。


          4、難點(diǎn)總結(jié)


          難點(diǎn)1:holder的復(fù)用導(dǎo)致勾選混亂 比如我勾了第1個(gè)商品,但是第11個(gè)也會(huì)勾上,這個(gè)可以靠單獨(dú)的數(shù)據(jù)源來(lái)解決,比如代碼中的ischoose(會(huì)有其他問(wèn)題,比如勾選了,滑動(dòng)導(dǎo)致 holder刷新,勾選狀態(tài)又沒(méi)了),當(dāng)然也可以簡(jiǎn)單除暴holder.setIsRecyclable(false);禁止holder的復(fù)用。


          難點(diǎn)2:獲取單個(gè)item中的單個(gè)view,這里的view是checkbox。通過(guò)布局管理器來(lái)獲取到view對(duì)象,跟著代碼里來(lái)做就可以


          ?。?!難點(diǎn)3:一定要將checkbox的初始狀態(tài)傳入adapter,否者雖然取消了復(fù)用,但是由于recycleview會(huì)自動(dòng)回收,導(dǎo)致選擇了第一個(gè),下滑在上滑回來(lái)時(shí),勾選狀態(tài)卻是“未勾選”。
          這里的checkbox就是根據(jù)mProductPreferences來(lái)確定的。


          個(gè)人猜想:recycleview在回收了holder再次啟用時(shí),會(huì)根據(jù)最新的數(shù)據(jù)自動(dòng)確定狀態(tài)。

          瀏覽 122
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲资源在线观看 | caopen人人 | 久久福利一区 | 福利一区二区视频 | 国内精品视频97 |