仿掘金框架之listview全解(二)

仿掘金框架之listview全解(二).jpg

文章首发:Android程序员日记

作者:贤榆的鱼

测试阅读时间:4min 30s

前言

我先把昨天那篇“仿掘金框架之listview全解(一)”中提到的,我们可以通过这个项目练习到的知识点再列举一下:

  • listView的基本用法
  • listView的复用优化
  • listview添加headerView实现一些布局和功能
  • listview通过footerview和滚动监听实现上拉加载更多
  • listview通过触摸监听事件实现上下bar的布局隐藏功能

在昨天的分享当中,我已经分享了前面四点!那么今天我接着分享第五点,不多说先看掘金app本身的动态效果图

正文

续“仿掘金框架之listview全解(一)

[ 5 ] 通过listview的触摸监听事件,实现头尾bar的布局隐藏

思路:在listView的触摸事件当中,我们判断手触摸滑动大于一定的正值或者小于一定的负值,我们分别对应进行头尾bar的隐藏和显示的属性动画!

Step 0:先展示一下整体的布局

处理技巧:为了能够在隐藏之后全屏都是listview那么我们需要用RelativeLayout作为根布局,让listview在底层,头尾bar在上层!同时为了不让headbar遮挡住headerView的内容,所以我们再做添加一块headbar高度的空白view!


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.timen4.ronnny.JueJinModel.MainActivity">

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/sr_refresh"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        >
        <ListView
            android:scrollbars="vertical"
            android:fadingEdge="vertical"
            android:overScrollMode="never"
            android:dividerHeight="0.5dp"
            android:divider="#05999999"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/listView"
            android:layout_alignParentTop="true" />
        <Button
            android:clickable="true"
            android:visibility="gone"
            android:id="@+id/empty_fresh"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="暂无数据点击刷新"
            android:textSize="40sp"
            />
    </android.support.v4.widget.SwipeRefreshLayout>

    <LinearLayout
        android:visibility="visible"
        android:clickable="true"
        android:background="#0280FC"
        android:gravity="center_vertical"
        android:id="@+id/head_bar"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">
        <Button

            android:drawableLeft="@drawable/tab_home_find_search"
            android:paddingLeft="8dp"
            android:drawablePadding="8dp"
            android:layout_margin="7dp"
            android:background="@drawable/search_button_selector"
            android:textColor="#99ffffff"
            android:text="@string/search"
            android:gravity="left|center_vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
    <LinearLayout
        android:gravity="bottom"
        android:background="@drawable/shadow_bottom"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal"
        android:id="@+id/bottom_bar"
        android:layout_width="match_parent"
        android:layout_height="51dp">
        <ImageButton
            android:id="@+id/ib_home"
            android:src="@drawable/tab_home_selector"
            style="@style/BottomButtonTheme"
            />
        <ImageButton
            android:id="@+id/ib_explore"
            android:src="@drawable/tab_explore_selector"
            style="@style/BottomButtonTheme" />
        <ImageButton
            android:id="@+id/ib_notifications"
            android:src="@drawable/tab_notificaions_selector"
            style="@style/BottomButtonTheme"
            />
        <ImageButton
            android:id="@+id/ib_profile"
            android:src="@drawable/tab_profile_selector"
            style="@style/BottomButtonTheme"
            />
    </LinearLayout>
</RelativeLayout>

Step 1:从xml中实例化头尾bar


    mBottom_bar = (LinearLayout) findViewById(R.id.bottom_bar);
    mHead_bar = (LinearLayout) findViewById(R.id.head_bar);

Step 2:实现listview的触摸事件:


 mlistView.setOnTouchListener(new View.OnTouchListener() {
            private float mEndY;
            private float mStartY;
            private int direction;//0表示向上,1表示向下
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        mStartY = event.getY();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        mEndY = event.getY();
                        float v1 = mEndY - mStartY;

                        if (v1 > 3 && !isRunning&& direction == 1) {
                            direction = 0;
                            showBar();
                            mStartY = mEndY;
                            return false;
                        } else if (v1 < -3 && !isRunning && direction == 0) {
                            direction = 1;
                            hideBar();
                            mStartY = mEndY;
                            return false;
                        }
                        mStartY = mEndY;
                        break;
                    case MotionEvent.ACTION_UP:
                        break;
                }
                return false;
            }
        });
//隐藏头尾bar的方法(这里我们用的是属性动画)
public void hideBar() {
    mHeaderAnimator = ObjectAnimator.ofFloat(mHead_bar, "translationY", -mHead_bar.getHeight());
    mBottomAnimator = ObjectAnimator.ofFloat(mBottom_bar, "translationY", mBottom_bar.getHeight());
    mHeaderAnimator.setDuration(300).start();
    mBottomAnimator.setDuration(300).start();
    mHeaderAnimator.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationStart(Animator animation) {
            super.onAnimationStart(animation);
            isRunning = true;
        }
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            isRunning = false;
        }
    });
}
//显示头尾bar的方法
public void showBar() {
    mHeaderAnimator = ObjectAnimator.ofFloat(mHead_bar, "translationY", 0);
    mBottomAnimator = ObjectAnimator.ofFloat(mBottom_bar, "translationY", 0);

    mHeaderAnimator.setDuration(300).start();
    mBottomAnimator.setDuration(300).start();
}

注:

这里我再一次使用了标识符的手法,
第一个是通过改变isRunning的状态来判断动画是结束!否则在快速滑动时,我们动画会有卡顿的现象!
第二个是通过direction标识符,来判断滑动的方向,这样也是为了保证在向同一个方向上产生触摸滑动时,不会因为每一小段距离的滑动就调用一次动画从而导致动画不顺畅!
大家如果想看一下这两个标志符是怎样影响效果的,那么可clone一下代码然后自己把值替换掉试试看!

老规矩最后看一下我们仿掘金的效果图:

该项目的github地址:https://github.com/luorenyu/JuejinMoudel.git

后记

如果大家觉得还不错的可以把github上面的代码download下来看一下!如果是新手或初学者也可以自己敲一下!这个Demo中基本含盖了listview大多数常用内容的操作!另外这个Demo中还有别的一些东西是可以分享的。比如带波纹效果的button,比如关于SwipeRefreshLayout实现下拉刷新的使用等等!这些都会在接下来的时间一一和大家分享!另外,这个仿掘金app实现了这一个页面,其他的点击事件什么都还没有做!不过,我会持续更新它的!
现在,我越来越觉得实操是学习和探索一项技能最好的方式,书写是总结和梳理或者用我们的术语是“抽象”我们实操内容最好的方法!希望这两句话也能帮助到大家!

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

推荐阅读更多精彩内容