第四章 ListView 使用技巧

Android 群英传笔记
第一章Android体系与系统架构
第二章 Android开发工具及技巧
第三章 Android控件架构与事件拦截机制
第四章 ListView 使用技巧
第五章 Android Scroll 分析
第六章 Android 绘图机制与屏幕适配
第七章 Android 动画机制与使用技巧
第八章 Activity与Activity调用栈分析
第九章 Android 系统信息与安全机制
第十章 Android性能优化
本文出自:
//www.greatytc.com/u/a1251e598483

说实话 就是一个刚做android 的同学也知道ListView 的使用吧;
在Android 开发中ListView出现的频率是相当的高,可能最近有点没落了,因为在5.X的时候 增加了RecyclerView ,ListView 能实现的,RecyclerView 都能实现,且效率更高, 关于一会要写的优化,RV 已经帮封装好了,不需要再写这些一堆代码了,使用起来更加方便,实现的效果更多,比如 竖向,横向的list,瀑布流等都是默认的选项,但是今天还是写下ListView的种种吧,也算是对ListView 的一个使用总结;

1. 使用ViewHolder 模式提高效率

ViewHolder模式充分利用了ListView 的视图缓存机制,避免每次调用getView 的时候都去findViewById() 实例化控件,这样在数据超过一屏幕可以展示下的情况下都是可以提高效率的.

设置分割线
这个比由于是直接支持的,比RV好处理多了

直接在布局文件里写
android:divider="@android:color/dark_gray"
android:dividerHeight="10dp"
如果不想设置 android:divider="@null"

取消listView item 的点击效果

android:listSelector="#0000"

设置需要显示在第几项

listView.setSelection(N);
类似scrollTo 瞬间完成移动,或者可以使用如下代码实现平滑移动
listView.smoothScrollBy(distance,duration);
listView.smoothScrollByOffset(offset);
listView.smoothScrollToPosition(index);

动态修改Listview

list.add(bean);
adapter.notifyDataSetChanged();

ListView 的滑动监听

除了下面要介绍的 监听方法 还可以通过 使用 GestureDetector手势识别,VelocityTracker 滑动速度检测等辅助类来完成监听;

            @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;
            }
        });

OnScrollListener

        listView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int i) {
                switch (i){
                    case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
                        // 滑动停止时
                        break;
                    case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                        // 正在滚动
                        break;
                    case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
                        // 手指抛动时, 用手指用户滑动手指离开 由于惯性继续滑动
                        break;
                }
            }

            @Override
            public void onScroll(AbsListView absListView,
 int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                //滚动时会一直调用这个方法
            }
        });

可以在 onScroll 方法中做一些事
比如 判断是不是滑到最后一个了
if(firstVisibleItem +visibleItemCount == totalItemCount && totalItemCount > 0 ){
//滑动到最后一行
}

还可以判断 滚动的方法问题;
if(firstVisibleItem > lastVisibleItemPosition){
//上滑
} else if(firstVisibleItem < lastVisibleItemPosition){
//下滑
}
lastVisibleItemPosition = firstVisibleItem;

//获取可视区域内最后一个item的id 同样的也有第一个;
listView.getLastVisiblePosition();

重写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, maxOverScrollY, isTouchEvent);
    }

重写ListView 重写这个方法,修改 maxOverScrollY 这个字,在return 的时候 返回我们定义的值就行了, 默认的是0 ,没有效果,

为了更好的适配大部分手机,可以根据手机 的 density来计算具体的值

        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        float density = metrics.density;
        mMaxOverScrollY = (int)(density * maxOverScrollY);

看到 这块的时候,我想讲一个我在实际项目中用到的 监听屏幕滑动的案例;
需求就是 一个页面,默认的时候不显示title ,屏幕上滑时,title由无到有,一个渐变过程, 其实就是监听ScrollView 的滚动事件 setOnScrollListener 下面就是试下这个需求的代码,大致可以看懂吧

 @Override
    public void onScroll(int scrollY) {
        float k = Math.abs(scrollY);
        if (k <= 50) {
//滑动的距离小于50 时 title是透明的,不显示
            rlTitle.getBackground().mutate().setAlpha(0);
//            tv_top_title.setVisibility(View.GONE);
            rlTitle.setVisibility(View.GONE);
            common_title_bottom_line.setVisibility(View.GONE);
        } else if (k > 50 && k < 200) {
//50到200之间随着滑动的距离变化来调整透明度
            rlTitle.getBackground().mutate().setAlpha((int) ((k - 50) / 150 * 255));
            if ((int) ((k - 50) / 150 * 255) > 100) {
//                tv_top_title.setVisibility(View.VISIBLE);
                rlTitle.setVisibility(View.VISIBLE);
                common_title_bottom_line.setVisibility(View.VISIBLE);
            } else {
//                tv_top_title.setVisibility(View.GONE);
                rlTitle.setVisibility(View.GONE);
                common_title_bottom_line.setVisibility(View.GONE);
            }
        } else {
// 大于200后 就一直显示着 不透明的title
            rlTitle.getBackground().mutate().setAlpha(255);
//            tv_top_title.setVisibility(View.VISIBLE);
            rlTitle.setVisibility(View.VISIBLE);
            common_title_bottom_line.setVisibility(View.VISIBLE);
        }
    }

代码中有一个内容,需要注意一下 rlTitle.getBackground().mutate().setAlpha(255); 的 mutate() 当时为什么要加这个方法呢 是我在想通过代码动态改变 title的背景的透明度时,他把整个页面的背景搞得混乱了,完全不是想要的效果了, 网上查到原来是因为:

我明明只给title的背景设置了着色的 Drawable,为什么其他的颜色色值也改变了呢?这是因为 Android 为了优化系统性能,资源 Drawable 只有一份拷贝,你修改了它,等于所有的都修改了。 也是就是他们是共享状态的 ;幸运的是,Drawable 提供了一个方法 mutate(),来打破这种共享状态,等于就是要告诉系统,我要修改(mutate)这个 Drawable。给 Drawable 调用 mutate() 方法以后。

所以以后遇到这种背景颜色错乱,可以看看是不是这个原因导致的;
好了 今天这一章就先这样吧;后续如果想到更好的内容,会完善进来;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,270评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,489评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,630评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,906评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,928评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,718评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,442评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,345评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,802评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,984评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,117评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,810评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,462评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,011评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,139评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,377评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,060评论 2 355

推荐阅读更多精彩内容