Android中ListView的使用及优化
一.ListView常规使用
1.list item布局文件
<?xml version="1.0" encoding="utf-8"?>
2.Adapter public class MyAdapter extends BaseAdapter { private List mData; private LayoutInflater mInflater; public MyAdapter(Context context, List mData) { this.mData = mData; mInflater = LayoutInflater.from(context); } @Override public int getCount() { return mData.size(); } @Override public Object getItem(int position) { return mData.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder = new ViewHolder(); if (convertView == null) { convertView = mInflater.inflate(R.layout.list_item, null); viewHolder.imageView = (ImageView) convertView.findViewById(R.id.listview_image); viewHolder.textView = (TextView)convertView.findViewById(R.id.listview_text); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.imageView.setImageResource(R.mipmap.ic_launcher); viewHolder.textView.setText(mData.get(position).toString()); return convertView; } private final class ViewHolder { ImageView imageView; TextView textView; }}
3.Activity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); for(int i = 0; i < 20; i++) { list.add(Integer.valueOf(i)); } listView = (ListView) findViewById(R.id.list_view); myAdapter = new MyAdapter(this, list); listView.setAdapter(myAdapter); }
4.Layout <?xml version="1.0" encoding="utf-8"?>
5.效果图:
优化方式:
1.重用convertView:通过重用convertView来减少不必要的view的创建,另外Inflate操作会把xml文件实例化成相应的View实例,是耗时操作。复用convertView的时候,当图片加载采用异步的方式加载的时候可能出现错位的情况,解决办法是给给 ImageView 设置一个 tag, 并预设一个图片。点击打开链接
实际上跟多图片加载框架比如Glide加载图片都是异步的,提高性能。
2.减少findViewById()操作:将xml文件中的元素封装成viewHolder静态类,通过convertView的setTag和getTag将view和相应的对象绑定在一起,避免不必要的findViewById操作。
3.避免在getView方法中作耗时操作:例如加载本地Image需要载入内存以及解析Bitmap,都是比较耗时的操作,如果用户快速滑动listView,会因为getView逻辑过于复杂而造成滑动卡顿的现象。用户滑动的时候不要加载图片,待滑动完成再加载,可以使用第三方的库glide。
4.Item的布局层次结构尽量简单,避免布局太深或者不必要的重绘。
5.尽量保证Adapter的hasStablelds()返回true,这样在notifyDataSetChaged()的时候,如果Item内容没有变化,listView将不会重绘这个View,达到优化的目的。
6.在一些场景中,ScrollView内会包含多个ListView,可以把listView的高度写死固定下来。由于ScrollView在快速下滑过程中需要大量计算每个listView的高度,阻塞UI线程导致卡顿现象,如果每一个item的高度是均匀的,可以通过计算把listView的高度确定下来。
7.使用RecyclerView代替ListView:RecyclerView的用法
每个item内容的变动,ListView都需要调用notifyDataSetChanged来更新全部item。Recycler可以实现当前item的局部刷新,并且引入了增加和移除的动态效果,在性能和定制上有很大改善。
8.开启硬件加速。
二.ListView的扩展
1.设置列别分隔线
android:divider="@color/colorPrimary"android:dividerHeight="10dp"
2.隐藏滚动条
android:scrollbars="none"
3.改变item点击效果 android:listSelector="@android:color/transparent"
4.设置ListView需要显示在第几项 listView.setSelection(N);
或者 listView.smoothScrollToPosition(N);
5.动态改变ListView mData.add("string");mAdapter.notifyDataSetChanded();
6.遍历ListView for (int i = 0; i < listView.getCount(); i++) { View view = listView.getChildAt(i); }
7.ListView滑动监听 OnTouchListener
listView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // break; case MotionEvent.ACTION_HOVER_MOVE: // break; case MotionEvent.ACTION_UP: // break; } return false; } });
OnScrollListener
listView.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { switch (scrollState) { case AbsListView.OnScrollListener.SCROLL_STATE_IDLE: // break; case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: // break; case AbsListView.OnScrollListener.SCROLL_STATE_FLING: // break; } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) { //滚动到最后一行 } int lastVisibleItemPosition = 0; if (firstVisibleItem > lastVisibleItemPosition) { //上滑 } else if (firstVisibleItem < lastVisibleItemPosition) { //下滑 } lastVisibleItemPosition = firstVisibleItem; } });
//获取可见区域最后一个可见item id listView.getLastVisiblePosition();
//获取可见区域第一个可见item id
listView.getFirstVisiblePosition();
8.具有弹性的ListView 重写LisyView的overScrollBy()方法
@Override protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, initHeight(100), isTouchEvent); } private int initHeight(int height) { float density = mContext.getResources().getDisplayMetrics().density; return (int) (height * density); }
9.设置不同的item,Adapter中的type方法 @Override public int getViewTypeCount() { return super.getViewTypeCount(); }
更多相关文章
- Android(安卓)SDCard操作
- android操作excel
- 【android开发】android操作文件
- 最完美的android仿ios开关按钮源码
- android之luncher滑动效果
- Android(安卓)Gridview 禁止滚动的二种方法
- Android(安卓)异步加载一张网络图片
- Android(安卓)gallery 实现定时滑动并添加动画效果
- ListView 实现像Android(安卓)Market那样 分页加载 滚动加载