1. 程式人生 > >適應所有巢狀自動滾動bug。ListView巢狀在ScrollView中、Lv載入完資料之後Sv自動滾動

適應所有巢狀自動滾動bug。ListView巢狀在ScrollView中、Lv載入完資料之後Sv自動滾動

Notice

Notice
最近使用RecyclerView巢狀RecyclerView也出現了類似的問題,最後使用下面的方法三也解決了。

問題

第一次進入介面 請求資料成功的時候 , ListView 自動 滾動到底部了。
因為ScrollView預設會展示佈局內最後一個有焦點的控制元件
怎麼樣 才可以 讓ListView 載入完成之後,不自動跑到底部
想要的 效果 和 實際效果 貼上圖片
這裡寫圖片描述
這裡寫圖片描述

第一種方法:

(這種有時網速快或慢,使用者容易看到滑動的動畫體驗不好。), PS:不推薦

setAdapter之後 ,加一個延遲 讓ScrollView  滾動到 0
,0的座標 lvMerchants.setAdapter(mMerchantAdapter); new Handler().postDelayed(new Runnable() { @Override public void run() { mScrollView.smoothScrollTo(0, 0); } }, 300); }

第二個方法: PS:推薦使用這種,原理一看便知

在佈局程式碼的最上方增加這段程式碼:

<LinearLayout
        android:layout_width="0px"
        android:layout_height="0px"
        android:focusable="true"
        android:focusableInTouchMode="true" />

這段程式碼的意思就是優先獲取焦點,這樣ListView就無法得到焦點,就不會滾動到底部了

第三個方法:

手動計算LIstview的高度 ,確定:程式碼有點繁多。 PS : 不推薦

public static void setListViewHeightBasedOnChildren(ListView listView) {
        // 獲取ListView對應的Adapter
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            return;
        }

        int totalHeight = 0;
        int len = listAdapter.getCount();
        for (int i = 0; i < len; i++) { // listAdapter.getCount()返回資料項的數目
            View listItem = listAdapter.getView(i, null, listView);
            if (null != listItem) {
                listItem.measure(0, 0); // 計運算元項View 的寬高
                totalHeight += listItem.getMeasuredHeight(); // 統計所有子項的總高度
            }
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight
                + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        // listView.getDividerHeight()獲取子項間分隔符佔用的高度
        // params.height最後得到整個ListView完整顯示需要的高度
        listView.setLayoutParams(params);
    }

第四個方法:沒有實踐,暫不做評論

感覺跟第二個方法沒差,一個是在佈局檔案中一個是在程式碼中。
這裡寫圖片描述
在oncreat裡面新增這幾句,viewgroup是你的activity的父佈局。

第五個方法:

scrollview預設會展示佈局內最後一個有焦點的控制元件,解決方法:重寫scrollview的computeScrollDeltaToGetChildRectOnScreen方法,返回0,使其選擇第一個控制元件
或者使其餘控制元件失去焦點setFocusable(false) (這就跟二四 方法差不多了。)

好了,寫了怎麼多的方法了。具體使用哪個根據個人愛好和實際需求了。