Android-RadioGroup+ScrollView 實現聯動標籤效果

開篇

新的項目中有一個很長的資料提交和資料查看頁面,爲了方便查看,上方加了 RadioGroup 分類標籤,可以快速滑動的相應位置。
實現的效果和下面差不多,其實,蘑菇街的商品詳情也是這樣實現的。

實現思路

  1. RadioGroup + ScrollView 控件搭配實現

  2. RadioGroup 的 OnCheckedChangeListener 監聽事件中拿到 RadioButton 對應的內容 Y 座標,通過 scrollTo(0,Y)或者 smoothScrollTo(0,Y) 控制 ScrollView 的滑動。

  3. ScrollView 的 onScrollChanged 方法中通過 Y 值判斷範圍,來確定選中哪個 RadioButton 。

始料未及的小問題 & 解決方法

上面的步驟是不是看起來是不是超級簡單,然而事實證明,too young to naive !

1.OnCheckedChangeListener 和 onScrollChanged 會互相觸發吶吶吶,下滑時還好,上滑的時候,標籤直接會連續選中到第一個。

2.被上滑時不受控制的 ScrollView 折磨得幾乎要瘋的我,發現是 RadioGroup 的鍋,這貨的 onCheckedChanged 一次觸發會調用多次。

OnCheckedChangeListener 和 onScrollChanged 會互相觸發

實話說,這是非常正常的表現,畢竟是需要相互聯動的兩個控件,就是聯動的時機有誤,需要我們來手動控制一下。

現狀:
點擊 RadioGroup ,ScrollView 滑動到固定位置,上滑不會有問題,下滑時由於判斷條件不同,ScrollView 滑動到固定位置時會觸發 RadioGroup 的監聽事件。

需求:
RadioGroup 觸發的時候,,ScrollView 中對 RadioGroup 就不要觸發。
ScrollView 聯動觸發 RadioGroup 的時候,RadioGroup 對 ScrollView 的聯動不要觸發。

簡單來說,就是雙向同時聯動改成雙向不同時聯動。

修改方法:

1.添加兩個變量:

boolean isScrollFlag = false ;
boolean isRadioFlag = false;

2.RadioGroup 的 onCheckedChanged 中的判斷:

//攔截 scrollView 中的聯動觸發
if(isScrollFlag){
    isScrollFlag = isRadioFlag = false;
    return;
}

3.ScrollView 的 onScrollChanged 中的判斷:

//攔截 radioGroup 選中的聯動觸發
if(isRadioFlag ){
    Log.d(TAG, "onScrollChanged: 攔截");
    isRadioFlag = isScrollFlag = false;

    return;
}

RadioGroup 調用check()方法 onCheckedChanged 一次觸發多次調用的問題。

多次觸發是 check() 中多次調用了 setCheckedId() 方法,而 setCheckedId() 裏面又有多次調用 onCheckedChanged 。以上這句話的具體細節請自行查看相關源碼。這裏放上我的解決方法:

在 RadioGroup 的 onCheckedChanged 方法里加入如下代碼:

mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
     @Override
     public void onCheckedChanged(RadioGroup group, int checkedId) {

         //防止onCheckedChanged 被調用多次
         View viewById = mRadioGroup.findViewById(checkedId);
         if (!viewById.isPressed()){
             Log.w(TAG, "onCheckedChanged: 阻止");
             return;
         }

         //...
       }
});

最後

本來想按照實現步驟一步步附上上對應的代碼的,後來想想也不是很有必要,還是思路說清楚比較重要,最後附上完整代碼鏈接。

完整代碼在這裏

發現一個待改進的問題,就是 scrollView 調用 smoothScrollTo(0,Y) 方法其實也是會多次觸發 onScrollChanged()。雖然最後實現了效果,但是總是有點不對的,這個問題後面會再優化。

技術粗淺,如果有不對的地方,還請留言告知。


歡迎關注博主的微信公衆號,快快加入哦,期待與你一起成長!
發佈了125 篇原創文章 · 獲贊 367 · 訪問量 124萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章