android 一個頁面內 多個listview的實現


如果很平常的兩個listview組件豎直放在linearLayout布局中,結果是:

兩個listview 很獨立,中間似乎有個分割線,完全吧他們分離了,各自獨立滾動,如果上面的listview把整個屏幕占據了,那么下面的listview永遠滾不上來了,看不到了。

網上關於這個話題大約有兩種方法解決:

(1)有多少個listview就用多少個listview組件,然后放在一個LinearLayout布局里面,linearLayout布局在放入Scrollview中。

這樣做,必須先計算出每個listview被對應的adapter適配之后的實際高度,然后設置listview為這個高度。再放入scrollview中ok了。

(2)不管有多少個listview,都放在一個listview,用一個adapter適配,在listview組件對應的數據存儲結構list中,設置flag標志位,在adapter中再對不同的flag做不同的適配。

一開始,項目中使用的第一種方法,隨着項目的進行,發現第一種方法會在很多種情況下不適應,最嚴重的問題,就是第一種方法非常耗時,已經到了一種無可忍受的地步了。

一個很常見的例子,城市列表,有兩個list:熱門城市、全部城市

假如用第一種方法,先計算兩個listview在對應的adapter適配后的高度:

    public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            return;
        }
        int totalHeight = 0;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
    }

其實從這段代碼中,和上面這個需求,問題已經可以看出來了。

adapter有一個方法getView,這個方法是如果這個listview的某行將要在屏幕上顯示了,系統就會自動調用getview得到這個布局,然后顯示。

也就是每次被調用的次數,只是屏幕上能顯示的條數,最多也就是10條左右。

而一次計算高度就要對每一條調用getview,for循環里面:

View listItem = listAdapter.getView(i, null, listView);

是非常耗時的,尤其對於全部城市,幾百條,3~4秒肯定是要的。所以面對這個需求,第一種方法是不可行。

除了耗時,第一種方法,維護性也不好。就比如,一個頁面中,listview的數據是不定的,是動態計算得到的。用第一種方法分散到多個listview,對於一些事件監聽,不好操作。

下面講解下第二種方法的具體實現

拿上面城市列表具體

分兩塊:

1、數據dataList

2、adapter

1、datalist填充:

主要以一個flag標記,對於城市列表共有兩種布局:

一個是頭信息

 

一個是具體的城市

代碼:

        cityList.clear();
        Map<String, Object> map1 = new HashMap<String, Object>();
        map1.put("city", new City(0, "熱門城市", '#'));
        cityList.add(map1);

        List<City> cities = getHotCity();

        for (City city : cities) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("is_selected", false);
            map.put("city", city);
            cityList.add(map);
        }

        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("city", new City(0, "全部城市", '$'));
        cityList.add(map2);

        index++;
        cities = getAllCity();

        for (City city : cities) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("is_selected", false);
            map.put("city", city);
            cityList.add(map);
        }


哦~這個好像沒用到flag標記,直接判斷city的name了~~~

2、adapter適配:

@Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        City city = (City) listData.get(position).get("city");
        String nameString = city.getName();
        if (nameString.compareTo("熱門城市") == 0) {
            convertView = mInflater.inflate(headResource, null);
            ((TextView) convertView.findViewById(R.id.label)).setText("熱門城市");
            return convertView;
        }
        if (nameString.compareTo("全部城市") == 0) {
            convertView = mInflater.inflate(headResource, null);
            ((TextView) convertView.findViewById(R.id.label)).setText("全部城市");
            return convertView;
        }

        convertView = mInflater.inflate(listResource, null);
        ((TextView) convertView.findViewById(R.id.label)).setText(nameString);
        ImageView isSelectedImageView = (ImageView) convertView.findViewById(R.id.is_selected);

//        boolean isSelected = (Boolean) listData.get(position).get("is_selected");

        int whichIsSelected = (Integer) listData.get(getCount() - 1).get("which_is_selected");

        if (city.getId() == whichIsSelected)
            isSelectedImageView.setBackgroundResource(R.drawable.is_selected_yes);
        else
            isSelectedImageView.setBackgroundResource(R.drawable.is_selected_no);

        return convertView;
    }

對於各行的點擊操作也可以根據flag統一處理。維護起來非常方便。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM