Android22-ListView常用优化技巧
2017-05-24 本文已影响0人
figure_ai
1. 使用ViewHolder模式提高效率
- 定义一个内部类ViewHolder
- 在getView()方法中通过视图缓存机制来重用缓存即可。
设置item间的分隔线
注:这里可以把分隔线设置为一个颜色,也可以设置为一个图片资源。
android:divider="@android:color/darker_gray" android:dividerHeight="10dp"
以下代码可以把分隔线设置为透明:
android:divider="@null"
隐藏ListView的滚动条
android:scrollbars="none"
取消ListView的Item点击效果
android:listSelector="#00000000"
android:listSelector="@android:color/transarent"
动态修改ListView
mData.add("new"); mAdapter.notifyDataSetChanged();
如上代码,当修改了Adapter的映射List之后,只需要调用Adapter的notifyDatasetChanger()方法,通知ListView修改数据源即可,需注意的是在使用mAdapter.notifyDataSetChanged()方法时,必须保证传进Adapter的数据List是同一个List而不能是其他对象。
遍历ListView中的所有Item
for (int i = 0; i < mListView.getChildCount(); i++) { View view = mListView.getChildAt(i); }
处理空ListView
setEmptyView()方法可以在ListView中无数据时设置一个默认的显示布局,而当ListView有数据的时候则不会显示,代码示例如下:
ListView listView = (ListView)findViewById(R.id.listView); listView.setEmptyView(findViewById(R.id.empty_view));
ListView滑动监听
- 使用OnTouchListener()来实现滑动监听
mListView.setOnTouchListener(new View.OnTouchListener() {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
//触摸时的操作
break;
case MotionEvent.ACTION_MOVE:
//移动时的操作
break;
case MotionEvent.ACTION_UP:
//手指离开屏幕时的操作
break;
}
});
- 使用OnScrollListener()来实现滑动监听
OnScrollListener是AbsListView中的监听事件,它封装了很多与ListView相关的信息。以下是OnScrollListener的一般使用方法。
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");
case OnScrollListener.SCROLL_STATE_FLING:
//手指抛开时
//在离开后,ListView由于惯性继续滑动
Log.d("Test", SCROLL_STATE_FLING);
break;
}
}
/*
* view: 当前的ListView
* firstVisibleItem: 当前能看见的第一个Item的ID,包括显示一小半的Item
* visibleItemCount: 当前能看见的Item总数
* totalItemCount: 整个ListView的Item总数。
*/
@Override
public void onScroll(AbsListView view,
int firstVisibleItem,
int visibleItemCount,
int totalItemCount) {
//滚动时一直调用
Log.d("Test", "onScroll");
}
})
- 判断是否滚动到最后一行
if (firstVisibleItem + visibleItemCount == totalItemCount&&totalItem-Count>0) {
//滚动到最后一行
}
- 判断滚动的方向
if (firstVisibleItem > lastVisibleItemPosition) {
//上滑
} else if (firstVisibleItem < lastVisibleItemPosition){
//下滑
}
lastVisibleItemPosition = firstVisibleItem;
- 获取可视区域内的Item
//获取可视区域内最后一个Item的id
mListView.getLastVisiblePosition();
//获取可视区域内第一个Item的id
mListView.getFirstVisiblePosition();
ListView常用扩展
具有弹性的ListView
//控制滑到边缘到处理方法
@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);
}
根据滑动方向,自动隐藏toolbar
public class ScrollHideList extends AppCompatActivity {
private Toolbar mToolbar;
private ListView mListView;
private String[] mstr = new String[20];
private int mTouchSlop;
private float mFirstY;
private float mCurrentY;
private int direction;
private ObjectAnimator mAnimator;
private boolean mShow = true;
View.OnTouchListener myTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mFirstY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
mCurrentY = event.getY();
if (mCurrentY - mFirstY > mTouchSlop) {
direction = 0;//down
} else if (mFirstY - mCurrentY > mTouchSlop) {
direction = 1;//up
}
if (direction == 1) {
if (mShow) {
toolbarAnim(1);//hide
mShow = !mShow;
}
} else if (direction == 0) {
if (!mShow) {
toolbarAnim(0);//show
mShow = !mShow;
}
}
break;
case MotionEvent.ACTION_UP:
break;
}
return false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.scroll_hide);
mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mListView = (ListView) findViewById(R.id.listview);
for (int i = 0; i < mstr.length; i++) {
mstr[i] = "Item" + i;
}
View header = new View(this);
header.setLayoutParams(new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT,
(int) getResources().getDimension(
R.dimen.abc_action_bar_default_height_material)));
mListView.setAdapter(new ArrayAdapter<String>(ScrollHideList.this, android.R.layout.simple_expandable_list_item_1,
mstr));
mListView.setOnTouchListener(myTouchListener);
}
private void toolbarAnim(int flag) {
if (mAnimator != null && mAnimator.isRunning()) {
mAnimator.cancel();
}
if (flag == 0){
mAnimator = ObjectAnimator.ofFloat(mToolbar, "translationY", mToolbar.getTranslationY(),0);
} else {
mAnimator = ObjectAnimator.ofFloat(mToolbar, "translationY", mToolbar.getTranslationY(),-mToolbar.getHeight());
}
mAnimator.start();
}
}
动态改变ListView布局
public class FocusListViewAdapter extends BaseAdapter {
private List<String> mData;
private Context mContext;
private int mCurrentItem;
public FocusListViewAdapter(Context context, List<String> data) {
this.mContext = context;
this.mData = data;
}
public int getCount() {
return mData.size();
}
public Object getItem(int position) {
return mData.get(position);
}
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout layout = new LinearLayout(mContext);
layout.setOrientation(LinearLayout.VERTICAL);
if (mCurrentItem == position) {
layout.addView(addFocusView(position));
} else {
layout.addView(addNormalView(position));
}
return layout;
}
public void setmCurrentItem(int currentItem) {
this.mCurrentItem = currentItem;
}
private View addFocusView(int i) {
ImageView iv = new ImageView(mContext);
iv.setImageResource(R.mipmap.ic_launcher);
return iv;
}
private View addNormalView(int i) {
LinearLayout layout = new LinearLayout(mContext);
layout.setOrientation(LinearLayout.HORIZONTAL);
ImageView iv = new ImageView(mContext);
iv.setImageResource(R.mipmap.ic_launcher);
layout.addView(iv, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
TextView tv = new TextView(mContext);
tv.setText(mData.get(i));
layout.addView(tv,new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
layout.setGravity(Gravity.CENTER);
return layout;
}
}