zoukankan      html  css  js  c++  java
  • Android中ListView的使用

    1、主要概念

    ListView用于将大数据集以列表的形式展示。

    ListView可以看成一个容器,它有如下继承链:

    View <- ViewGroup <- AdapterView <- AbsListView <- ListView

    可见 ListView继承自AdapterView, 而AdapterView的作用就是为ListView提供数据。
    主要的API:

    listView.setAdapter(adapter实例)
    

    我们通常用的Adapter有如下几个:BaseAdapter, CursorAdapter, ArrayAdapter, SimpleAdapter.它们有如下的继承关系:

    Adapter <- ListAdapter <- BaseAdapter

    SimpleAdapterCursorAdapterArrayAdapter都是BaseAdapter的子类。

    2、使用方法
    • Activity布局文件中加入一个ListView组件
    <ListView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:entries="@array/listItems"></ListView>
    

    这里entries用于指定一个数组来渲染ListView,它定义在strings.xml中,内容如下:

    <resources>
        <string-array name="listItems">
            <item>orange</item>
            <item>apple</item>
            <item>banana</item>
            <item>pear</item>
            <item>watermelon</item>
            <item>lemon</item>
            <item>peach</item>
            <item>strawberry</item>
        </string-array>
    </resources>
    

    到这里,运行项目已经可以看到列表项了。但这种方式只是静态的给ListView添加数据,有很大的局限性。基本不用。下面通过给ListView设置Adapter提供数据。

    • 删除上面的entries属性, 修改Activity的内容
    public class ArrayAdapterActivity extends AppCompatActivity {
    
        private String[] items = new String[]{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"};
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_array_adapter);
            ListView lv = findViewById(R.id.array_adapter_list_view);
            //可以这里为ListView设置了一个Adapter
            //并且指定了一个array_adapter_list_item.xml的布局文件,因此要新建一个这样的布局文件
            //这个布局文件限制了一个数据项的显示形式,即一行数据如何展示
            //该布局文件的根标签为TextView
            //然后用上面的定义的字符串数组填充每一个TextView
            lv.setAdapter(new ArrayAdapter<>(this, R.layout.array_adapter_list_item, items));
        }
    }
    

    这样,运行程序ListView显示的便是数组中定义的值了。

    • 不同的Adapter使用方式基本一致

    下面是SimpleAdapter的使用:

    lv.setAdapter(new SimpleAdapter(context, data, resource, from, to));
    

    1.context: 当前上下文

    2.data: List<Map<String, ?>>类型的数据集

    3.resource:单个数据项的布局文件

    5.from:data中map的各个key

    6.to: 将key对应的值映射到数据项布局文件的某个组件
    看个例子:

    public class SimpleAdapterActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_simple_adapter);
            ListView lv = findViewById(R.id.simple_adapter_list_view);
            Map<String, Object> student1 = new HashMap<>();
            student1.put("username", "jack");
            student1.put("gender", "male");
            student1.put("age", 33);
            Map<String, Object> student2 = new HashMap<>();
            student2.put("username", "nacy");
            student2.put("gender", "female");
            student2.put("age", 13);
            List<Map<String, Object>> students = new ArrayList<>();
            students.add(student1);
            students.add(student2);
            //from对应map的key
            String[] from = new String[]{"username", "gender", "age"};
            //to对应单行数据项布局文件中组件的id
            int[] to = new int[]{R.id.simple_adapter_username, R.id.simple_adapter_gender, R.id.simple_adapter_age};
            lv.setAdapter(new SimpleAdapter(this, students, R.layout.simple_adapter_list_item, from, to));
        }
    }
    

    单行数据项布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
    
        <TextView
            android:id="@+id/simple_adapter_username"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"></TextView>
    
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="3"
            android:orientation="vertical">
    
            <TextView
                android:id="@+id/simple_adapter_gender"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"></TextView>
    
            <TextView
                android:id="@+id/simple_adapter_age"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"></TextView>
        </LinearLayout>
    
    </LinearLayout>
    

    3、BaseAdapter的使用

    BaseAdapter作为一个抽象类,比前几种Adapter使用起来更灵活。

    下面是一个例子:

    创建一个类继承BaseAdapter

    public class MyBaseAdapter extends BaseAdapter {
    
        //根据当前上下文将一个布局文件加载到内存,实例化为对象的一个类
        private LayoutInflater layoutInflater;
    
        public MyBaseAdapter(Context context) {
            layoutInflater = LayoutInflater.from(context);
        }
    
        //决定数据项的个数
        @Override
        public int getCount() {
            return 20;
        }
    
        //指定位置的数据项
        @Override
        public Object getItem(int position) {
            return null;
        }
    
        //指定位置数据项的索引
        @Override
        public long getItemId(int position) {
            return 0;
        }
    
        //容纳当前数据项布局文件的一个类
        private class ViewHolder {
            public ImageView header;
            public TextView username;
        }
    
        //手机在滚动屏幕时,超出屏幕之外的ViewItem要被移除
        //如果有10000个ViewItem,那么getView方法就要调用10000次,加载布局文件10000次,然后创建ViewItem,这是相当耗资源的
        //为了提高性能,就需要对移除的ViewItem进行复用,每次滚动屏幕移除的ViewItem就是convertView
        //因此每次调用方法时,都要对convertView判空,如果为空才去加载布局文件,创建新的View,否则进行复用。
        //这里的ViewHolder相当于一个容器,承载了一个ViewItem中所有的组件,避免了每次都要findViewById
        //一次findViewById之后,通过setTag方法将其设置到convertView中,下次就不用再查找了
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                convertView = layoutInflater.inflate(R.layout.base_adapter_list_item, null);
                holder = new ViewHolder();
                holder.header = convertView.findViewById(R.id.iv_header);
                holder.username = convertView.findViewById(R.id.tv_username);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            holder.header.setImageResource(R.drawable.ic_launcher_foreground);
            holder.username.setText("这是第" + position + "项");
            return convertView;
        }
    }
    

    数据项布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
    
        <ImageView
            android:id="@+id/iv_header"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#008080"></ImageView>
    
        <TextView
            android:id="@+id/tv_username"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"></TextView>
    </LinearLayout>
    

    Activity文件

    public class BaseAdapterActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_base_adapter);
            ListView lv = findViewById(R.id.base_adapter_list_view);
            lv.setAdapter(new MyBaseAdapter(this));
            lv.setOnItemClickListener(new ListView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Toast.makeText(BaseAdapterActivity.this, "点击" + position, Toast.LENGTH_SHORT).show();
                }
            });
    
            lv.setOnItemLongClickListener(new ListView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                    Toast.makeText(BaseAdapterActivity.this, "长按" + position, Toast.LENGTH_SHORT).show();
                    return true;
                }
            });
        }
    }
    
  • 相关阅读:
    RJ-45与RJ-48的区别
    PCB设计铜铂厚度、线宽和电流关系
    PCB设计铜铂厚度、线宽和电流关系
    WiFi天线对PCB布局布线和结构的要求详解
    WiFi模块选型参考
    掩码是什么意思?
    计算机音频基础-PCM简介
    使用CSS2对页面中的文字添加彩色边框
    SQL Plus
    A Famous Music Composer
  • 原文地址:https://www.cnblogs.com/wotoufahaiduo/p/11649513.html
Copyright © 2011-2022 走看看