zoukankan      html  css  js  c++  java
  • Android学习(五)分组ListView(Sectioned Headers)

    问题

    当你想展示一个分类的数据列表比如依据时间、日期、产品累不或者销售价格序等
    解决方案
    我们可以使用“Sectioned headers“(这里不知道应该具体叫啥,故未翻译,可以理解为分割头,或者分组) ListView.这里我们自定义一个Adapter,使用不同类型的视图和其对应的Adapter来实现,这里我们必须关注2个方法:

    int getItemViewType(int position)
    为特定的视图返回getView(int, View, ViewGroup)即将构建的视图类型
    int getViewTypeCount()
    返回getView(int, View, ViewGroup)即将构建的视图的视图类型个数.

    下面是我们的实现代码:

    我们这里构建我们的Android工程,并添加一个GroupListVeiwActivity(Project的包名:com.jeriffe.app)

    首先我们需要定义我们的Layout文件:

    注:这里我们有3个Layout文件,分别是activity的Layout,sectionsHeader的Layout,及listView Item的Layout,以下只是演示,故Layout代码文件格式并未应用Theme及Style

    activity_group_list_veiw.xml(activity的Layout)

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <ListView
            android:id="@+id/add_journalentry_menuitem"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    
        <ListView
            android:id="@+id/list_journal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    
    </RelativeLayout>

    group_list_header.xml(sectionsHeader的Layout)

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/list_header_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/gray"
        android:paddingBottom="2dip"
        android:paddingLeft="5dip"
        android:paddingTop="2dip"
        android:textColor="@color/black" />
    
    

    (listView Item的Layout)

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/list_item_title"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:paddingBottom="10dip"
        android:paddingLeft="15dip"
        android:paddingTop="10dip" />
    

    接下来便是我们需要自定义的一个Adapter

    我们添加一个新的类:SeparatedListAdapter 继承自BaseAdapter适配器类,以下代码已经很直白,关键代码已经添加了注释,最重要的4个方法如下粗体所示

    package com.jeriffe.app;
    
    import java.util.LinkedHashMap;
    import java.util.Map;
    import android.content.Context;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Adapter;
    import android.widget.ArrayAdapter;
    import android.widget.BaseAdapter;
    
    public class SeparatedListAdapter extends BaseAdapter {
        public final Map<String, Adapter> sections = new LinkedHashMap<String, Adapter>();
        public final ArrayAdapter<String> headers;
        public final static int TYPE_SECTION_HEADER = 0;
    
        public SeparatedListAdapter(Context context) {
            headers = new ArrayAdapter<String>(context, R.layout.group_list_header);
        }
    
        public void addSection(String section, Adapter adapter) {
            this.headers.add(section);
            this.sections.put(section, adapter);
        }
    
        public Object getItem(int position) {
            for (Object section : this.sections.keySet()) {
                Adapter adapter = sections.get(section);
                int size = adapter.getCount() + 1;
                // check if position inside this section
                if (position == 0)
                    return section;
                if (position < size)
                    return adapter.getItem(position - 1);
                // otherwise jump into next section
                position -= size;
            }
            return null;
        }
    
        public int getCount() {
            // total together all sections, plus one for each section header
            int total = 0;
            for (Adapter adapter : this.sections.values())
                total += adapter.getCount() + 1;
            return total;
        }
    
        public boolean areAllItemsSelectable() {
            return false;
        }
    
        @Override
        public int getViewTypeCount() {
            // assume that headers count as one, then total all sections
            int total = 1;
            for (Adapter adapter : this.sections.values())
                total += adapter.getViewTypeCount();
            return total;
        }
    
        @Override
        public int getItemViewType(int position) {
            int type = 1;
            for (Object section : this.sections.keySet()) {
                Adapter adapter = sections.get(section);
                int size = adapter.getCount() + 1;
                // check if position inside this section
                if (position == 0)
                    return TYPE_SECTION_HEADER;
                if (position < size)
                    return type + adapter.getItemViewType(position - 1);
    
                // otherwise jump into next section
                position -= size;
                type += adapter.getViewTypeCount();
            }
            return -1;
        }
    
        @Override
        public boolean isEnabled(int position) {
            // 设置header enabled is false,通俗点就是点击header无效
            return (getItemViewType(position) != TYPE_SECTION_HEADER);
        }
    
        public View getView(int position, View convertView, ViewGroup parent) {
            int sectionnum = 0;
            for (Object section : this.sections.keySet()) {
                Adapter adapter = sections.get(section);
                int size = adapter.getCount() + 1;
    
                // check if position inside this section
                if (position == 0)
                    return headers.getView(sectionnum, convertView, parent);
                if (position < size)
                    return adapter.getView(position - 1, convertView, parent);
    
                // otherwise jump into next section
                position -= size;
                sectionnum++;
            }
            return null;
        }
    
        public long getItemId(int position) {
            return position;
        }
    }

    接下来便是我们的Activity类

    GroupListVeiwActivity类比较简单就是构建UI,并初始化Adapter来展示数据:

    package com.jeriffe.app;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    import android.widget.Toast;
    
    public class GroupListVeiwActivity extends Activity {
        // SectionHeaders
        private final static String[] days = new String[]{"2012-04-06",
                "2012-05-08", "2012-09-28", "2012-10-16", "2012-12-03"};
    
        // Section Contents
        private final static String[][] notes = new String[][]{
                {"阴转多云", "12℃/25℃", "穿衣指数:天气较热,建议着短裙、短裤、短套装。"},
                {"晴天", "22℃/34℃", "穿衣指数:天气大热,建议着短裙、短裤、注意预防中暑。"},
                {"小雨", "8℃/16℃", "穿衣指数:天气微冷,建议着秋季服装。"},
                {"中雨", "5℃/12℃", "穿衣指数:天气较冷,建议着秋季服装。"},
                {"小雪", "-1℃/6℃", "穿衣指数:天气寒冷,建议冬季服装。"}};
    
        // ListView Contents
        private ListView journalListView;
        // Adapter for ListView Contents
        private SeparatedListAdapter adapter;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_group_list_veiw);
    
            setupViews();
        }
    
        private void setupViews() {
    
            // Create and Initialize the ListView Adapter
            initializeAdapter();
    
            // Get a reference to the ListView holder
            journalListView = (ListView) this.findViewById(R.id.list_journal);
            journalListView.setOnItemClickListener(new OnItemClickListener() {
                public void onItemClick(AdapterView<?> parent, View view,
                        int position, long duration) {
                    String item = (String) adapter.getItem(position);
                    Toast.makeText(getApplicationContext(), item,
                            Toast.LENGTH_SHORT).show();
                }
            });
            // Set the adapter on the ListView holder
            journalListView.setAdapter(adapter);
        }
    
        private void initializeAdapter() {
            adapter = new SeparatedListAdapter(this);
    
            for (int index = 0; index < days.length; index++) {
                ArrayAdapter<String> listadapter = new ArrayAdapter<String>(this,
                        R.layout.group_list_item, notes[index]);
                adapter.addSection(days[index], listadapter);
            }
        }
    }

    好了到此已经相关代码已经Over,粘贴代码到自己构建Project,编译即可运行(当然String.xml及Color.xml还是要自己来添加的),下面来一张运行效果图:

    注:这里,本人运行环境是Android4.1.2

    image_thumb3

    以下文章探讨了其他的实现方式:

    1.用2个Adapter数据源:一个是Header数据源,一个是包含Item的数据源,界面数据全部来自Item数据源

    ,自定义Adapter继承自ArrayAdapter<String>,其主要核心代码是getView方法,详细可见博客原文。

    原文地址:http://www.cnblogs.com/qianxudetianxia/archive/2011/06/07/2074326.html

    注:下面的代码,group_list_item_text再给TextVeiw设置文本的时候要留意:Header及Item的ID是一致的,详细可以见原文,

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        //根据标签类型加载不通的布局模板
        if(listTag.contains(getItem(position))){
            //如果是标签项
            view = LayoutInflater.from(getContext()).inflate(R.layout.group_list_item_tag, null);
        }else{              
            //否则就是数据项了      
            view = LayoutInflater.from(getContext()).inflate(R.layout.group_list_item, null);
        }
        //显示名称
        TextView textView = (TextView) view.findViewById(R.id.group_list_item_text);
        textView.setText(getItem(position));
        //返回重写的view
        return view;
    }

    2.使用第三方插件,详细我也为研究,感兴趣的同志见:http://code.google.com/p/android-section-list/

    3.利用GONE Visibility,具体的实现可见这里:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=157934&extra=page%3D1&page=1

  • 相关阅读:
    在线心理测试脚本
    素数
    设置层叠效果
    年轻,无权享受...
    Unity3D之预设
    Json解析类
    php 正则表达式
    php 字符串处理
    php 基础语法
    SQL 函数
  • 原文地址:https://www.cnblogs.com/jeriffe/p/2757186.html
Copyright © 2011-2022 走看看