Android之ListView的使用

来源:互联网 发布:玉和颜去黑头 知乎 编辑:程序博客网 时间:2024/06/06 20:25

前言

在实现列表的技术里,Android有一个稍微古老的ListView,之所以古老是现在有一个叫 RecyclerView 的方法更加实用和强大,以致于现在基本上很少用 ListView 。但是这是题外话,本章内容虽然讲的是 ListView 但是它也有值得我们学的价值,正所谓技多不压身嘛~

什么是 ListView?

由于手机屏幕有限,我们不可能把所有想要展示的内容全部放在一个界面,这就需要一个列表,列表里每个Item里面在放置内容,听起来是会相比 Button TextView这些控件要难得多,而事实上操作起来确实也比较复杂,接下来由我细细讲解

首先我们建立一个 ListView 的 activity_main.xml 文件,表明我们要开始做列表了

<?xml version="1.0" encoding="utf-8"?><LinearLayout 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/list_item"        android:layout_width="match_parent"        android:layout_height="match_parent">    </ListView></LinearLayout>

这第一步有了做列表的决心,我们就应该思考列表的每一项应该怎么展示,那么我们又应该写一个Item的布局文件,这里我以学生列表为例,所以命名为 student.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/imageview"        android:src="@drawable/iconfont_user"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <TextView        android:id="@+id/textview"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></LinearLayout>

从代码可以看出每个Item 由一张图片和文字组成,水平放置,很常规的一种布局,一看就懂的。

之后呢?写好了布局,我们就应该思考怎么把 Item 加到 ListView 里面去,并且每个 Item 都要赋予内容吧,先想想怎么装内容吧,没有内容的 Item 装进去了也是空白列表,就像建房子总要住活人吧 ,装了内容的 Item 才是有生命力的活人,那么问题来了怎么装?读者不妨可以思考一下~~~~

本文例子一直是以学生为对象(ps:因为博主也是学生哈)。所以内容我们就装学生吧,那我们就建一个学生类,如下

public class Student {    private  String name;    private  int image;    public Student(String name,int image){        this.name = name;        this.image = image;    }    //问题1:这里为什么要get方法而不用set方法    public int getImage() {        return image;    }    public String getName() {        return name;    }}

看了代码里面的问题1大家可以思考一下,稍后会解答,好了,有了学生这个对象,我们是不是得对号入座呢。把对应的学生放在对应的座位上去,但是这些是小学生,是需要老师指导去坐哪个座位的,这个老师就是一个中间者,即每个 Item 与 对象之间需要一个适配器 Adapter,接下来我们就创建一个 StudentAdapter 记得要继承自 ArrayAdapter
StudentAdapter.java

package com.example.hanlertest.listview2;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.ImageView;import android.widget.TextView;import java.util.List;public class StudentAdapter extends ArrayAdapter<Student> {    private  int resourceId;//接收布局文件Id    public StudentAdapter(Context context, int textViewResourceId, List<Student> objects) {        super(context, textViewResourceId, objects);        resourceId = textViewResourceId;//将传过来的布局文件赋给resoureceId    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        View view;        //将布局文件连接到View        view = LayoutInflater.from(getContext()).inflate(resourceId,null);        //获取当前的Item        Student stu  = getItem(position);        ViewHolder  viewHolder = new ViewHolder();        //获取对应的实例        viewHolder.imageView = (ImageView) view.findViewById(R.id.imageview);        viewHolder.textView = (TextView) view.findViewById(R.id.textview);        viewHolder.imageView.setImageResource(stu.getImage());        viewHolder.textView.setText(stu.getName());        return view;    }    //问题2:为什么要建这个内部类    private class ViewHolder {        ImageView imageView;        TextView textView;    }}

同样这里留了个问题2,大家可以思考看看,代码中的 getView 方法可能新手朋友会陌生,我们来看看API

public View getView(int position, View convertView,ViewGroup parent)Get a View that displays the data at the specified position in the data set. You can either create a View manually or inflate it from an XML layout file. When the View is inflated, the parent View (GridView, ListView...) will apply default layout parameters unless you use LayoutInflater.inflate(int, android.view.ViewGroup, boolean) to specify a root view and to prevent attachment to the root. 

简单的说,这个方法就是展示(display)Item 数据的方法,在手动滑动列表或者当列表出现在手机屏幕中时就会调用此方法,所以我们在这个方法中编写代码赋予数据。
顺便回答下问题1,这就是为什么我们要写get 方法的原因,因为在这里赋予数据的时候我们需要获取到 Item 的对象数据。
最后我们就在 MainActivity里面将所有的 Item 写进列表
MainActivity.java

package com.example.hanlertest.listview2;import android.app.Activity;import android.content.Context;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.ListView;import java.net.FileNameMap;import java.util.ArrayList;import java.util.List;public class MainActivity extends Activity {    public List<Student> stuList = new ArrayList<>();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initStudent();//初始化数据         StudentAdapter stuadapter = new StudentAdapter(MainActivity.this,R.layout.student,stuList);//实例化Adapter并调用构造方法传入布局ID,本例中没有对stuList操作         ListView listview = (ListView) findViewById(R.id.list_item);        listview.setAdapter(stuadapter);        listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            //点击Item事件            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                Student stu = stuList.get(position); Toast.makeText(MainActivity.this,stu.getName(),Toast.LENGTH_SHORT).show();            }        });    }    private void initStudent() {      for (int i = 0 ; i < 10 ; i++){          Student stu = new Student("学生"+i,R.drawable.iconfont_user);          stuList.add(stu);      }    }}

下面贴上结果图
这里写图片描述
还记得问题2吗?为什么在Adapter要建一个 ViewHolder内部类,事实上 ListView 之所以难用,还因为它有很多细节有待优化,因为在 getView()方法里面每次都要将布局重新加载一边,就这么一拉上拉下就浪费了很多资源,那么怎么优化呢,在 getView()参数列表里还有一个 convertView 参数,这个参数的作用就是将之前已经加载好的东西进行缓存,具体代码看以下修改:

package com.example.administrator.listview;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.ImageView;import android.widget.TextView;import java.util.List;public class FruitAdapter extends ArrayAdapter<Fruit> {    private  int resourceId;    public FruitAdapter(Context context, int textViewResourceId,List<Fruit> objects) {        super(context, textViewResourceId,objects);        resourceId = textViewResourceId;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        View view;        Fruit fruit = getItem(position);        ViewHolder viewHolder = new ViewHolder();        if(convertView == null){        //第一次加载的时候            view = LayoutInflater.from(getContext()).inflate(resourceId, null);            viewHolder.fruitImage = (ImageView) view.findViewById(R.id.fruit_image);            viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name);            view.setTag(viewHolder);        }else{            view = convertView;            viewHolder = (ViewHolder) view.getTag();        }        viewHolder.fruitImage.setImageResource(fruit.getImageId());       viewHolder.fruitName.setText(fruit.getName());        return view;    }    private class ViewHolder {        ImageView fruitImage;        TextView fruitName;    }}

好了,关于ListView的介绍大概如此,看了博主的文章,有没有收获那么一点点呢?或者是有什么指点建议之类的欢迎指出,共勉thanks!!!

0 0