不用涉及到各種沖突常規(guī)打造酷炫下拉視差效果SmartRefreshLayout+ViewPager+RecyclerView

首先看下效果

效果圖.gif

背景

上圖所示這種效果辈赋,在很多APP上很常見(jiàn),當(dāng)我們真正想著手開(kāi)發(fā)時(shí)毛俏,可能會(huì)遇到很多沖突問(wèn)題炭庙,很難實(shí)現(xiàn)完美效果饲窿,如果想研究事件沖突的擼友們可以看看這篇文章傳送地址煌寇,于是我本著無(wú)聊的心態(tài)做了下,下面講述下實(shí)現(xiàn)的一種常規(guī)方案逾雄,如果有不足的地方請(qǐng)大家提出阀溶,我將繼續(xù)完善

功能點(diǎn)簡(jiǎn)單說(shuō)明

  1. 下拉整體刷新,上拉加載(上拉隸屬于單個(gè)fragment)
  2. 下拉圖片視差效果鸦泳,開(kāi)始圖片整體放大银锻,向下平移,達(dá)到閥值時(shí)(可自定義)做鹰,下拉只保留向下平移效果击纬,頂部title左右倆側(cè)按鈕漸變隱藏
  3. 上滑頂部title停留
  4. 上滑頂部title左右倆次按鈕改變顏色,頂部title背景顏色漸變顯示
  5. Tablayout停留

布局設(shè)計(jì)分析

-FrameLayout(最外層)
    -ImageView(頭部背景圖)
        -SmartRefreshLayout(頭部刷新控件)
            -CoordinatorLayout
                -AppBarLayout
                     -CollapsingToolbarLayout
                         -Toolbar
                         ...省略中間巴拉巴拉布局
                     -Tablayout
                     -ViewPager
   -Toolbar

功能點(diǎn)模塊分析钾麸,效果實(shí)現(xiàn)

1.下拉整體刷新更振,上拉加載(上拉隸屬于單個(gè)fragment)

通過(guò)上述布局分析可以看出炕桨,在最外層嵌套了一層刷新控件 SmartRefreshLayout ,此控件提供頂部刷新功能肯腕,Tablayout+ViewPager+Fragment實(shí)現(xiàn)方法可以放N多個(gè)Fragment献宫,F(xiàn)ragment布局中設(shè)計(jì)如下

<?xml version="1.0" encoding="utf-8"?>
<com.scwang.smartrefresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/refreshLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</com.scwang.smartrefresh.layout.SmartRefreshLayout>

于是會(huì)出現(xiàn)外層和內(nèi)層Fragment都會(huì)出現(xiàn)上拉和下拉功能,所以我們
禁止外層上拉加載功能 mRefreshLayout.setEnableLoadMore(false);
禁止內(nèi)層下拉刷新功能 mRefreshLayout.setEnableLoadMore(false);
這樣就實(shí)現(xiàn)了我們的需求

2.下拉圖片視差效果实撒,開(kāi)始圖片整體放大姊途,向下平移,達(dá)到閥值時(shí)(可自定義)知态,下拉只保留向下平移效果捷兰,頂部title左右倆側(cè)按鈕漸變隱藏

所以我們需要對(duì)RefreshLayout做向下平移監(jiān)聽(tīng),代碼如下

 mRefreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener() {
            @Override
            public void onHeaderMoving(RefreshHeader header, boolean isDragging, float percent, int offset, int headerHeight, int maxDragHeight) {
                //設(shè)置圖片向下移動(dòng)
                mIvHeader.setTranslationY(offset / 2);
                //設(shè)置title漸變效果
                mToolbar1.setAlpha(1 - Math.min(percent, 1));
                //設(shè)置圖片寬度變化   當(dāng)達(dá)到指定設(shè)置的指定值后  寬度停止  只向下移動(dòng)
                if (offset <= 100) {
                    ViewGroup.LayoutParams layoutParams = mIvHeader.getLayoutParams();
                    layoutParams.width = (mScreenWidth + offset);
                    ((ViewGroup.MarginLayoutParams) layoutParams).setMargins(-(layoutParams.width - mScreenWidth) / 2,  -DisplayUtil.dip2px(MainActivity.this,200), 0, 0);
                    mIvHeader.requestLayout();
                }
            }
        });

(1)圖片向下平移實(shí)現(xiàn)我們可通過(guò)setTranslationY實(shí)現(xiàn)负敏,速度自己可以調(diào)節(jié)(offset / 2)
(2)頂部titleBar下拉漸變隱藏寂殉, mToolbar1.setAlpha(1 - Math.min(percent, 1));搞定,建議大家打印下回調(diào)的各個(gè)參數(shù)日志原在,以便理解
(3)圖片放大重點(diǎn)說(shuō)一下友扰,其實(shí)原理是動(dòng)態(tài)改變圖片的寬度,如果直接改變width的話庶柿,因?yàn)閳D片的坐標(biāo)起始點(diǎn)在左上角村怪,改變了寬度之后圖片中心點(diǎn)會(huì)往屏幕中心點(diǎn)右側(cè)偏移(在寬度變大情況下),所以需要給圖片設(shè)置一個(gè)margins浮庐,

值為=(圖片寬度-圖片放大寬度)/2

因?yàn)閳D片需要實(shí)現(xiàn)向下拉升不到頭效果甚负,所以布局MargingTop需要個(gè)給負(fù)數(shù)如( -DisplayUtil.dip2px(MainActivity.this,200)),這樣就實(shí)現(xiàn)了一直拉不到頭效果

3.如何實(shí)現(xiàn)上滑頂部title停留

這個(gè)測(cè)試了多種方法审残,但還是選擇了下邊這種梭域,思路為CollapsingToolbarLayout中放一個(gè)titleBar,但是這個(gè)titleBar無(wú)任何顯示作用,只是提供滑動(dòng)到頂部停留作用搅轿,這是這個(gè)控件不設(shè)置任何屬性的強(qiáng)大之處病涨,真正titlebar的相關(guān)控件放在最外層,和imageView同級(jí)璧坟,它一直存在既穆,只是對(duì)它做顯示隱藏處理
在說(shuō)明一下,如果CollapsingToolbarLayout中的titleBar放置返回等按鈕雀鹃,在下拉刷新時(shí)幻工,整體布局向下移動(dòng),這樣title中返回和右邊的按鈕會(huì)一起向下移動(dòng)黎茎,這樣體驗(yàn)不好囊颅,所以采用了倆個(gè)titleBar這樣思路去實(shí)現(xiàn)

此外衍生一個(gè)問(wèn)題,titleBar高度如何處理,比如高版本低版本等踢代,為了適配頁(yè)面先鱼,不采用固定值做法,動(dòng)態(tài)測(cè)量狀態(tài)欄高度

//增加View的paddingTop,增加的值為狀態(tài)欄高度 (智能判斷奸鬓,并設(shè)置高度)  titleBar
 StatusBarUtil.setPaddingSmart(this, mToolbar);
  StatusBarUtil.setPaddingSmart(this, mToolbar1);
/** 增加View的paddingTop,增加的值為狀態(tài)欄高度 (智能判斷焙畔,并設(shè)置高度)*/
    public static void setPaddingSmart(Context context, View view) {
        if (Build.VERSION.SDK_INT >= 19) {
            ViewGroup.LayoutParams lp = view.getLayoutParams();
            if (lp != null && lp.height > 0) {
                lp.height += getStatusBarHeight(context);//增高
            }
            view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + getStatusBarHeight(context),
                    view.getPaddingRight(), view.getPaddingBottom());
        }
    }
4.如何實(shí)現(xiàn)上滑頂部title左右倆次按鈕改變顏色,頂部title背景顏色漸變顯示

想實(shí)現(xiàn)這個(gè)效果需要監(jiān)聽(tīng)上滑移動(dòng)串远,這樣我們需要用到AppBarLayout的方法宏多,mAppbarLayout.addOnOffsetChangedListener(this);

@Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
        int scrollRangle = appBarLayout.getTotalScrollRange();
        /**
         * 如果是verticalOffset改成負(fù)數(shù)   有不一樣的效果,可以模擬試試
         */
        mIvHeader.setTranslationY(verticalOffset);
        /**
         * 這個(gè)數(shù)值可以自己定義
         */
        if (verticalOffset < -10) {
            mIvBack.setImageResource(R.drawable.back_black);
            mIvMenu.setImageResource(R.drawable.icon_menu_black);
        } else {
            mIvBack.setImageResource(R.drawable.back_white);
            mIvMenu.setImageResource(R.drawable.icon_menu_white);
        }

        int mAlpha = (int) Math.abs(255f / scrollRangle * verticalOffset);
        //頂部title漸變效果
        mToolbar1.setBackgroundColor(Color.argb(mAlpha, 255, 255, 255));
        mToolbarUsername.setTextColor(Color.argb(mAlpha, 0, 0, 0));
    }

(1)整體上滑時(shí)澡罚,我想讓圖片整體向上移動(dòng)伸但,所以
mIvHeader.setTranslationY(verticalOffset);,改變圖片的Y軸位置留搔,
如果想讓圖片反方向移動(dòng)更胖,可以將verticalOffset改成負(fù)數(shù),如
mIvHeader.setTranslationY(-verticalOffset);隔显,有不一樣的視差體驗(yàn)却妨,效果也是棒棒的,大家可以試試
(2)頂部title左右倆測(cè)按鈕改變顏色括眠,其實(shí)也就是改變圖片彪标,自己定義一個(gè)閾值,很好實(shí)現(xiàn)

if (verticalOffset < -10) {
            mIvBack.setImageResource(R.drawable.back_black);
            mIvMenu.setImageResource(R.drawable.icon_menu_black);
     } else {
            mIvBack.setImageResource(R.drawable.back_white);
            mIvMenu.setImageResource(R.drawable.icon_menu_white);
     }

或者對(duì)圖片做漸變顯示隱藏操作也是可以的掷豺,就會(huì)有圖片漸變由白變成黑的效果捞烟,大家可以試試,方法是這個(gè)setAlpha
(3)頂部title背景漸變效果当船,和文字漸變题画,
int mAlpha = (int) Math.abs(255f / scrollRangle * verticalOffset);
mToolbar1.setBackgroundColor(Color.argb(mAlpha, 255, 255, 255));
mToolbarUsername.setTextColor(Color.argb(mAlpha, 0, 0, 0));

5.如何實(shí)現(xiàn)Tablayout停留

這個(gè)歸功于AppBarLayout+CollapsingToolbarLayout強(qiáng)大之處
AppBarLayout里放入的都可以跟著向上滑動(dòng)滑出布局的的,添加app:layout_scrollFlags="scroll"屬性可以滑出布局德频,TabLayout沒(méi)有添加苍息,所以停留在頂部,理解這個(gè)屬性就隨意操控了抱婉,還有很多炫酷的動(dòng)畫視覺(jué)效果档叔,大家可以去查閱下


項(xiàng)目提供幾個(gè)輪子演示,大家可以盡情的玩耍了

指示器輪子
刷新框架輪子
adapter適配器輪子
屏幕適配輪子蒸绩,倆種實(shí)現(xiàn)方法
多字體輪子,因?yàn)轫?yè)面不好看铃肯,改了一種字體

CSDN下載地址
gitHub下載

最后患亿,祝大家開(kāi)發(fā)順利!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子步藕,更是在濱河造成了極大的恐慌惦界,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咙冗,死亡現(xiàn)場(chǎng)離奇詭異沾歪,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)雾消,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門灾搏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人立润,你說(shuō)我怎么就攤上這事狂窑。” “怎么了桑腮?”我有些...
    開(kāi)封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵泉哈,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我破讨,道長(zhǎng)丛晦,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任提陶,我火速辦了婚禮采呐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搁骑。我一直安慰自己斧吐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布仲器。 她就那樣靜靜地躺著煤率,像睡著了一般。 火紅的嫁衣襯著肌膚如雪乏冀。 梳的紋絲不亂的頭發(fā)上蝶糯,一...
    開(kāi)封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音辆沦,去河邊找鬼昼捍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛肢扯,可吹牛的內(nèi)容都是我干的妒茬。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼蔚晨,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼乍钻!你這毒婦竟也來(lái)了肛循?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤银择,失蹤者是張志新(化名)和其女友劉穎多糠,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體浩考,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡夹孔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了析孽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搭伤。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖绿淋,靈堂內(nèi)的尸體忽然破棺而出闷畸,到底是詐尸還是另有隱情,我是刑警寧澤吞滞,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布佑菩,位于F島的核電站,受9級(jí)特大地震影響裁赠,放射性物質(zhì)發(fā)生泄漏殿漠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一佩捞、第九天 我趴在偏房一處隱蔽的房頂上張望绞幌。 院中可真熱鬧,春花似錦一忱、人聲如沸莲蜘。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)票渠。三九已至,卻和暖如春芬迄,著一層夾襖步出監(jiān)牢的瞬間问顷,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工禀梳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留杜窄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓算途,卻偏偏與公主長(zhǎng)得像塞耕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子郊艘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 如果你還在為處理滑動(dòng)沖突而發(fā)愁荷科,那么你需要靜下心來(lái)看看這邊文章唯咬,如果你能徹底理解這篇文章中使用的技術(shù)纱注,那么畏浆,一切滑...
    SiberianDante閱讀 9,751評(píng)論 12 85
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件狞贱、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,024評(píng)論 4 62
  • 畫著畫 頭一抬 窗外的凄涼清一色的天空沖刷過(guò)我的眼睛 又是一年冬季了呢 去年冬天我還在聽(tīng)著張國(guó)榮的歌 悠閑的不...
    大大大大大不丟t閱讀 152評(píng)論 1 0
  • 你從哪里來(lái)? 要到哪里去氧枣? 看到越來(lái)越多的朋友開(kāi)始關(guān)注這類的問(wèn)題沐兵,而今天在一本叫做《原則》的書中,開(kāi)篇也是這樣警示...
    愛(ài)吃土的楊小姐閱讀 625評(píng)論 1 0
  • 2018年最后1天 你是不是一邊驚訝于時(shí)間過(guò)得太快,一邊抱怨還有許多目標(biāo)沒(méi)實(shí)現(xiàn)烧董? 時(shí)間是公平的毁靶,它給每一個(gè)努力的人...
    4YearsClub閱讀 293評(píng)論 1 1