以前在作空數據的時候,會在ListView同界面再放一個其它控件,而後在ListView數據爲空時,將控件顯示,有數據再隱藏。
最近發現有方法直接處理: ListView處理空數據時,可用經過方法setEmptyView()來設置空數據佈局
<?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:orientation="vertical"> <Button android:id="@+id/btn_data" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="有數據"/> <Button android:id="@+id/btn_nodata" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="無數據"/> <ListView android:id="@+id/mListView" android:layout_width="match_parent" android:layout_height="wrap_content"></ListView> <!--ListView 數據爲空時 顯示下面默認的圖片--> <ImageView android:id="@+id/empty_view" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/pic1"/> </LinearLayout>
private ListView mListView; private Button btn_data; private Button btn_nodata; private Context context; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_view); context = this; initView(); } private void initView(){ btn_data = (Button)findViewById(R.id.btn_data); btn_nodata = (Button)findViewById(R.id.btn_nodata); btn_data.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String[] datas = {"item1", "item2"}; mListView.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, datas)); } }); btn_nodata.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String[] datas = {}; mListView.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, datas)); } }); mListView = (ListView)findViewById(R.id.mListView); mListView.setEmptyView(findViewById(R.id.empty_view)); }
ListView滑動監聽 java
工做時間也不短了,一直忙着作項目,除了本身會的那點基礎,有不少是多拼湊一段代碼,西拼湊一段代碼。
經常使用就是到github上找開源庫,直接使用。
可是時間一長,遇到一些特殊需求,就很難搞定。因此,搞定原理仍是很重要的。
2.1 OnTouchListener事件
OnTouchListener是View中的監聽事件,
經過監聽ACTION_DOWN、ACTION_MOVE、ACTION_UP這三個事件發生時的座標,就能夠根據座標判斷用戶滑動的方向,
並在不一樣的事件中進行相應的邏輯處理,使用代碼以下所示: android
mListView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (motionEvent.getAction()){ case MotionEvent.ACTION_DOWN: //觸摸時操做 break; case MotionEvent.ACTION_MOVE: //移動時操做 break; case MotionEvent.ACTION_UP: //離開時操做 break; } return false; } });
mListView.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView absListView, int scrollState) { switch (scrollState){ case SCROLL_STATE_IDLE: //滑動中止時 Log.d("Test", "SCROLL_STATE_IDLE"); break; case SCROLL_STATE_TOUCH_SCROLL: //正在滾動 Log.d("Test", "SCROLL_STATE_TOUCH_SCROLL"); break; case SCROLL_STATE_FLING: //手指拋動時,即手指用力滑動 //在離開後ListView因爲慣性繼續滑動 /** * 當用戶沒有作手指拋動的狀態時,這個方法只會回調2次,不然會回調3次,差異就是手指拋動的這個狀態。 * 一般狀況下,咱們會在這個方法中經過不一樣的狀態來設置一些標誌Flag,來區分不一樣的滑動狀態,供其餘方法處理。 */ Log.d("Test", "SCROLL_STATE_FLING"); break; } } /** * * @param absListView * @param firstVisibleItem 當前能看見的第一個Item的ID(從0開始) * @param visibleItemCount 當前能看見的Item總數 * 這裏須要注意的是,當前能看見的Item數,包括沒有顯示完整的Item,即顯示一小半的Item也包括在內了。 * * @param totolItemCount 整個ListViewI 的item總數 */ @Override public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totolItemCount) { //滾動時一直調用 /** * 判斷當前是否滾動到最後一行 */ if(firstVisibleItem + visibleItemCount == totolItemCount && totolItemCount > 0){ //滾動到最後一行 Log.d("Test", "滾動到最後一行"); } /** * 判斷滾動的方向 */ if(firstVisibleItem > lastVisibleItemPosition){ //上滑 Log.d("Test", "上滑"); }else if(firstVisibleItem < lastVisibleItemPosition){ //下滑 Log.d("Test", "下滑"); } lastVisibleItemPosition = firstVisibleItem; Log.d("Test", "onScroll"); } });
ListView經常使用拓展 git
具備彈性的ListView:
Android默認的ListView在滾動到頂端或者底端的時候,並無很好的提示。
在Android5.X中,添加了一個半月形的陰影效果。 滾動到頂部和底部繼續往上或者往下滑動一段距離。
ListView的源代碼有這麼一個方法: 有個 maxOverScrollY,默認值是0,只須要修改這個參數的值,就可讓ListView具備彈性了!
/** * 控制滑動到邊緣的處理方法 * @param deltaX * @param deltaY * @param scrollX * @param scrollY * @param scrollRangeX * @param scrollRangeY * @param maxOverScrollX * @param maxOverScrollY * @param isTouchEvent * @return */ @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, maxOverScrollY, isTouchEvent); }
修改後的方法: github
public class MListView extends ListView { int mMaxOverDistance = (int)getResources().getDisplayMetrics().density*50; public MListView(Context context) { super(context); } public MListView(Context context, AttributeSet attrs) { super(context, attrs); } public MListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } /** * 控制滑動到邊緣的處理方法 * @param deltaX * @param deltaY * @param scrollX * @param scrollY * @param scrollRangeX * @param scrollRangeY * @param maxOverScrollX * @param maxOverScrollY * @param isTouchEvent * @return */ @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, maxOverScrollY, // isTouchEvent); return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, mMaxOverDistance, isTouchEvent); } }
ListView + ToolBar
ListView 向下滑動時,隱藏ToolBar,
向上滑動時,顯示ToolBar功能
代碼以下:
public class ListViewWithTopShowOrHide extends Activity{ private MListView mListView; private float mFirstY; private float mCurrentY; private float mTouchSlop; private int direction;//標識方向 private boolean mShow = true; private List<String> datas = new ArrayList<String>(); private ArrayAdapter adapter; private Context context; private ObjectAnimator animator; private Toolbar mToolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_view_with_top_show_or_hide); context = this; mToolbar = (Toolbar)findViewById(R.id.mToolbar); mListView = (MListView)findViewById(R.id.mListView); //添加頭部 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.addHeaderView(header); mListView.setOnTouchListener(myTouchListener); adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, datas); mListView.setAdapter(adapter); /** * 獲取系統認爲的最低滑動距離 */ mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop(); initData(); } /** * 加載數據 */ private void initData(){ for(int i=0;i<20;i++){ datas.add("item"+i); } adapter.notifyDataSetChanged(); } private View.OnTouchListener myTouchListener = new View.OnTouchListener() { @Override public boolean onTouch(View view, 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){//向上 Log.d("mShow", "direction: 向上滑動"+direction+" mShow:"+mShow); if(mShow){ mShow = !mShow; toolbarAnim(mShow);//隱藏 } }else if(direction == 0){//向下 Log.d("mShow", "direction:向下滑動"+direction+" mShow:"+mShow); if(!mShow){ mShow = !mShow; toolbarAnim(mShow);//顯示 } } //移動時操做 break; case MotionEvent.ACTION_UP: //離開時操做 break; } return false; } }; /** * 是否顯示toolbar * @param isshow */ private void toolbarAnim(boolean isshow){ if(animator!=null && animator.isRunning()){ animator.cancel(); } if(isshow){ //顯示 animator = ObjectAnimator.ofFloat(mToolbar, "translationY", mToolbar.getTranslationY(), 0); }else { //隱藏 animator = ObjectAnimator.ofFloat(mToolbar, "translationY", mToolbar.getTranslationY(), -mToolbar.getHeight()); } animator.start(); } }
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"> <com.example.mydemo.widget.MListView android:id="@+id/mListView" android:layout_width="match_parent" android:layout_height="wrap_content"></com.example.mydemo.widget.MListView> <android.support.v7.widget.Toolbar android:id="@+id/mToolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:title="ListViewWithToolBar" android:background="@android:color/holo_blue_light" app:titleTextColor="@color/white"></android.support.v7.widget.Toolbar> </RelativeLayout>
效果如圖所示: app