《Android群英传》个人读书笔记
4.1 ListView常用优化技巧
4.1.1 使用ViewHolder模式提高效率
- ViewHoler 模式利用了ListView的缓存机制,避免了每次在getView()的时候通过findViewById()来实例化控件(提高了约50%的效率)
4.1.2 设置项目间分割线
- 系统提供了 divider 以及 dividerHeight 两个属性来完成设置
- 设置分割线为透明: android:divider="@null"
4.1.3 隐藏ListView滚动条
- android:scrollbars="none"
4.1.4 取消ListView的Item点击效果
- android:listSelector="#00000000" 或者使用Android自带的透明色 android:listSelector="@Android:color/transparent"
4.1.5 设置ListView需要显示在第几项
- ListView以Item为单位进行展示,默认显示在第一个Item上
- listview.setSelection(N) N 表示显示的第N个Item 它是一个瞬间的移动
- 平滑的移动:
mListView.smoothScrollBy(distance, duration);
mListView.smoothScrollByOffset(offset);
mListView.smoothScrollToPosition(index);
4.1.6 动态修改ListView
mData.add("New");
mAdapter.notifyDataSetChanged();
- 这样就避免了直接修改adapter的麻烦
4.1.7 遍历ListView中的所有Item
- List作为一个ViewGroup,为我们提供了操纵子View的各种方法,最常用的就是通过getChildAt() 来获取第i个子view
for(int i = 0; i < mListView.getChildCount(); i++)
{
View view = mListView.getChildAt(i);
}
4.1.8 处理空ListView
listView listview = (ListView)findViewById(R.id.listView);
listview.setEmptyView(findViewById(R.id.empty_view));
- 当ListView没有数据的时候, 就会默认展示 empty_view 这张图。而这张图是我们写在布局中,ListView下方的,所有是通过id去找的。
4.1.9 ListView滑动监听
4.1.9.1 OnTouchListener
- 它是View中的监听事件,监听 ACTION_DOWN、ACTION_MOVE、ACTION_UP,来判断用户的滑动方向。
mListView.setOnTouchListener(new View.OnTouchListener(){
@Override
public boolean onTouch(View view, MotionEvent event)
{
swich(event.getAction())
{
case MotionEvent.ACTION_DOWN:
// 触摸时操作
break;
case MotionEvent.ACTION_MOVE:
// 滑动时操作
break;
case MotionEvent.ACTION_UP:
// 抬起时操作
break;
default:
break;
}
return false;
}
})
4.1.9.2 OnScrollListener
- OnScrollListener是AbsListView中的监听事件
mListView.setOnScrollListener(new OnScrollListener(){
@Override
public void onScrollStateChanged(AbsListView view, int scrollState){
switch (scrollState){
case OnScrollListener.SCROLL_STATE_IDLE:
// 滑动时停止
log.d("Test", "SCROLL_STATE_IDLE");
break;
case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
// 正在滚动
log.d("Test", "SCROLL_STATE_TOUCH_SCROLL");
break;
case OnScrollListener.SCROLL_STATE_FLING:
// 手指用力滑动,在离开后由于惯性,listview继续滑动
log.d("Test", "SCROLL_STATE_FLING");
break;
}
}
})
@Override
public void onScroll(AbsListView view,
int firstVisibleItem,
int visibleItemCount,
int totalItemCount)
{
// 滚动时一直调用
Log.d("Test", "onScroll");
}
- firstVisibleItem 当前能看见的第一个Item的id(从0开始)。
- visibleItemCount 当前能看见的Item总数(包括没有显示完整的Item)
- totalItemCount 整个ListVIew的Item数
- 判断是否滚动到最后一行:
if(firstVisibleItem + visibleItemCount == totalItemCount
&& totalItem - Count > 0)
{
//滚动到最后一行
}
- 判断滚动方向:
if(firstVisibleItem > lastVisibleItemPosition)
{
// 上滑
}
else if(firstVisibleItem < lastVisibleItemPosition)
{
// 下滑
}
lastVisibleItemPosition = firstVisibleItem;
- 通过成员变量lastVisibleItemPosition来记录上次第一个可视Item的ID,并与当前的可视Item的ID进行比较,即可知道滑动的方向。
- ListView封装的方法来获得当前可视Item的位置信息
// 获取可视区域内最后一个Item的id
mListView.getLastVisiblePosition();
// 获取可视区域内第一个Item的id
mListView.getFirstVisiblePosition();
4.2 ListView 常用拓展
4.2.1 具有弹性的ListView
- 重写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, mMaxOverDistance,
isTouchEvent);
}
- 计算屏幕的density值,使不同分辨率屏幕的弹性距离保持一致
private void initView()
{
DisplayMetrics metrics = mContext.getResopurces().getDisplayMetrics();
float density = metrics.density;
mMaxOverDistance = (int)(density * mMaxOverDistance);
}