国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android實現(xiàn)知乎選項卡動態(tài)隱藏效果實例

2019-10-22 18:15:41
字體:
供稿:網(wǎng)友

前言

因為最近手上項目也是資訊閱讀類,簡書,掘金,知乎的效果都想往項目上加,沒事就來仿寫。

android,知乎,選項卡實現(xiàn),選項卡
選項卡動態(tài)隱藏.gif

效果呢,和知乎首頁一樣,可以去知乎看看;點擊back鍵可以返回頂部。下面話不多說了,來一起看看詳細的介紹吧。

想法:

  • 列表上拉,選項卡隱藏,下滑出現(xiàn);recycleView滾動監(jiān)聽(OnScrollListener)中onScrolled方法的dy參數(shù),dy>0表示上拉,dy<0表示下滑,剛好合適。
  • 選項卡怎么隱藏呢,屬性動畫,移動選項卡的相對位置View.TRANSLATION_Y(Y軸方向移動肯定是_Y),View.TRANSLATION系列都是相對運動,參考系是view原本的位置。
  • 還有個問題,對于選項卡來說,它需要的顯隱時機是列表滑動方向改變,而不是只監(jiān)聽它的滑動;上拉改下滑,下滑改上拉這2個時機才能執(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();  //得到當前列表第一個完全顯示的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)聽方法:

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

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

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

@Overridepublic 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傳遞過來的recycleViewprivate 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; }};@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) { //點擊返回鍵 if (keyCode == KeyEvent.KEYCODE_BACK) {  //如果當前不是第一個fragmeng則顯示第一個  if (mViewPager.getCurrentItem() != 0) {   mViewPager.setCurrentItem(0);   return true;  }  //如果當前recycleView沒有在頂部則返回頂部  if (!inTop) {   topRecyclerView.smoothScrollToPosition(0);   return true;  } } return super.onKeyDown(keyCode, event);}

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

@Overridepublic 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)接口第二個方法:

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

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

back鍵點擊

@Overridepublic 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)獲取當前選項卡位置就好了,顯示動畫同理。(寫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) };}@Overridepublic 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ù)改一改,多試試效果,注意起始值。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網(wǎng)的支持。


注:相關(guān)教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 云和县| 微博| 易门县| 霍邱县| 武义县| 泽州县| 合水县| 嘉峪关市| 永平县| 郁南县| 旌德县| 米泉市| 临泉县| 女性| 中牟县| 泸定县| 凌海市| 天长市| 青田县| 新宾| 二手房| 工布江达县| 蓝田县| 连平县| 垣曲县| 区。| 县级市| 怀化市| 绍兴县| 景宁| 新建县| 丰城市| 南木林县| 克什克腾旗| 临夏市| 通州区| 精河县| 囊谦县| 从江县| 龙陵县| 长兴县|