文档章节

【学习笔记】ListView初识

鬼风
 鬼风
发布于 2016/01/17 13:42
字数 1533
阅读 81
收藏 5
  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滑动监听

    工作时间也不短了,一直忙着做项目,除了自己会的那点基础,有很多是多拼凑一段代码,西拼凑一段代码。

    常用就是到github上找开源库,直接使用。

    但是时间一长,遇到一些特殊需求,就很难搞定。所以,搞定原理还是很重要的。


    2.1 OnTouchListener事件

    OnTouchListener是View中的监听事件,
    通过监听ACTION_DOWN、ACTION_MOVE、ACTION_UP这三个事件发生时的坐标,就可以根据坐标判断用户滑动的方向,
    并在不同的事件中进行相应的逻辑处理,使用代码如下所示:

    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常用拓展

    具有弹性的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);
        }


    修改后的方法:

    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>

    效果如图所示:

© 著作权归作者所有

鬼风
粉丝 13
博文 116
码字总数 32745
作品 0
苏州
Android工程师
私信 提问
【学习笔记】重构 初识一

将与业务无关的封装到类库中,可以重复使用 我的Module类库结构图: activity包中存放的是与业务无关的Activity基类。可以将基类BaseActivity封装到类库里,这里是与业务无关的公用逻辑,主项...

小树coding
2016/02/03
55
0
【学习笔记】Android 5.X UI 设计初识

Android 5.x系列开始使用新的设计风格Material Design来统一整个Android系统的界面设计风格。 1、材料的形态模拟 材料的形态模拟是Material Design中最核心也是改变最大的一个设计,Google通...

小树coding
2016/02/23
69
0
【学习笔记】Android Apk反编译初识

三个重量级的工具: 1.apktool 2.dex2jar 3.jd-gui-windows 工具下载地址:http://pan.baidu.com/s/1mh4F1PY apktool版本太低的话,请到这里下载http://ibotpeaches.github.io/Apktool/ 首先...

小树coding
2016/02/01
95
0
【学习笔记】Android5.X Notification新功能初识

基本的Notification /** 基本的Notification 效果: 折叠式的Notification /** 折叠式的Notification 悬挂式的Notification /** 悬挂式的Notification 显示等级的Notification /** 显示等级的...

小树coding
2016/02/18
294
0
Ext.Error: Unable to parse the JSON returned by the server: You're trying to decode an invalid JSON String

Firefox给出的错误 Ext.Error: Unable to parse the JSON returned by the server: You're trying to decode an invalid JSON String: articlelist.jsp {"results":"100","rows":[{"id":"1"......

anonymous_007
2014/05/28
2.2K
2

没有更多内容

加载失败,请刷新页面

加载更多

安得一颗光明心——《王阳明大传》的读后感作文4100字

安得一颗光明心——《王阳明大传》的读后感作文4100字: 偶然听到一个关于王阳明的讲座,简直让我入了迷。多年前接触到阳明,是在思想史中读到的对阳明心学的介绍,晦涩难懂的学术词汇,让我...

原创小博客
7分钟前
0
0
单点登录-基于Redis+MySQL实现单点登录(SSO)

1. 为什么要用单独登录? 主要便于公司内部多系统统一认证授权管理,一次登录可访问多个跨域系统,也同时更加方便统一管理用户登录(员工离职需要拿掉登录权限、统计所有用户对系统的登录请求...

秋日芒草
20分钟前
1
0
827. Making A Large Island

思想: 将所有连通的 1 分成一个组,分配编号,然后使用BFS统计1的个数,得到这个组的面积。 遍历格子里所有为 0 的元素,检查四个方向的1所在的组并加上这个组面积。于是得到当前元素为 0 ...

reter
28分钟前
0
0
亿万pv的混合云规划实施

基础服务: keepalive,lvs,nginx,dns,ntp,redis集群,yum仓库,web资源 网络高可用 防火墙冗余,交换机堆叠 专线互联 物理机虚拟化 VMware vcenter/ Proxmox...

以谁为师
54分钟前
4
0
聊聊dubbo的LRUCache

序 本文主要研究一下dubbo的LRUCache LRUCache dubbo-2.7.2/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LRUCache.java public class LRUCache<K, V> extends LinkedHashMap<......

go4it
56分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部