19-10-16 Android中ListView的使用及优化

ListView控件的使用

虽然现在手机屏幕变得越来越大,但是毕竟屏幕空间还是有限的,能够一次性显示在屏幕上的内容并不多,但是在大多数的软件中有很多布局风格都是一样的条目,这就可以使用ListView控件实现。


ListView是以列表的形式展示数据的具体内容,使用的时候在布局文件中添加ListView控件,一般宽和高都设置为匹配父容器。
<ListView
	android:id="@+id/lv"
	android:layout_width="match_parent"
	android:layout_height="match_parent"> 
</ListView>

数据适配器

在使用ListView控件时需要进行数据适配,在进行数据适配时会用到适配器,安卓系统中提供了多种适配器(Adapter),BaseAdapter、SimpleAdapter、ArrayAdapter等,下面我用BaseAdapter适配器。

BaseAdapter是一个抽象类,使用BaseAdapter时需要重写以下四个方法

方法功能
public int getCount()返回Item条目的总数
public Object getItem(int position)根据position得到某个Item的对
public long getItemId(int position)根据position得到某个Item的id
public View getView(int position, View convertView, ViewGrouppar ent)得到相应position对应Item视图,position 是当前Item的位置,convertView用于复用旧视图,parent用于加载xml布局

代码如下

//1 获取listview控件
listView = findViewById(R.id.lv);
//2 给listview设置适配器
MyBaseAdapter adapter = new MyBaseAdapter();
listView.setAdapter(adapter);
//创建适配器类 继承自BaseAdapter 重写四个方法
class MyBaseAdapter extends BaseAdapter{
        @Override
        public int getCount() {
        	return 50;
        }
        @Override
        public Object getItem(int position) {
        	return null;
        }
        @Override
        public long getItemId(int position) {
        	return 0;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
        //直接创建了一个textview对象
        	TextView textView = new TextView(MainActivity.this);
        	textView.setText("我爱学安卓!");
        	textView.setTextColor(Color.RED);
        	textView.setTextSize(20);
        	//返回textview
        	return textView;
        }
}

ListView的定制界面

上面我们实现了一个简单的ListView程序,但是实际开发中一般不会这么用,ListView界面内容要丰富得多。
下面对ListView的界面进行定制


首先我们创建一个ListView对应的item布局

<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"     
	android:layout_width="match_parent"     
	android:layout_height="match_parent"     
	android:gravity="center_vertical">
	
	<ImageView
	    android:background="@drawable/qq"     
	    android:id="@+id/item_image"
	    android:layout_width="48dp"     
		android:layout_height="48dp" />
	     
	<TextView
		android:id="@+id/item_tv"
		android:textSize="18sp"
		android:text="我是ListView的item布局"         
		android:layout_width="wrap_content"         
		android:layout_height="wrap_content" />
</LinearLayout>

在Java代码中给ListView设置适配器

//创建两个数组用来存放数据
//准备数据  注意 name和icon要对应起来
private String[] names = {"京东商城","QQ","QQ斗地主","新浪微博","天猫","UC浏览器","微信"};
private int[] icons = {R.drawable.jd,R.drawable.qq,R.drawable.dz,R.drawable.xl,R.drawable.tm,R.drawable.uc,R.dr awable.wx};
//创建适配器类 继承自BaseAdapter 重写四个方法
class MyBaseAdapter extends BaseAdapter {
		@Override
		public int getCount() {
			return names.length;
        }
        @Override
        public Object getItem(int position) {
        	return names[position];
        }
        @Override
        public long getItemId(int position) {
        	return position;
       	}
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
	        //如何把item布局转换成view显示给用
	        //将list_item布局抓换成view对象‐‐‐‐也叫做打气筒服务
	        //获取上下文对象的方法,如果是当前类可以写this;如果不是需要写全称,比如  MainActivity.this;如果不确定类名,getApplicationContext()
	        //infate方法的参数 1上下文对象 2布局的资源文件 3权限 用不上写null
	        View view = View.inflate(Main2Activity.this, R.layout.lits_item, null);
	        ImageView imageView = view.findViewById(R.id.item_image);
	        TextView textView = view.findViewById(R.id.item_tv);
	        imageView.setBackgroundResource(icons[position]);
	        textView.setText(names[position]);
	        return view;
       }
}

结果如下图:
在这里插入图片描述

ListView控件的优化

1、简单来说,有多少个条目就会执行多少次MyBaseAdapter类中的getView()方法,这样的话如果展示的数据有成千上万条,getView()方法也会被执行成千上万次,相应的也会创建成千上万个条目对象,这样不仅会增加内存的消耗,而且快速滚动ListView时,很容易造成内存溢出而导致程序崩溃。
2、每次执行getView方法都会获取view,这样也属于一种耗时操作

优化“我爱学安卓”案例

原理:在Listview第一次展示时,系统会根据屏幕的高度和item的高度创建一定数量的条目 对象。当滑动listview时,顶部的item会滑出屏幕,同时释放它所使用的convertview,底部新的数据会进入屏幕进行展示,这时新的数据会使用顶部滑出item的converview,从而使整 个listview展示数据的过程使用固定数量的convertview,避免了每次创建新的item而消耗大量内存。

public View getView(int position, View convertView, ViewGroup parent){
	TextView textView;
	if (convertView == null) {
		textView = new TextView(MainActivity.this);
	} else {
		textView = (TextView) convertView;
	}
	textView.setText("我超级爱学安卓!");
	textView.setTextColor(Color.RED);
	textView.setTextSize(20);
	return textView;
}

优化“应用程序列表案例”

原因:因为每一次加载新的item数据时都会进行控件寻找,产生耗时操作。
原理:使用一个类叫做 ViewHolder。 将要加载的子view放在ViewHolder类中,当第一次创 建convertview时将这些控件找出,第二次复用convertview时可直接通过convertview中的一 个getTag()方法获得这些控件。

public View getView(int position, View convertView, ViewGroup  parent) {
	ViewHolder viewHolder;
	View view;
	if (convertView==null){
		view = View.inflate(getApplicationContext(),  R.layout.lits_item, null);
		viewHolder=new ViewHolder();
		viewHolder.imageView=view.findViewById(R.id.item_image);
		viewHolder.textView=view.findViewById(R.id.item_tv);
		view.setTag(viewHolder);
	}else {
		view=convertView;
		viewHolder= (ViewHolder) view.getTag();
	}
	viewHolder.textView.setText(names[position]);
	viewHolder.imageView.setBackgroundResource(icons[position]);
	return view;
}
class ViewHolder{
	ImageView imageView;
	TextView textView;
}

但是ListView只能纵向滚动不能实现横向滚动,所以从Android5.0开始,谷歌公司推出了一个增强版的ListView,新控件RecylerView,它不仅拥有与ListView相同的效果,而且对ListView中的不足之处进行了优化。
RecylerView的用法见下一条博客

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值