当前位置:   article > 正文

实现标题固定,上滑覆盖标题的效果_向上滑动覆盖

向上滑动覆盖

前两天实验了一个效果,demo是速卖通app AliExpress 商品详情页面,上滑覆盖顶部ViewPager。

不过在实现的效果略有不同,我设定的是ViewPager是固定页面顶部的,没有不同步滑动的效果。

如果想实现不同步滑动的效果,可以设置viewpager的滑动速度是原来速度的1/3或者其他。


第一步,重写ScrollView,实现三个构造方法,重写onScrollChanged()这个方法。


第二步,创建接口OnScrolledListener:

  1. public interface OnScrolledListener {
  2. /**
  3. * ScrollView的滑动事件的回调监听
  4. * @param y ScrollView的滑动纵坐标
  5. */
  6. void scroll(int y);
  7. }

第三步,在重写的ScrollView中初始化OnScrolledListener接口:

  1. private OnScrolledListener listener = new OnScrolledListener() {
  2. @Override
  3. public void scroll(int y) {
  4. }
  5. };


第四步,在onScrollChanged()这个方法中对接口回调监听:

  1. @Override
  2. protected void onScrollChanged(int l, int t, int oldl, int oldt) {
  3. listener.scroll(getScrollY());
  4. super.onScrollChanged(l, t, oldl, oldt);
  5. }


第五步, 重写的ScrollView中添加方法,设置回调监听对象:

  1. public void setListener(OnScrolledListener listener){
  2. this.listener = listener;
  3. }

第六步,当布局文件xml中使用被重写的ScrollView:

  1. <com.ximoon.corveredtitlescrollview.MyScrollView
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:id="@+id/msv"
  6. xmlns:android="http://schemas.android.com/apk/res/android">
  7. <RelativeLayout
  8. android:layout_width="match_parent"
  9. android:layout_height="wrap_content">
  10. <android.support.v4.view.ViewPager
  11. android:id="@+id/vp"
  12. android:layout_width="match_parent"
  13. android:layout_height="200dp"></android.support.v4.view.ViewPager>
  14. <TextView
  15. android:layout_width="wrap_content"
  16. android:layout_height="wrap_content"
  17. android:text="我是标题"
  18. android:textSize="20sp"
  19. android:layout_alignParentLeft="true"
  20. android:layout_marginLeft="20dp"
  21. android:layout_alignBottom="@id/vp"/>
  22. <LinearLayout
  23. android:layout_width="match_parent"
  24. android:layout_height="700dp"
  25. android:layout_below="@id/vp"
  26. android:background="@android:color/holo_red_dark"></LinearLayout>
  27. </RelativeLayout>
  28. </com.ximoon.corveredtitlescrollview.MyScrollView>

MyScrollView是刚刚重写的ScrollView,里面包含一个子控件RelativeLayout

(ScrollView的特性,最多含有一个子控件)。

RelativeLayout里面包含三部分,一个就是顶部的ViewPager。

还有一个是TextView,随着滑动,在ViewPager上显示,最后是LinearLayout,是整个滑动区域。


第七步,在Activity内找到控件,并设置回调监听对象,重写滑动事件:

  1. private MyScrollView myScrollView = null;
  2. private ViewPager mViewPager = null;
  3. /** 屏幕宽度*/
  4. public static int DISPLAYW = 0;
  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. // 测量屏幕的宽度
  9. DISPLAYW = getResources().getDisplayMetrics().widthPixels;
  10. setContentView(R.layout.activity_main);
  11. myScrollView = (MyScrollView) findViewById(R.id.msv);
  12. mViewPager = (ViewPager) findViewById(R.id.vp);
  13. // 设置viewpager的宽高一致,为屏幕的宽度(因为嵌套在scrollview中,所以必须重新设置高度)
  14. mViewPager.setLayoutParams(new RelativeLayout.LayoutParams(DISPLAYW,DISPLAYW));
  15. myScrollView.setListener(new OnScrolledListener() {
  16. @Override
  17. public void scroll(int y) {
  18. // 若滑动坐标的绝对值即滑动距离不超过viewpager的高度的时候,设置viewpager回滚位置(相当于viewpager滑动的距离是ScrollView滑动距离的相反值,以保持viewpager固定)
  19. // if ((y < 0 && -y <= DISPLAYW) || (y > 0 && y <= DISPLAYW)) {
  20. // 因为viewpager是可横向滚动的控件,所以需要按屏计算它的目前滚动宽度,滚动纵坐标即ScrollView的滚动纵坐标的相反值
  21. mViewPager.scrollTo(mViewPager.getCurrentItem() * DISPLAYW, -y); // 此处存在一个问题 滑屏到中间位置的时候再滑动viewpager,会导致图片位置出错,可重写viewpager的滑动纠错
  22. // }
  23. }
  24. });
  25. mViewPager.setAdapter(new ImageAdapter());
  26. mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
  27. @Override
  28. public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
  29. // 当viewpager滑动的时候解决viewpager恢复相对于scrollview的坐标造成的显示失误
  30. myScrollView.scrollTo(0,0);
  31. }
  32. @Override
  33. public void onPageSelected(int position) {
  34. }
  35. @Override
  36. public void onPageScrollStateChanged(int state) {
  37. }
  38. });
  39. }
而这句代码:
mViewPager.scrollTo(mViewPager.getCurrentItem() * DISPLAYW, -y);

正常情况下,myScrollView滑动多少距离,myScrollView 内部的控件也应该随之滑动多少距离。

但是由于在ScrollView内,所以获得的相对滑动坐标即getScrollY()为0。

这个时候,我们需要手动设置mViewPager相对myScrollView的相对滑动纵坐标。

意思表示,当myScrollView向上或者向下滑动到y坐标的时候,mViewPager则向相反方向滑动相同的距离。

所以滑动纵坐标为-y。参数y是通过myScrollView.getScrollY()获得的mScrollY返回过来,

所以通过scrollTo()方法就可以滑动到坐标指示位置。

横坐标就更简单了,因为mViewPager相当于一个横向的ScrollView,

所以它也有一个滑动坐标,但是是横向的,每一屏都对应着不同的横坐标。

myScrollView滑动的时候,如果设置滑动横坐标为0。

mViewPager.scrollTo(0,-y),那么造成的后果就是当mViewPager不在position=0的位置的时候,

myScrollView的滑动会促使mViewPager回到position为0的位置。

添加mViewPager滑动的监听事件,并在onPageScrolled()方法中设置myScrollView的滑动事件。

此方法可另类解决当myScrollView滑动到mViewPager的中间位置时再滑动myScrollView,

造成mViewPager的相对滑动纵坐标出现问题,

导致mViewPager的底部出现在可滑动区域的上方,而mViewPager只显示下半部分的错误。



github地址:点击打开链接

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/93746
推荐阅读
相关标签
  

闽ICP备14008679号