Android快速入门之使用AdapterView展示不同风格的列表

在面向对象的程序设计中接触过MVC模式,其实现原理:数据模型M(Model)负责存放数据,通过控制器C(Controller)将数据显示到相应的试图上(View)。在Android中也有类似的控件,它不像之前的控件那样拖拽到界面上,而是通过适配器将某些样式的数据添加到其上使用,这样的控件就是AdapterView。

常用的AdapterView控件

AdapterView组件作为一组非常重要的组件,主要以列表形式展示多个具有相同风格式的资源。常用的AdapterView有:AutoCompleteTextView(自动提示控件)、Spinner(下拉列表)、ListView(列表)、GriView(网格图)等…

AutoCompleteTextView控件:

AutoCompleteTextView类继承自EditText类,与EditText控件是一样的,当用户输入了与事先为该控件定义的一组字符串集中相关的信息时,才会出现下拉选项,供用户选择。

使用方式:

String[] contents = new String[]{"Student","Student1", "student2","AAA","ST1","dut","学生","User", "tv","Study","study","yyy"};
    
ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(this,
                //Android中自带的布局
                android.R.layout.simple_expandable_list_item_1,
                //这里用String数组表示,也可以来源于文件或数据库
                contents);
//输入2个字母就开始自动提示
autoTextView.setThreshold(2);

Spinner控件:

Spinner下拉列表,外观是一个一行的列表框,用户单击控件,下拉出选项列表供用户选择,Spinner每次只显示用户选中的元素。为Spinner加载数据的两种方式:

  • 方式1:在XML文件中先定义好要加载的数据资源,然后使用ArrayAdapter.createFromResource()把资源加载进来
  • 方式2:直接在Java代码中使用ArrayAdapter对象,把List中的数据资源加载到Spinner中,进行事件监听——onItemSelectedListener,传入一个实现了Spinner.onItemSelectedListener接口的匿名内部类对象,同时实现接口的onItemSelected方法,通过传入的position参数完成匹配

在res/values/values.xml文件中准备一个数据源:

<string-array name = "corse_array">
    <item>Web程序设计</item>
    <item>Android引用开发</item>
    <item>大数据处理</item>
    <item>操作系统</item>
    <item>计算机网络</item>
    <item>操作系统</item>
    <item>数据结构</item>
    <item>C语言</item>
</string-array>

在Activity中,声明初始化Spinner控件,绑定适配器,实现数据监听:

//声明Spinner控件
private Spinner spinner;
spinner = (Spinner) findViewById(R.id.spinner1);
//将可选内容与ArrayAdapter连接起来
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.courses, android.R.layout.simple_spinner_item);
//设置下拉列表的风格
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//将adapter 添加到spinner中
spinner.setAdapter(adapter);
spinner.setPrompt("请选择课程");
spinner.setSelection(0, true);
//添加事件Spinner事件监听
spinner.setOnItemSelectedListener(……)

案例:

界面代码:

<?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="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="联想输入" />

        <AutoCompleteTextView
            android:id="@+id/autoCompleteTextView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10" >

            <requestFocus />
        </AutoCompleteTextView>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="请选择你最喜欢的专业课" />

        <Spinner
            android:id="@+id/spinner1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>

</LinearLayout>

运行代码:

public class AdapterViewActivity extends Activity{

    private AutoCompleteTextView autoText;
    private Spinner spinner;
    String[] contents = new String[]{"Student","Student1", "student2","AAA","ST1","duts","学生","User", "tv","Study","study","yyy"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.adapter_view_layout);
        initView();
    }

    private void initView() {
        autoText = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1);
        ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, contents);

        //将adapter1 添加到AutoCompleteTextView中
        autoText.setAdapter(adapter1);
        autoText.setTextColor(Color.BLACK);
        //设置输入2个字符后开始提示
        autoText.setThreshold(2);

        spinner = (Spinner) findViewById(R.id.spinner1);
        //将可选内容与ArrayAdapter连接起来
        final ArrayAdapter<CharSequence> adapter2 = ArrayAdapter.createFromResource(this, R.array.corse_array, android.R.layout.simple_spinner_item);
        //设置下拉列表的风格
        adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        //将adapter2 添加到spinner中
        spinner.setAdapter(adapter2);

        spinner.setPrompt("请选择课程");
        spinner.setSelection(0, true);
        //添加事件Spinner事件监听
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String choice = getResources().getStringArray(R.array.corse_array)[position];
                Toast.makeText(AdapterViewActivity.this,
                        "你选的是"+choice, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

    }
}

在这里插入图片描述

在这里插入图片描述

ListView

ListView以列表形式展示内容,并根据数据的长度自适应显示。采用MVC模式将前端显示与后端数据分离,提供数
据的List或数组相当于Model,listView相当于视图,Adapter相当于Control,将数据适配到控件中。

使用步骤:

  • 1.声明并初始化ListView控件。可以让Activity直接继承ListActivity或在Activity布局中加入ListView控件,在Activity中进行声明或初始化。
  • 2.构造Adapter对象,通过Adapter获取要显示的数据
  • 3.绑定Adapter,通过setAdapter()将ListView和Adapter绑定。
  • 4.监听ListView,列表的响应事件。(单击或长按)

响应用户单机事件:
setOnItemClickListener()绑定AdapterView.OnItemClickListener接口,实现onItemClick方法,在其中进行单击事件处理list.setOnItemClickListener(new AdapterView.OnItemClickListener(){……}})

  • parent:发生单击动作的ListView对象
  • view:在ListView中被单击的View
  • position:点击项在ListView中的位置
  • id:点击项的行id

响应用户长按事件:
setOnItemLongClickListener()绑定AdapterView.OnItemLongClickListener接口,实现onItemLongClick方法,在其中进行长按事件处理:list.setOnLongItemClickListener(new AdapterView.OnItemLongClickListener(){……})

  • parent:发生单击动作的ListView对象
  • view:在ListView中被长按的View
  • position:被长按的列表项在ListView中的位置
  • id:被长按的列表项的行id

使用Adapter对象给ListView填充数据

Adapter适配器: Adapter对象在Adapter控件和数据源之间扮演桥梁的角色。提供访问数据源的入口,把从数据源拿到的数据项逐项加载到Adapter控件中。四种Adapter适配器:

  • ArrayAdapter:适用于列表项只含有文本信息的情况
  • SimpleAdapter:适用于每一个列表项中含有不同的子控件,比如图片+文本+按钮的
  • SimpleCursorAdapter:专门用来把一个Cursor中的数据映射到列表中,Cursor中的每一条数据映射为列表中的一项
  • 自定义Adapter:继承BaseAdapter,完全自定义数据适配方式,灵活性最强

ArrayAdapter

  • 数据源:数组 || List
  • 方法:ArrayAdapter adapter = new ArrayAdapter(this, R.layout.array_item_1, dataList);
    listView.setAdapter(adapter);
  • 属性说明:
    Context context:Context上下文对象
    int resource:对应列表项item的布局文件
    int textViewResourceId:列表item布局中对应的TextView的ID
    Object[] object:需要显示数据的集合
    List object:需要显示数据的集合

案例:

布局代码:

<?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">

    <ListView
        android:id="@+id/array_listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:dividerHeight="3dp" />

</LinearLayout>

运行代码:

public class ArrayAdapterListActivity extends Activity {

    private ListView listView;
    private List<String> dataList;
    private ArrayAdapter<String> adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.array_listview_layout);
        listView = (ListView) findViewById(R.id.array_listview);
        dataList = new ArrayList<String>();
        for (int i = 0; i <=50; i++) {
            dataList.add("ListView 测试文本,第"+(i+1)+"项");
        }
        adapter = new ArrayAdapter<String>(this, R.layout.array_adapter_item, dataList);
        listView.setAdapter(adapter);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(ArrayAdapterListActivity.this, "你点击的是"+(position+1)+"项",
                        Toast.LENGTH_SHORT).show();
            }
        });

        listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                final int myPosition = position;
                new AlertDialog.Builder(ArrayAdapterListActivity.this)
                        .setIcon(R.mipmap.ic_launcher)
                        .setTitle("警告")
                        .setMessage("你确定要删除吗?")
                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dataList.remove(myPosition);
                                adapter.notifyDataSetChanged();
                            }
                        })
                        .setNegativeButton("取消", null)
                        .create().show();

                return true;
            }
        });
    }
}

运行结果:
在这里插入图片描述
在这里插入图片描述

SimpleAdapter
使用SimpleAdapter丰富Item中的组件,
数据源:List<Map<String,Object>>,一个Map对应一个列表项,列表项布局在/res/layout/中定义
实质:使用Map的数据反复填充XML布局文件的各个控件的过程
缺点:附带事件的组件(Button、CheckBox)无法将数据映射在ListView上

案例:

布局代码:

<?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/simple_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginLeft="5dp"
        android:gravity="center_vertical"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/simple_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:textSize="20sp" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="right" >

        <CheckBox
            android:id="@+id/simple_cbx"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:focusable="false"
            android:focusableInTouchMode="false" />

        <Button
            android:id="@+id/simple_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:text="详情" />

    </LinearLayout>

</LinearLayout>

运行代码:

public class SimpleAdapterListActivity extends Activity {

    private List<HashMap<String, Object>> dataList;
    private SimpleAdapter adapter;
    private ListView simpleList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.array_listview_layout);

        dataList = new ArrayList<HashMap<String,Object>>();
        HashMap<String, Object> map;
        for (int i = 0; i < 50; i++) {
            map = new HashMap<String, Object>();
            map.put("img", R.mipmap.ic_launcher);
            map.put("text", "第"+(i+1)+"个测试文本");
            map.put("cbx", "");
            map.put("btn", "详情");
            dataList.add(map);
        }
        /*
         *参数说明:
         * Context context:Context上下文
         * List<? extends Map <String,?>>:数据集合,用于存储列表要显示的数据
         * intresource:item列表项布局文件的id
         * from:一个String数组,对应的Map上的每一个<key,value>的key值
         * to:int数组,resource自定义布局中各个控件的id,需要与from对应
         */
        adapter = new SimpleAdapter(this, dataList,R.layout.simple_list_item_layout,
                new String[]{"img","text","cbx","btn"},
                new int[]{R.id.simple_image,R.id.simple_text,R.id.simple_cbx,R.id.simple_btn});

        simpleList = (ListView) findViewById(R.id.array_listview);
        simpleList.setAdapter(adapter);

        simpleList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(SimpleAdapterListActivity.this, "你点击的是"+(position+1)+"项", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

运行结果:
在这里插入图片描述

自定义适配器:
BaseAdapter是一个抽象类,使用该类用户可以自定义适配器,需要重载四个方法。

使用自定义适配器可以丰富每一个Item的显示效果,如交替背景色、便捷的事件监听、自定义Item布局、交替显示背景色、为Button添加事件监听

自定义Adapter继承自BaseAdapter实现方法:

  • int getCount():获得项目item数量
  • Object getItem(int position):或等当前选项
  • long getItemId(int position):获得当前选项的id
  • abstract getView(int position,View converView,ViewGroup parent):返回列表对应的视图

案例:

布局文件-好友列表:friend_list_layout.xml

<?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="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:gravity="center_vertical|center_horizontal" >

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/tangseng" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="25sp"
            android:text="我的好友" />

    </LinearLayout>

    <ListView
        android:id="@+id/friendlist"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:dividerHeight="3dp" >
    </ListView>

</LinearLayout>

布局文件-列表设计:friend_list_item_layout.xml

<?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_friend"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:layout_weight="3"
        android:scaleType="centerInside"
        android:src="@mipmap/tangseng" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="6"
        android:layout_marginLeft="5dp"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/tv_friend_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:text="TextView" />

        <TextView
            android:id="@+id/tv_friend_msg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3"
        android:gravity="right" >

        <CheckBox
            android:id="@+id/cbx_friend"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:focusable="false"
            android:focusableInTouchMode="false"/>

        <Button
            android:id="@+id/btn_friend_detail"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:text="详情" />

    </LinearLayout>

</LinearLayout>

列表中有按钮、复选框等组件,通常这些组件会自动获取列表项的焦点,使得ListView列表项无法响应点击长按等事件。可通过设置android:focusable = “false”,以及android:focusableInTouchMode="false"来解决。

为了使Button、CheckBox等组件附带的事件能够映射到ListView上,或者丰富每一个Item的显示效果,我们可以在自定义适配器里来操作:

public class MyAdapter extends BaseAdapter{

    private Context context;//运行上下文
    private List<Map<String, Object>> listItems;//好友信息集合
    private LayoutInflater listContainer;//视图容器
    //用于存储CheckBox选中状态
    public  Map<Integer,Boolean> cbxFlag = null;


    public class ViewHolder{
        //自定义控件集合
        public ImageView image;
        public TextView name;
        public TextView msg;
        public CheckBox cbx;
        public Button detail;
    }

    public MyAdapter(Context context, List<Map<String, Object>> listItems) {
        this.context = context;
        listContainer = LayoutInflater.from(context);
        this.listItems = listItems;
        cbxFlag = new HashMap<Integer, Boolean>();
        init();

    }

    private void init() {
        for (int i = 0; i < listItems.size(); i++) {
            cbxFlag.put(i, false);
        }
    }

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

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

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

    public boolean hasChecked(int position) {
        return cbxFlag.get(position);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final int selectId = position;
        ViewHolder holder = null;

        if (convertView == null) {
            holder = new ViewHolder();
            //获取list_item布局文件的视图
            convertView = listContainer.inflate(R.layout.friend_list_item_layout, null);
            //获取控件对象
            holder.image = (ImageView) convertView.findViewById(R.id.iv_friend);
            holder.name = (TextView) convertView.findViewById(R.id.tv_friend_name);
            holder.msg = (TextView) convertView.findViewById(R.id.tv_friend_msg);
            holder.cbx = (CheckBox) convertView.findViewById(R.id.cbx_friend);
            holder.detail = (Button) convertView.findViewById(R.id.btn_friend_detail);
            //设置控件集到convertView
            convertView.setTag(holder);

        }else {
            holder = (ViewHolder) convertView.getTag();
        }

        //设置颜色交替
        if (position%2 ==0) {
            convertView.setBackgroundColor(Color.parseColor("#CAFFFF"));
        } else {
            convertView.setBackgroundColor(Color.parseColor("#B3FAFAFA"));
        }

        holder.image.setImageResource((Integer) listItems.get(position).get("image"));
        holder.name.setText((String) listItems.get(position).get("name"));
        holder.msg.setText((String) listItems.get(position).get("msg"));

        holder.detail.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new AlertDialog.Builder(context)
                        .setIcon((Integer) listItems.get(selectId).get("image"))
                        .setTitle((String) listItems.get(selectId).get("name"))
                        .setMessage((String) listItems.get(selectId).get("info"))
                        .setPositiveButton("确定", null)
                        .create()
                        .show();
            }
        });
        holder.cbx.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    cbxFlag.put(selectId, true);
                } else {
                    cbxFlag.put(selectId, false);
                }
            }
        });
        holder.cbx.setChecked(cbxFlag.get(selectId));
        return convertView;
    }
}

运行结果:


public class FriendListActivity extends Activity{

    private ListView listView;
    private MyAdapter listAdapter;
    private List<Map<String, Object>> listItems;

    private Integer[] imageIDs = {R.mipmap.lufei,R.mipmap.suolong,
            R.mipmap.wusuopu,R.mipmap.shanzhi,R.mipmap.namei,
            R.mipmap.qiaoba,R.mipmap.luobin,R.mipmap.fulanqi,R.mipmap.buluke,R.mipmap.xiangkesi,R.mipmap.baihuzi};

    private String[] friendNames = {"路飞", "索隆",
            "乌索普", "山治", "娜美", "乔巴","罗宾","弗兰奇","布鲁克","香克斯","白胡子"};

    private String[] msgs = {"【船长】蒙奇·D·路飞(蒙奇·D·路飞 )","【剑士】罗罗诺亚·索隆","【狙击手】乌索普",
            "【厨师】香吉士","【航海士】娜美","【船医】托尼托尼·乔巴 ","【考古学家】妮可·罗宾 ","【船匠】弗兰奇","【音乐家】布鲁克","【四皇】香克斯","【四皇】白胡子 "};

    private String[] infos = {"我是要当海贼王的男人"," 我总有一天要砍了那小子 ","我得了一上岛就会死的病…… ",
            " 啊,娜美桑~罗宾酱~ ","财宝?!","笨蛋,就算你夸我bai我也不du会高兴的~笨zhi蛋~笨蛋~ ","~_~"," 变态?是在叫我吗? ","这位美丽的小姐,可以让我欣赏一下你的内裤吗?","这次还请给我一个面子","做我的儿子吧"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.friend_list_layout);

        listView = (ListView) findViewById(R.id.friendlist);
        listItems = getFriendItems();
        listAdapter = new MyAdapter(this, listItems);
        listView.setAdapter(listAdapter);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (listAdapter.hasChecked(position)) {
                    Toast.makeText(FriendListActivity.this, "你想和" + listItems.get(position).get("name")
                                    + "冒险哇!", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(FriendListActivity.this, "你想成为海贼王吗?" , Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    private List<Map<String,Object>> getFriendItems() {
        List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
        for(int i = 0; i < friendNames.length; i++) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("image", imageIDs[i]);  //图片资源
            map.put("name", friendNames[i]);  //好友名称
            map.put("msg", msgs[i]); //最新消息
            map.put("info", infos[i]);
            listItems.add(map);
        }
        return listItems;
    }
}

运行结果:
在这里插入图片描述

ListView缓存原理及优化

  • 有多少行数据就需要绘制多少行Item,findViewById执行多次,极大地消耗了系统资源
  • 当启动Activity呈现第一屏ListView的时候,convertView为零、convertView相当于一个缓存,开始为0,当有条目变为不可见,它缓存了它的数据,后面再出来的条目只需要更新数据就可以了,这样大大节省了系统资料的开销。
  • 利用convertView实现缓存,条目不可见时,缓存数据,新的条目使用已经实例化的组件
    ViewHolder
    setTag(holder) 为每个View绑定一个存放控件的ViewHolder对象
    getTag() 避免了findViewById对控件的层层查询,而是快速定位到控件
    使用ConvertView实现缓存,改进程序

GridView

ListView适用列表是单列多行的形式,如果列表是多行多列的网状形式,则可以考虑使用GridView:
常用属性:

  • android:numColumns 设置列数,auto_fit将列数设置为自动
  • android:columnWidth 设置每列的宽度,也就是item的宽度
  • android:gravity 设置每个网络的比重位置,可选的值有:top、bottom、left、right、center…多个时使用|分开
  • android:stretchMode 缩放模式,设置列应该以何种形式填充可用空间
  • android:horizontalSpacing 网格之间列的默认水平距离
  • android:verticalSpacing 设置网格间的默认垂直距离

案例:

布局界面:grid_view_layout.xml

<?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="vertical">

    <GridView
        android:id="@+id/grid_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:numColumns="3"
        android:horizontalSpacing="10dp"
        android:verticalSpacing="10dp"/>
</LinearLayout>

每个模块的样式:grid_view_item_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/gridItemImage"
        android:layout_height="100dp"
        android:layout_width="wrap_content"
        android:layout_centerHorizontal="true">
    </ImageView>

    <TextView
        android:id="@+id/gridItemText"
        android:layout_width="wrap_content"
        android:layout_below="@+id/gridItemImage"
        android:layout_height="wrap_content"
        android:text="TextView01"
        android:layout_centerHorizontal="true">
    </TextView>

    <TextView
        android:id="@+id/gridItemPriceText"
        android:layout_width="wrap_content"
        android:layout_below="@+id/gridItemText"
        android:layout_height="wrap_content"
        android:text="TextView01"
        android:layout_centerHorizontal="true">
    </TextView>

</RelativeLayout>

运行代码:


public class GridViewActivity extends Activity {

    private GridView imageGridView;
    private int[] Card={R.mipmap.lufei, R.mipmap.suolong,
            R.mipmap.wusuopu, R.mipmap.suolong, R.mipmap.namei,
            R.mipmap.qiaoba,R.mipmap.luobin,R.mipmap.fulanqi,
            R.mipmap.baihuzi,R.mipmap.xiangkesi,R.mipmap.baihuzi};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.grid_view_layout);

        imageGridView = (GridView) findViewById(R.id.grid_view);
        final List<HashMap<String, Object>> mapsList = new ArrayList<HashMap<String, Object>>();
        for (int i = 0; i < 60; i++) {
            HashMap<String, Object> hashMap = new HashMap<String, Object>();
            hashMap.put("Image", Card[(int)(Math.random()*11)]);
            hashMap.put("text", "人物卡牌"+i);
            hashMap.put("pro", "售价"+(int)(Math.random()*10000000)+"¥");
            mapsList.add(hashMap);
        }
        SimpleAdapter adapter = new SimpleAdapter(getApplicationContext(),
                mapsList, R.layout.grid_view_item_layout, new String[] {
                "Image", "text","pro" }, new int[] {R.id.gridItemImage , R.id.gridItemText , R.id.gridItemPriceText});
        imageGridView.setAdapter(adapter);

        imageGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(GridViewActivity.this,"你选的是"+mapsList.get(position).get("text"),Toast.LENGTH_SHORT).show();
            }
        });
    }
}

运行结果:

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙源lll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值