日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

仿网易云音乐Android端歌手资料页面的实现

發布時間:2023/12/14 Android 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 仿网易云音乐Android端歌手资料页面的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近項目首頁需要用到Banner + tab + ViewPager切換的效果,在思考實現的過程中我突然發現,這個效果與網易云音樂Android端的歌手資料頁面十分相似,因此好好把玩了一下網易云音樂,然后模仿出了一個效果類似的頁面,這里就將界面元素完全替換為模仿網易云音樂,作為一個demo拿來分享。

項目地址:網易云音樂歌手資料頁面Demo




說一下實現思路:

頁面分為三個部分,最上方是透明的自定義導航欄(Toolbar),下面是帶有歌手圖片和PagerSlidingTabStrip的Header,最下方是帶有各個子頁面的ViewPager。在滑動的過程中是不能夠改變ViewPager里面滑動組件的高度的,不然會導致滑動距離判斷出現異常,因此ViewPager實際上是占滿整個屏幕的。為了保證上面的Header不會把列表項擋住,在各個Fragment中加入一個與Header高度一樣的空View作為占位。這樣基本上就完成了基本頁面的樣式。水平滑動基本上是沒什么問題了。

接下來就要解決上下滑動時Header的伸縮距離與ViewPager內滑動元素的滾動同步的問題。

列表頁面使用RecyclerView,各種控件組合的頁面使用ScrollView,這些控件的滑動距離與Header伸縮的距離是1:1的,而滑動距離與Header變色實際上也是一次函數關系,因此只需要檢測到RecyclerView和ScrollView的滑動距離,就可以根據這個值的變化來改變頭部,RecyclerView可以通過addOnScrollChangedListener來監測滑動距離:

rcvGoodsList.addOnScrollListener(new RecyclerView.OnScrollListener() {@Overridepublic void onScrolled(RecyclerView recyclerView, final int dx, final int dy) {super.onScrolled(recyclerView, dx, dy);scrolledX += dx;scrolledY += dy;if(HomeListFragment.this.isResumed()) {doOnScrollChanged(scrolledX, scrolledY, dx, dy);}}});
scrolledX和scrolledY分別記錄了RecyclerView的滑動距離,并通過設定在Fragment中的Listener傳遞給上層。

對于ScrollView則需要繼承重寫,并為其添加滑動距離監測的方法:

public class ObservableScrollView extends ScrollView {public interface OnScrollChangedListener {void onScrollChanged(ScrollView scrollView, int scrolledX, int scrolledY, int dx, int dy);}private int scrolledX;private int scrolledY;private OnScrollChangedListener listener;public ObservableScrollView(Context context) {super(context);}public ObservableScrollView(Context context, AttributeSet attrs) {super(context, attrs);}public ObservableScrollView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public void setOnScrollChangedListener(OnScrollChangedListener listener) {this.listener = listener;}@Overrideprotected void onScrollChanged(int l, int t, int oldl, int oldt) {super.onScrollChanged(l, t, oldl, oldt);int dl = l - oldl;int dt = t - oldt;scrolledX += dl;scrolledY += dt;if(listener != null) {listener.onScrollChanged(this, getScrollX(), getScrollY(), dl, dt);}} }


在Header所屬的頁面,對ViewPager所屬的Fragment加入監測滑動距離的Listener,設定好計算顏色變化和滑動距離的初始值即可

/*** 初始化滑動參數,k值* */private void initSlidingParams() {int headerSize = getResources().getDimensionPixelOffset(R.dimen.home_header_size);int navBarHeight = getResources().getDimensionPixelOffset(R.dimen.nav_bar_height);int tabStripHeight = getResources().getDimensionPixelOffset(R.dimen.tabstrip_height);slidingDistance = headerSize - navBarHeight - tabStripHeight;Log.d("HomeFragment", "slidingDistance" + slidingDistance);}/*** 根據頁面滑動距離改變Header方法* */private void scrollChangeHeader(int scrolledY) {if (scrolledY < 0) {scrolledY = 0;}if (scrolledY < slidingDistance) {rlNavBar.setBackgroundColor(Color.argb(scrolledY * 192 / slidingDistance, 0x00, 0x00, 0x00));llHeader.setPadding(0, -scrolledY, 0, 0);currScrollY = scrolledY;} else {rlNavBar.setBackgroundColor(Color.argb(192, 0x00, 0x00, 0x00));llHeader.setPadding(0, -slidingDistance, 0, 0);currScrollY = slidingDistance;}}


這樣單個列表滑動就已經實現了,但是還有一個很重要的問題沒有解決,試想這樣一個場景:我滑動了第一頁,把Header滑到了最小值,此時我切到了另一個頁面,而這個頁面的列表還是未滑動的,這時占位的空View就顯示出來了,或者說我在一個頁面把Header滑到了最大,切到了另一個頁面,就把列表給擋住了。

對于這個問題,我又看了一眼網易云音樂的頁面,發現它的做法是在切換時把各個列表的滑動距離都設定為當前Header的滑動距離,so,我也采取了這樣的方法

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}@Overridepublic void onPageSelected(int position) {currentPosition = position;displayFragments.get(position).setScrolledY(currScrollY);}@Overridepublic void onPageScrollStateChanged(int state) {}});

在Fragment基類中

public abstract void setScrolledY(int scrolledY);

在含有RecyclerView的Fragment中

@Overridepublic void setScrolledY(int scrolledY) {if(rcvGoodsList != null) {if (this.scrolledY >= scrolledY) {int scrollDistahan'yorollBy(0, scrollDistance);}else {rcvGoodsList.scrollBy(0, scrolledY);}}}


在含有ScrollView的Fragment中

@Overridepublic void setScrolledY(int scrolledY) {if (osvHomeRecommend != null) {osvHomeRecommend.scrollTo(0, scrolledY);}}
這樣就實現了滑動距離的同步,最后一個問題是下拉刷新與列表上滑手勢的沖突,在這里我使用的是SwipeRefreshLayout來實現下拉刷新,因此對于此沖突的解決辦法就是自定義SwipeRefreshLayout,重寫onInterceptTouchEvent,加入監聽,如果Header伸縮距離沒有恢復到0,就不觸發下拉刷新。
@Overridepublic boolean onInterceptTouchEvent(MotionEvent event) {if (listener != null && !listener.onInterceptTouchEvent(event)) {return false;}return super.onInterceptTouchEvent(event);}

設定監聽器

srlRefresh.setOnInterceptTouchEventListener(new CusSwipeRefreshLayout.OnInterceptTouchEventListener() {@Overridepublic boolean onInterceptTouchEvent(MotionEvent event) {return currScrollY == 0;}});
這樣基本的效果就已經實現了,在網易云音樂的頁面中還有一個可以橫向滑動的列表,這里也需要在ViewPager中對水平滑動的事件進行攔截判斷,只不過我暫時用不上就沒有實現了,原理同下拉刷新,代碼都在Github上,這里只列出了一些實現思路相關的代碼,僅供參考


總結

以上是生活随笔為你收集整理的仿网易云音乐Android端歌手资料页面的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。