Android知乎選項卡動態(tài)隱藏

選項卡動態(tài)隱藏.gif

效果呢族吻,和知乎首頁一樣,可以去知乎看看哗蜈;點擊back鍵可以返回頂部纽竣。

想法:

  • 列表上拉,選項卡隱藏储笑,下滑出現(xiàn)甜熔;recycleView滾動監(jiān)聽(OnScrollListener)中onScrolled方法的dy參數(shù),dy>0表示上拉突倍,dy<0表示下滑腔稀,剛好合適盆昙。
  • 選項卡怎么隱藏呢,屬性動畫焊虏,移動選項卡的相對位置View.TRANSLATION_Y(Y軸方向移動肯定是_Y),View.TRANSLATION系列都是相對運(yùn)動淡喜,參考系是view原本的位置。
  • 還有個問題诵闭,對于選項卡來說炼团,它需要的顯隱時機(jī)是列表滑動方向改變,而不是只監(jiān)聽它的滑動疏尿;上拉改下滑瘟芝,下滑改上拉這2個時機(jī)才能執(zhí)行動畫,不能在列表同一方向持續(xù)滾動時重復(fù)調(diào)用動畫褥琐。

步驟:

要寫多少代碼呢锌俱? fragmeng中一個recycleView的監(jiān)聽要寫,一個接口要寫踩衩;activity中接口實現(xiàn)嚼鹉。沒了,代碼不多驱富。

Fragment:

public interface RvScrollListener {
    //滑動方向監(jiān)聽
    void scrollType(boolean direction);
    //是否滑動到頂部監(jiān)聽
    void inTop(boolean top,RecyclerView recyclerView);
}

private RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        if (fragmentposition != 0) {
            //如果不是第一個fragment則返回
            return;
        }
        LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
        //得到當(dāng)前列表第一個完全顯示的item的position
        int position = layoutManager.findFirstCompletelyVisibleItemPosition();
        if (position == 0) {
            //如果position為0表示列表正處于頂部
            mRvScrollListener.inTop(true, recyclerView);
        } else {
            mRvScrollListener.inTop(false, recyclerView);
        }
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        //判斷滑動方向锚赤,recycleView item 上拉 下滑不同動畫
        if (dy > 0) {
            isUp = true;
        } else {
            isUp = false;
        }

        if (fragmentposition != 0) {
            return;
            //如果不是第一個fragment則返回
        }
        //過濾掉一些緩慢的滑動
        if (Math.abs(dy) > 10) {
            //滑動方向
            mRvScrollListener.scrollType(dy > 0);
        }
    }
};
  • recycleView第一個監(jiān)聽方法:

@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {}

這個里面就做一件事情,判斷當(dāng)前recycleView是否滑動到頂部褐鸥,然后通過接口傳遞到activity中线脚,當(dāng)點擊back鍵時,如果不在頂部叫榕,則調(diào)用方法滾動到頂部浑侥。

  • recycleView第二個監(jiān)聽方法:

@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {}

做2件事,一是recyleView的item做動畫時晰绎,因為上拉和下滑動畫不一樣寓落,代碼中 isUp 就是用來區(qū)分上拉下滑的((給recycleView的item做加載動畫使用))
二是判斷滑動方向荞下,接口傳遞到activity中伶选。

Activity:

//上拉狀態(tài)
private boolean hasup = true;
//下滑狀態(tài)
private boolean hasdown = true;
//是否在頂部
private boolean inTop = true;
//從fragment傳遞過來的recycleView
private RecyclerView topRecyclerView;

BlankFragment.RvScrollListener mRvScrollListener = new BlankFragment.RvScrollListener() {

    @Override
    public void scrollType(boolean direction) {
        //上拉
        if (direction) {
            hasdown = true;
            //連續(xù)上拉,第一次有效
            if (hasup) {
                ObjectAnimator.ofFloat(mTablayout, View.TRANSLATION_Y, mTablayout.getTranslationY(), PixelChange.dp2px(XjwTablayoutActivity.this, 50)).setDuration(400).start();
                hasup = false;
            }
        } else {//下滑
            hasup = true;
            //連續(xù)下滑尖昏,第一次有效
            if (hasdown) {
                ObjectAnimator.ofFloat(mTablayout, View.TRANSLATION_Y, mTablayout.getTranslationY(), 0).setDuration(400).start();
                hasdown = false;
            }
        }
    }

    @Override
    public void inTop(boolean top, RecyclerView recyclerView) {
        inTop = top;
        topRecyclerView = recyclerView;
    }
};

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    //點擊返回鍵
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        //如果當(dāng)前不是第一個fragmeng則顯示第一個
        if (mViewPager.getCurrentItem() != 0) {
            mViewPager.setCurrentItem(0);
            return true;
        }
        //如果當(dāng)前recycleView沒有在頂部則返回頂部
        if (!inTop) {
            topRecyclerView.smoothScrollToPosition(0);
            return true;
        }
    }
    return super.onKeyDown(keyCode, event);
}
  • 實現(xiàn)接口第一個方法:

@Override
public void scrollType(boolean direction) {}

方法里用到三個boolean值 direction ,hasup, hasdown 仰税,direction判斷執(zhí)行上拉動畫或者下滑動畫;hasup和hasdown作用是:滑動有上拉抽诉,下滑2個狀態(tài)陨簇,處于一種狀態(tài)時動畫只執(zhí)行一次;比如列表正在持續(xù)上拉迹淌,監(jiān)聽也會觸發(fā)多次河绽,上拉的多次觸動中只執(zhí)行一次動畫己单。

  • 實現(xiàn)接口第二個方法:

@Override
public void inTop(boolean top, RecyclerView recyclerView) {}

就一個賦值作用,用在back鍵的點擊事件中onKeyDown葵姥。

  • back鍵點擊

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {}

一點需要注意:recycleView滾動到頂部荷鼠,調(diào)用的是smoothScrollToPosition()方法,這個最簡單榔幸,調(diào)用別的方法譬如smoothScrollBy()允乐,還需要算距離,不過這個方法可以給插值器削咆。

  • 屬性動畫
//隱藏
ObjectAnimator.ofFloat(mTablayout, View.TRANSLATION_Y, mTablayout.getTranslationY(), PixelChange.dp2px(XjwTablayoutActivity.this, 50)).setDuration(400).start();
//顯示
 ObjectAnimator.ofFloat(mTablayout, View.TRANSLATION_Y, mTablayout.getTranslationY(), 0).setDuration(400).start();

注意2個點牍疏,一個是 View.TRANSLATION_Y 這個參數(shù)要寫對,
另外一個是動畫的起始值:
如果隱藏動畫是從0dp移動到50dp,快速切換上拉下滑狀態(tài)時(手指快速上下滑動)控件就會閃拨齐。所以隱藏動畫中從 mTablayout.getTranslationY()的位置移動到 50 dp的位置鳞陨,動態(tài)獲取當(dāng)前選項卡位置就好了,顯示動畫同理瞻惋。(寫50dp是因為我選項卡高度就是50dp)

另外把recycleView的item加載動畫代碼給出來:(這個寫在Adapter里面的,因為要在onBindViewHolder時調(diào)用)

protected Animator[] getAnimators(View view) {  //上滑動畫
    return new Animator[]{
            ObjectAnimator.ofFloat(view, View.ROTATION, 120, 0).setDuration(400)
    };
}

protected Animator[] getAnimatorsDown(View view) {  //下拉動畫
    return new Animator[]{
            ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, -100, 0).setDuration(400),
            ObjectAnimator.ofFloat(view, View.SCALE_X, 0.7f, 1f).setDuration(400)
    };
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (isUp) { //上拉
        Animator[] animators = getAnimators(holder.itemView);
        if (animators.length > 1) {
            AnimatorSet animatorSet = new AnimatorSet();
            animatorSet.playTogether(animators);
            animatorSet.start();
        } else {
            for (Animator annimator : animators) {
                annimator.start();
            }
        }
    } else {//下拉
        Animator[] animatorsDown = getAnimatorsDown(holder.itemView);
        if (animatorsDown.length > 1) {
            AnimatorSet animatorSet = new AnimatorSet();
            animatorSet.playTogether(animatorsDown);
            animatorSet.start();
        } else {
            for (Animator annimator : animatorsDown) {
                annimator.start();
            }
        }
    }
}

item加載動畫和選項卡顯隱動畫差不多厦滤,你可以把 View.SCALE_X 這種參數(shù)改一改,多試試效果歼狼,注意起始值掏导。





對于生活理想,應(yīng)該像宗教徒對待宗教一樣充滿虔誠與熱情羽峰!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末趟咆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子梅屉,更是在濱河造成了極大的恐慌值纱,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坯汤,死亡現(xiàn)場離奇詭異虐唠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)惰聂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進(jìn)店門凿滤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人庶近,你說我怎么就攤上這事【祢荆” “怎么了鼻种?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沙热。 經(jīng)常有香客問我叉钥,道長罢缸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任投队,我火速辦了婚禮枫疆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘敷鸦。我一直安慰自己息楔,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布扒披。 她就那樣靜靜地躺著值依,像睡著了一般。 火紅的嫁衣襯著肌膚如雪碟案。 梳的紋絲不亂的頭發(fā)上愿险,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天,我揣著相機(jī)與錄音价说,去河邊找鬼辆亏。 笑死,一個胖子當(dāng)著我的面吹牛鳖目,可吹牛的內(nèi)容都是我干的扮叨。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼疑苔,長吁一口氣:“原來是場噩夢啊……” “哼甫匹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起惦费,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤兵迅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后薪贫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恍箭,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年瞧省,在試婚紗的時候發(fā)現(xiàn)自己被綠了扯夭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡鞍匾,死狀恐怖交洗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情橡淑,我是刑警寧澤构拳,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響置森,放射性物質(zhì)發(fā)生泄漏斗埂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一凫海、第九天 我趴在偏房一處隱蔽的房頂上張望呛凶。 院中可真熱鬧,春花似錦行贪、人聲如沸漾稀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽县好。三九已至,卻和暖如春暖混,著一層夾襖步出監(jiān)牢的瞬間缕贡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工拣播, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留晾咪,地道東北人。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓贮配,卻偏偏與公主長得像谍倦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子泪勒,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,691評論 2 361

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