ListView分類顯示

jopen 13年前發布 | 59K 次閱讀 Android Android開發 移動開發

今天和大家分享關于“listview的分類顯示”。現在有比較多的應用都有這個效果,比如在androidICS風格的“設置”選項里面就有這個效果,先看看效果:

ListView分類顯示

實現這個效果比較簡單,在填充listviewadapter的時候,我們都會通過繼承BaseAdapter來寫我們自己的adapterlistview里面的item是通過getView(int position, View convertView, ViewGroup parent) 實現。其實這邊有實現預加載,你只要在getview方法里面打印出log信息就會發現,listview剛開始顯示的時候getview不會返回所有的item,只是返回了前面幾個,當你往下拖拽的時候getview方法會加載剩下的item。這樣做的好處大家都知道,如果不這樣做估計早就出現了內存泄漏了。

好吧,我們回到主題,實現分類顯示只需要你把你顯示的數據打包好。Listview里面的item都是通過getView來生成,所以可以這樣,如果在getview里面生成item的時候,你返回兩次convertView不就可以了嗎?也就是說平時我們都是通過convertView來返回item,但是現在多了一個操作就是你根據自身打包的數據,如果當前返回的item是和之前顯示的item不屬于同一類就返回兩次convertView。這樣理解這個就好實現多了吧。注意的是像上面圖上“Label”、“類別1”、“類別2”是不可點擊的,只要實現BaseAdapter里面的isEnabled(int position)的方法就可以。

下面介紹的實現方式是運用了工廠模式實現,下面是草圖

ListView分類顯示

新建了一個ListItems接口:

/***
 * @author  huangsm
 * @date 2012-8-29
 * @email  huangsanm@gmail.com
 * @desc 接口
 */
public interface ListItems {

    public int getLayout();

    public boolean isClickable();

    public View getView(Context context, View convertView, LayoutInflater inflater);

}

其中LabelItem和ContentItem分別是顯示的“類別”和“內容”,他們分別實現ListItems接口。LabelItem實現:
/***
 * @author  huangsm
 * @date 2012-8-29
 * @email  huangsanm@gmail.com
 * @desc 標簽
 */
public class LabelItem implements ListItems {

    private String mLabel;
    public LabelItem(String label){
        mLabel = label;
    }

    @Override
    public int getLayout() {
        return R.layout.label_layout;
    }

    @Override
    public boolean isClickable() {
        return false;
    }

    @Override
    public View getView(Context context, View convertView, LayoutInflater inflater) {
        convertView = inflater.inflate(getLayout(), null);
        TextView title = (TextView) convertView;
        title.setText(mLabel);
        return convertView;
    }

}

ContentItem的實現:
/***
 * @author  huangsm
 * @date 2012-8-29
 * @email  huangsanm@gmail.com
 * @desc 內容
 */
public class ContentItem implements ListItems {

    private Item mItem;
    public ContentItem(Item item){
        mItem = item;
    }

    @Override
    public int getLayout() {
        return R.layout.content_layout;
    }

    @Override
    public boolean isClickable() {
        return true;
    }

    @Override
    public View getView(Context context, View convertView, LayoutInflater inflater) {
        convertView = inflater.inflate(getLayout(), null);
        ImageView iv = (ImageView) convertView.findViewById(R.id.content_image);
        iv.setImageResource(mItem.getResid());
        TextView tv = (TextView) convertView.findViewById(R.id.content_text);
        tv.setText(mItem.getTitle());
        return convertView;
    }
}

在activity中實現就相對來說比較麻煩一些。定義一個以ListItems為泛型的list集合mListItems,作為填充adapter的數據源,然后在adapter里面處理就很簡單:

class PartAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return mListItems.size();
        }

        @Override
        public Object getItem(int position) {
            return mListItems.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public boolean isEnabled(int position) {
            return mListItems.get(position).isClickable();
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            return mListItems.get(position).getView(mContext, convertView, mInflater);
        }
    }

接下來是初始化數據,需要注意的是LabelItem的初始化,不過這個動作可以在你打包數據的時候處理好,這樣在activity里面就不會那么麻煩了
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.part_listview);
        mListView = (ListView) findViewById(R.id.part_list);
        mContext = this;
        mInflater = LayoutInflater.from(mContext);
        mListItems =  new ArrayList
        ();

        //初始化數據
        LabelItem label1 = new LabelItem("Label");
        mListItems.add(label1);

        Item item1 = new Item();
        item1.setResid(R.drawable.ic_launcher);
        item1.setTitle(getString(R.string.app_name));
        ContentItem content1 = new ContentItem(item1);
        mListItems.add(content1);

        for (int i = 0; i < 3; i++) {
            LabelItem label = new LabelItem("類別" + (i + 1));
            mListItems.add(label);

            for (int j = 0; j < 3; j++) {
                Item item = new Item();
                item.setResid(R.drawable.ic_launcher_biz);
                item.setTitle("Content" + (i + 1));
                ContentItem content = new ContentItem(item);
                mListItems.add(content);
            }
        }

        //設置adapter
        PartAdapter adapter = new PartAdapter();
        mListView.setAdapter(adapter);
    }
   

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!