ListView控件性能提升

       ListView控件是 Android 中最常用的控件之一,几乎所有的应用程序都会用到它。比如淘宝app中,有很多的商家,每个商家还有很多的商品,但是手机屏幕很小,不可能一下子将所有的商家和商品都展示出来,所以就需要使用 ListView来实现。这里我就直接上代码了,具体的代码解释会在程序中注释,在页面的最下面有下载该demo的链接地址。


效果图:




activity_main.xml中的代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:divider="#556B2F"
        android:dividerHeight="10dp" >
    </ListView>

</LinearLayout>

代码解释:

设置分隔线颜色:android:divider="#556B2F"

设置分割线高度:android:dividerHeight="10dp"


Person.java类中的部分代码:

public class Person {
	
	private int imgId ;//头像
	private String name ;//姓名
	private String status ;//状态信息:在线,离线
	private String info ; //签名
	private String date ;//日期

       get和set方法省略...
}


PersonAdapter.java中的代码:

public class PersonAdapter extends ArrayAdapter<Person> {

	/**
	 * ListView 子项布局的id
	 */
	private int rescourceId;
	/**
	 * 上下文
	 */
	private Context context;

	public PersonAdapter(Context context, int textViewResourceId,
			List<Person> objects) {
		super(context, textViewResourceId, objects);
		rescourceId = textViewResourceId;
		this.context = context;
	}

	/**
	 * 一、getView()方法在每个子项被滚动到屏幕内的时候 会被调用。
	 * 二、 提升性能:
	 *     1、当 convertView为空 的时候, 创建一个ViewHolder对象, 并将控件的实例都存放在
	 *       ViewHolder 里, 然后调用 View 的 setTag()方法,将ViewHolder 对象存储在 View 中。
	 *     2、当 convertView 不为空的时候则调用 View的 getTag()方法, 把 ViewHolder 重新取出。
	 *       这样所有控件的实例都缓存在了 ViewHolder 里,就没有必要每次都通过 findViewById()方法来获取控件实例了。
	 * 这样会使ListView的运行效率获得很大的提高
	 */
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		View view = null;
		final ViewHolder viewHolder;
		/**
		 * 通过 getItem()方法获取当前项的Person实例
		 */
		Person person = getItem(position);

		if (convertView == null) {
			/**
			 * 如果 convertView 为空,则使用 LayoutInflater 去动态加载我们传入的子项布局,
			 */
			view = LayoutInflater.from(context).inflate(rescourceId, null);
			viewHolder = new ViewHolder();
			/**
			 * 调用 View 的 findViewById()方法分别 获取到页面的控件对象实例
			 */
			viewHolder.imgView = (ImageView) view.findViewById(R.id.imageView);
			viewHolder.nameView = (TextView) view.findViewById(R.id.nameId);
			viewHolder.dateView = (TextView) view.findViewById(R.id.dateId);
			viewHolder.statusView = (TextView) view.findViewById(R.id.statusId);
			viewHolder.infoView = (TextView) view.findViewById(R.id.infoId);
			/**
			 * 将ViewHolder 存储在View 中 ,
			 */
			view.setTag(viewHolder);
		} else {
			/**
			 * 1、如果不为空则直接对 convertView进行重用。
			 * 2、可以大大提高ListView的运行效率,在快速滚动的时候也可以表现出更好的性能。
			 */
			view = convertView;
			/**
			 * 从view中重新获取ViewHolder
			 */
			viewHolder = (ViewHolder) view.getTag();
		}

		/**
		 * 1、从viewHolder中取出我们缓存的子项布局中的各个控件对象,
		 * 2、将此次加载的Person实例中的数据加载到当前进入屏幕的子项布局中的对应控件上,
		 * 3、完成数据到页面的展示
		 */
		viewHolder.imgView.setImageResource(person.getImgId());
		viewHolder.nameView.setText(person.getName());
		viewHolder.dateView.setText(person.getDate());
		viewHolder.statusView.setText(person.getStatus());
		viewHolder.infoView.setText(person.getInfo());
		viewHolder.imgView.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Toast.makeText(context, "修改 "+viewHolder.nameView.getText()+"的头像", 0).show() ;
			}
		}) ;

		/**
		 * viewHolder存储在view中,填充数据完成之后,我们把view返回,这个view中已经是填充完数据之后的view了
		 * 返回布局
		 */
		return view;

	}

	/**
	 * 内部类 ViewHolder,用于对控件的实例进行缓存
	 */
	class ViewHolder {
		ImageView imgView;
		TextView nameView, dateView, statusView, infoView;
	}

}


item.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:layout_margin="5dp"
    android:orientation="horizontal" >


    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:src="@drawable/ic_launcher" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="4"
        android:layout_gravity="center"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/nameId"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="3dp"
            android:text="name" />

        <TextView
            android:id="@+id/dateId"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:layout_marginRight="5dp"
            android:text="date" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_margin="2dp"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/statusId"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="status" />

            <TextView
                android:id="@+id/infoId"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_weight="3"
                android:text="info" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

MainActivity.java中的代码:

public class MainActivity extends Activity {

	private ListView listView;
	List<Person> datas = new ArrayList<Person>();

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

		listView = (ListView) findViewById(R.id.listView);
		/**
		 * 初始化数据
		 */
		initDatas() ;
		/**
		 * 创建PersonAdapter对象,将子项布局id,和数据源传递进去
		 */
		PersonAdapter adapter = new PersonAdapter(MainActivity.this,
				R.layout.item, datas);
		/**
		 * 将PersonAdapter作为适配器传递给 了 ListView。
		 */
		listView.setAdapter(adapter);
		listView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				// TODO Auto-generated method stub
				Person person = datas.get(position);
				Toast.makeText(MainActivity.this, "您点击了 "+person.getName()+" 这项", 0).show();
			}
		});
	}

	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式

	/**
	 * 获得数据
	 */
	private void initDatas() {
		for (int i = 1; i < 15; i++) {
			Person person = new Person();
			person.setImgId(R.drawable.img1);
			person.setName("司令" + i);
			person.setStatus("[在线]");
			person.setInfo("我们的部队今日就要去南海了");
			person.setDate(df.format(new Date()));
			datas.add(person);
		}
	}

}


项目下载地址:

ListView控件性能提升demo下载





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值