Android22-ListView常用优化技巧

1. 使用ViewHolder模式提高效率

  1. 定义一个内部类ViewHolder
  2. 在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(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 mData;
   private Context mContext;
   private int mCurrentItem;

   public FocusListViewAdapter(Context context, List 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;
   }
}

你可能感兴趣的:(Android22-ListView常用优化技巧)