(轉)Android ListView和Item焦點問題

原帖:https://www.jianshu.com/p/6fe14f9b7726

在Android 開發中,當我們使用ListView時,比如item是一個RadioButton或者CheckBox等控件時,此時會出現焦點問題,比如我們選擇了一個RadioButton,當我們滑動ListView後,我們返回我們剛纔選中的RadioButton時,會發現我們選擇的狀態沒有被選中。這是怎麼回事?下面來介紹一下怎麼解決這個問題。
當出現以上問題時,是因爲ListView和Item的焦點問題沒有處理好而出現的

如何解決

以下介紹三種方法:

  1. 將ListView中的Item佈局中的子控件focusable屬性設置爲false

  2. 在getView方法中設置button.setFocusable(false)

  3. 設置item的根佈局的屬性android:descendantFocusability="blocksDescendant"
    android:descendantFocusability屬性共有三個取值,分別爲:

  • beforeDescendants:viewgroup會優先其子類控件而獲取到焦點
  • afterDescendants:viewgroup 只有當其子類控件不需要獲取焦點時才獲取焦點
  • blocksDescendants:viewgroup 會覆蓋子類控件而直接獲得焦點

我們可以發現,其實這三種方法都是爲了讓Button等控件不能獲取焦點,從而使得item可以響應點擊事件。

第三種方法使用起來相對方便,因爲它是將item佈局中的其他所有控件都設置爲不能獲取焦點。下面我貼上我使用第三種方法的主要代碼。

  • 佈局文件如下(item的佈局文件,以RadioButton解釋)
<?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="fill_parent"
    android:orientation="horizontal"
    android:descendantFocusability="blocksDescendants" > 

     <RadioButton
            android:id="@+id/radio_bt"
            android:layout_width="match_parent"
            android:layout_height="78px" 
            android:clickable="false"            
            android:button="@null"
            android:drawableRight="@drawable/remember_xml"
            android:textColor="@android:color/white" 
            />              
</LinearLayout>
  • 下面是在MainActivity中使用的主要代碼
@Override
    public void showListDialog(final String[] str, final FLAG_CHOICE flag, int selected) {
     final ListBaseAdapter adapter = new ListBaseAdapter(this, str);
     //主要是在Adapter加入這個方法是爲了讓ListView初始化或者響應用戶的選中行爲
     adapter.setItemChoice(selected);
     mListView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                // TODO Auto-generated method stub
             //讓Listview更新選中Item狀態
                adapter.setItemChoice(arg2); 

            }

        });
     mListView.setAdapter(adapter);
        }
  • 下面是Adapter主要代碼
 @Override
 public View getView(int arg0, View view, ViewGroup arg2) {
        // TODO Auto-generated method stub
        ViewHolder holder = null;
        if (view == null) {
            holder = new ViewHolder();
            view = LayoutInflater.from(mContext).inflate(R.layout.layout_adapter, arg2, false);
            holder.mRadioButton = (RadioButton) view.findViewById(R.id.radio_bt);
            holder.mRadioButton.setPadding(20, 0, 20, 0);
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }
        if (mIndex == arg0) {
            holder.mRadioButton.setSelected(true);
        } else {
            holder.mRadioButton.setSelected(false);
        }
        holder.mRadioButton.setText(mData[arg0]);
        return view;
    }
    
    public void setItemChoice(int index) {
        mIndex = index;
        notifyDataSetChanged();
    }

以上是我在項目中使用的主要代碼,親測有效,到此結束,關於其他兩種解決方案,還請各自驗證。

 



作者:ssdlx
鏈接:https://www.jianshu.com/p/6fe14f9b7726
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章