【學習筆記】ListView初識

  1. 處理空ListView

    以前在作空數據的時候,會在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));
    
        }




  2. 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;
                }
            });





    2.2 OnScrollListener事件
    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");
                }
            });



  3. 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

相關文章
相關標籤/搜索