Android—ListView 的使用以及简单优化

Listview是在做东西的时候最常用的控件 基本什么都会用到它 我之前一直是模范别的APP里面的listview 咋写 没有仔细的想过里面到底是怎么的规范 需要什么 所以就专门找资料研究了一下 一个完整的Listview应该怎么实现 然后做了一些简单的优化 所以这篇博文有两个部分 一个是listview的实现 另外一部分就是listview的优化
好了 先来看第一部分
一.ListView的实现
1.新建一个项目 在main_activity中加入listview的控件
宽度高度没有什么特别强调的 再给他一个id就可以了 如果你需要什么效果还可以再加下面是我main_activity的代码

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

    <TextView
        android:text="LISTVIEW"
        android:gravity="center"
        android:textSize="50dp"
        android:layout_width="fill_parent"
        android:layout_height="70dp"
        android:layout_weight="0.04" />
    <ListView
        android:id="@+id/Listview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
    </ListView>

</LinearLayout>

这段代码实现的效果就是这样
其中蓝色框中的就是listview 我们之后的数据是要适配到这里的
这里写图片描述
listview的每一行都是有不同的内容 所以我们需要先考虑好我们给这里面存放的是什么内容
2.适配器中的数据类
这里我希望listview中可以显示一张图片和一段文字
以颜色为例
首先要准备好一些颜色的图片,分别对应每一种颜色 然后让对应的颜色图片和文字显示在一起
首先我们定义一个实体类Coloro 作为传入适配器的适配类型
(数据无法直接传递给listview 我们需要借助适配器来完成 建议使用arrayadapter 他可以通过泛型来指定要适配的数据类型)

定义实体类里面只有两个信息 name表示颜色的名字 imageid表示颜色对应图片的资源id实体类代码如下

public class Coloro{
    private String  name;
    private int imageid;
    public Coloro(String name,int imageid){
        this.name = name;
        this.imageid = imageid;
    }
    public String getName(){
        return  name;
    }
    public int getImageid() {
        return  imageid;
    }

}

3.给listview的子项指定一个自定义的布局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:orientation="horizontal"
    android:background="@drawable/listview"

    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/image"
        android:layout_width="40dp"
        android:layout_height="40dp" />
  <TextView
    android:id="@+id/name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:textSize="40dp"
    android:layout_marginLeft="20dp"/>

</LinearLayout>

4.自定义适配器
接下来要创建一个自定义适配器 这个适配器继承自ArrarAdapter 并将泛型指定为Coloro类 所以我们新建类 代码如下所示

public class ColorAdapter extends ArrayAdapter<Coloro> {
    private int resourceId;
    public ColorAdapter(Context context ,int textviewResourceID,List<Coloro> objects){
        super(context,textviewResourceID,objects);
        resourceId  =textviewResourceID;

    }
    public View getView(int position ,View convertView,ViewGroup parent){
       Coloro coloro = getItem(position);
        View view  = LayoutInflater.from(getContext()).inflate(resourceId, null);
        ImageView Colorimage  = (ImageView)view.findViewById(R.id.image);
        TextView Colorname = (TextView)view.findViewById(R.id.name);
        Colorimage.setImageResource(coloro.getImageid());
        Colorname.setText(coloro.getName());
       return  view;

    }

}

这个适配器重写了父类的一组构造方法 将上下文 listview的子项布局的id和数据都传递进来
重写了一个很重要的getView()方法,这个方法在子项被滚动到可视界面的时侯也就是在屏幕中的时候会被调用 最后将布局返回 我们的适配器也就完成了 。
下来就只有MainActivity中的代码要修改了

public class MainActivity extends AppCompatActivity {
public List<Coloro> coloroList = new ArrayList<Coloro>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initColor();//初始化图片资源信息 
        ColorAdapter adapter = new ColorAdapter(MainActivity.this,R.layout.layout,coloroList);
        ListView listview  = (ListView)findViewById(R.id.Listview);
        listview.setAdapter(adapter);
        //下面是给每一项添加了监听事件 
        listview.setOnItemClickListener(new AdapterView.OnItemClickListener(){
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Coloro co =coloroList.get(position);
                Toast.makeText(MainActivity.this,co.getName(),Toast.LENGTH_LONG).show();
            }
        });

    }
    private void initColor(){
        Coloro  red = new Coloro("绿色",R.mipmap.lv);
        Coloro  bai = new Coloro("白色",R.mipmap.bai);
        Coloro  dahong = new Coloro("红色",R.mipmap.dahong);
        Coloro  dian = new Coloro("靛蓝",R.mipmap.dian);
        Coloro  hei = new Coloro("黑色",R.mipmap.hei);
        Coloro  huang = new Coloro("黄色",R.mipmap.huang);
        Coloro  hui = new Coloro("灰色",R.mipmap.hui);
        Coloro  ju = new Coloro("橘色",R.mipmap.ju);
        Coloro  lan = new Coloro("蓝色",R.mipmap.lan);
        Coloro  tianlan = new Coloro("天蓝",R.mipmap.tianlan);
        Coloro  yanghong = new Coloro("洋红",R.mipmap.yanghong);
        Coloro  zi = new Coloro("紫色",R.mipmap.zi);
        for(int i=0;i<3;i++) {
            coloroList.add(red);
            coloroList.add(bai);
            coloroList.add(dahong);
            coloroList.add(dian);
            coloroList.add(hei);
            coloroList.add(huang);
            coloroList.add(hui);
            coloroList.add(ju);
            coloroList.add(lan);
            coloroList.add(tianlan);
            coloroList.add(yanghong);
            coloroList.add(zi);
        }

    }
}

这样就这几步 listview需要适配器 适配器需要数据类型 数据要显示在子项所以要有一个布局界面
一个ListView就完成了 先来看一下效果
这里写图片描述
完成是完成了 但是我们还可以提高他的运行效率 因为在适配器的getview()方法里每一次都要重新加载一遍布局 所以我们可以利用View 传进来的参数来优化代码
所以我就放上getview();的代码

public View getView(int position ,View convertView,ViewGroup parent){

        Coloro coloro = getItem(position);
        View view ;
        ViewHolder viewHolder;
        if(convertView==null){
            view =LayoutInflater.from(getContext()).inflate(resourceId, null);
            viewHolder  =new ViewHolder();
            viewHolder.image = (ImageView)view.findViewById(R.id.image);
            viewHolder.name =(TextView)view.findViewById(R.id.name);
            view.setTag(viewHolder);

        }else{
            view = convertView;
            viewHolder =(ViewHolder) view.getTag();

        }
        viewHolder.image.setImageResource(coloro.getImageid());
        viewHolder.name.setText(coloro.getName());
        return  view;
        //2.优化第一步
     //   Coloro coloro = getItem(position);
//        View view ;
//        if(convertView==null){
//            view =LayoutInflater.from(getContext()).inflate(resourceId, null);
//        }else{
//            view = convertView;
//        }
//        ImageView Colorimage  = (ImageView)view.findViewById(R.id.image);
//        TextView Colorname = (TextView)view.findViewById(R.id.name);
//        Colorimage.setImageResource(coloro.getImageid());
//        Colorname.setText(coloro.getName());
//        return  view
// 1.未优化的
      // Coloro coloro = getItem(position);
//        View view  = LayoutInflater.from(getContext()).inflate(resourceId, null);
//        ImageView Colorimage  = (ImageView)view.findViewById(R.id.image);
//        TextView Colorname = (TextView)view.findViewById(R.id.name);
//        Colorimage.setImageResource(coloro.getImageid());
//        Colorname.setText(coloro.getName());
//        return  view;

    }
    class ViewHolder{
        ImageView image;
        TextView name;
    }
}

优化了两次现在已经是比较好的了
第二次优化做到了不用重复加载布局
第三次也就是最终版的优化做到了不用在每次都获取一次实例
当第一次获取实例后 控件都已经缓存放在了我们自己写的一个内部类ViewHolder中 这样通过判断就不用每次都重新获取控件实例

以上——————————-完!!

最近状态好烂好烂的 看不到希望的时候才要坚持 加油加油。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值