Android scrollView和viewpager嵌套 指示器吸顶 根据viewpager每个页面的内容适配高度

原创 2018年04月16日 15:19:11

这几天 朋友问我了个问题  有个特别的需求  页面如下


就是当viewpager里面的当前页面内容足够多的时候  要去能滑上去 并且指示器吸顶  但是当内容不多的时候  能滑到哪就停在哪  当时第一反应是用coordinatelayout  结果不行 内容少的时候  也直接滑到顶部了 

activity的xml文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <com.example.wenlaisu.myapplication.MyScrollview
        android:id="@+id/scroll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:background="?attr/colorPrimary"
                android:scaleType="fitXY"
                android:id="@+id/iv"
                android:src="@drawable/tangyan" />

            <LinearLayout
                android:id="@+id/layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <android.support.design.widget.TabLayout
                    android:id="@+id/tabs"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="?attr/colorPrimary" />
            </LinearLayout>


            <com.example.wenlaisu.myapplication.CustomViewPager
                android:id="@+id/viewpager"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </com.example.wenlaisu.myapplication.MyScrollview>

    <RelativeLayout
        android:id="@+id/rl_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

    </RelativeLayout>
</RelativeLayout>

后来就直接用scrollView包裹来实现了 自定义scrollView实现滚动监听 用来实现指示器吸顶效果  

public class MyScrollview extends ScrollView {

    private ScrollViewListener scrollViewListener = null;

    public MyScrollview(Context context) {
        super(context);
    }

    public MyScrollview(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyScrollview(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, l, t, oldl, oldt);
        }
    }

    public interface ScrollViewListener {
        void onScrollChanged(MyScrollview scrollView, int l, int t, int oldl, int oldt);
    }
}

在activity里面设置监听

scroll.setScrollViewListener(new MyScrollview.ScrollViewListener() {
    @Override
    public void onScrollChanged(MyScrollview scrollView, int l, int t, int oldl, int oldt) {
        if (t >iv.getHeight() && mTabLayout.getParent() == layout) {
            layout.removeView(mTabLayout);
            rl_layout.addView(mTabLayout);
        } else if (t < iv.getHeight() && mTabLayout.getParent() == rl_layout) {
            rl_layout.removeView(mTabLayout);
            layout.addView(mTabLayout);
        }
    }
});

然后就是实现viewpager的每个页面的内容高度适配了  从写viewpager

public class CustomViewPager extends ViewPager {
  
    private int current;  
    private int height = 0;  
    /**  
     * 保存position与对于的View  
     */  
    private HashMap<Integer, View> mChildrenViews = new LinkedHashMap<Integer, View>();
  
    private boolean scrollble = true;  
  
    public CustomViewPager(Context context) {
        super(context);  
    }  
  
    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);  
    }  
  
  
    @Override  
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
        if (mChildrenViews.size() > current) {  
            View child = mChildrenViews.get(current);  
            if (child != null) {  
                child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));  
                height = child.getMeasuredHeight();  
            }  
        }  
  
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);  
  
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
    }  
  
    public void resetHeight(int current) {  
        this.current = current;  
        if (mChildrenViews.size() > current) {  
  
            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
            if (layoutParams == null) {  
                layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, height);
            } else {  
                layoutParams.height = height;  
            }  
            setLayoutParams(layoutParams);  
        }  
    }  
  
    /**  
     * 保存position与对于的View  
     */  
    public void setObjectForPosition(View view, int position) {  
        mChildrenViews.put(position, view);  
    }  
  
  
    @Override  
    public boolean onTouchEvent(MotionEvent ev) {
        if (!scrollble) {  
            return true;  
        }  
        return super.onTouchEvent(ev);  
    }  
  
  
    public boolean isScrollble() {  
        return scrollble;  
    }  
  
    public void setScrollble(boolean scrollble) {  
        this.scrollble = scrollble;  
    }  
  
  
}  
用法是在每个fragment 的onCreatView里面添加一行代码就行 

然后在viewpager所在的activity里面设置监听  就可以了

mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
        mViewPager.resetHeight(position);
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }
});

下面是整个activity的代码

package com.example.wenlaisu.myapplication;

import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import java.util.ArrayList;
import java.util.List;
/**
 * Created by wenlaisu on 2018/4/12.
 */
public class ViewPagerSample extends AppCompatActivity {

    CustomViewPager mViewPager;
    List<Fragment> mFragments;

    String[] mTitles = new String[]{
            "主页", "微博", "相册"
    };
    private TabLayout mTabLayout;
    private MyScrollview scroll;
    private LinearLayout layout;
    private RelativeLayout rl_layout;
    private ImageView iv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);
        // 第一步,初始化ViewPager和TabLayout
        mViewPager = (CustomViewPager) findViewById(R.id.viewpager);
        mTabLayout = (TabLayout) findViewById(R.id.tabs);
        layout = (LinearLayout) findViewById(R.id.layout);
        rl_layout = (RelativeLayout) findViewById(R.id.rl_layout);
        scroll = (MyScrollview) findViewById(R.id.scroll);
        iv = (ImageView) findViewById(R.id.iv);
        setupViewPager();
    }



    private void setupViewPager() {

        mFragments = new ArrayList<>();
        ListFragment listFragment = new ListFragment(mViewPager, 0);
        ListFragment2 listFragment2 = new ListFragment2(mViewPager, 1);
        ListFragment3 listFragment3 = new ListFragment3(mViewPager, 2);
        mFragments.add(listFragment);
        mFragments.add(listFragment2);
        mFragments.add(listFragment3);

        // 第二步:为ViewPager设置适配器
        BaseFragmentAdapter adapter =
                new BaseFragmentAdapter(getSupportFragmentManager(), mFragments, mTitles);

        mViewPager.setAdapter(adapter);
        //  第三步:将ViewPager与TableLayout 绑定在一起
        mTabLayout.setupWithViewPager(mViewPager);

        mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected(int position) {
                mViewPager.resetHeight(position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });

        scroll.setScrollViewListener(new MyScrollview.ScrollViewListener() {
            @Override
            public void onScrollChanged(MyScrollview scrollView, int l, int t, int oldl, int oldt) {
                if (t >iv.getHeight() && mTabLayout.getParent() == layout) {
                    layout.removeView(mTabLayout);
                    rl_layout.addView(mTabLayout);
                } else if (t < iv.getHeight() && mTabLayout.getParent() == rl_layout) {
                    rl_layout.removeView(mTabLayout);
                    layout.addView(mTabLayout);
                }
            }
        });

    }
}

就可以了

demo的github地址


版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/suwenlai/article/details/79960708

ViewPageIndctor,viewPage指示器效果

开发中我们很多时候遇到类似这种的效果 或者是这种三角形的该如何实现呢, 本篇介绍来源于慕课网的张鸿洋的自定义ViewPageIndctor,(视频中讲解的是三角形的那种) 我们看下项目的结构 主...
  • u013424496
  • u013424496
  • 2016-08-02 10:03:20
  • 784

App流行的吸顶效果

现在主流的App中许多加入了吸顶效果,用于在数据较多的展现时与ListView、ScrollView套用。使得用户在滑动读取数据的时候把产品需要持续展示的控件及信息一直固定在屏幕上方,以便用户操作和交...
  • hz51390
  • hz51390
  • 2015-11-21 19:42:41
  • 1678

Android 打造顶部停留控件,可用于所有可滚动的控件(ScrollView,ListView)

1、序言现在很多App为了让一个页面可以有更多展示的东西。于是乎有一个界面就有几个tab进行切换页面,同时滚动的时候为了方便用户切换tab,这时tab需要悬浮在布局的顶部。所以这样就有了这篇blog咯...
  • lanfei1027
  • lanfei1027
  • 2016-03-05 14:43:24
  • 2987

React Native 基础 之ListView实现吸顶效果

当滑动时,这个section header会固定在头部,也就是吸顶效果。但是遗憾的是,在Android平台上不支持吸顶效果 实现吸顶效果需要用到此方法 cloneWithRowsAnd...
  • JLhaoran
  • JLhaoran
  • 2017-04-13 14:38:01
  • 2007

Android scrollView和viewpager嵌套 指示器吸顶 根据viewpager每个页面的内容适配高度

这几天 朋友问我了个问题  有个特别的需求  页面如下就是当viewpager里面的当前页面内容足够多的时候  要去能滑上去 并且指示器吸顶  但是当内容不多的时候  能滑到哪就停在哪  当时第一反应...
  • suwenlai
  • suwenlai
  • 2018-04-16 15:19:11
  • 15

使用Banner实现图片的轮番显示的效果,替换ViewPager + CirclePagerIndicator

今天接触到了Banner,超级好用。 可以很方便的实现替换ViewPager + CirclePagerIndicator的效果。源码来自于github:https://github.com/you...
  • cjm2484836553
  • cjm2484836553
  • 2016-11-13 22:12:22
  • 544

ScrollView嵌套ViewPager自适应高度,图片高度小的会显示空白

最近项目中遇到ScrollView嵌套ViewPager,ViewPager中存放的是ImagView,要求是,ImagView高度不定,接下来就是各种方法尝试,比较普遍的方式就是自定义一个viewp...
  • lzq520210
  • lzq520210
  • 2016-11-17 11:41:35
  • 2235

重写ViewPager实现Scrollview嵌套ViewPager高度自适应

public class MyViewPager extends ViewPager {       public MyViewPager(Context context) {           s...
  • zengchao2013
  • zengchao2013
  • 2017-01-12 15:24:29
  • 2351

Android轮播图控件CustomBanner的使用讲解

今天给大家讲解的是Android轮播图控件CustomBanner的使用。CustomBanner是我在GitHub上传的一个Android轮播图控件。在上一篇博客中,我详细分析了CustomBann...
  • u010177022
  • u010177022
  • 2017-03-14 20:29:57
  • 708

Android中一些第三方开源库

Android开源库 自己一直很喜欢Android开发,就如博客签名一样,我是程序猿,我为自己代言。 在摸索过程中,GitHub上搜集了很多很棒的Android第三方库,推荐给在苦苦寻...
  • XinJiang_Terrorist
  • XinJiang_Terrorist
  • 2016-06-20 13:21:56
  • 149
收藏助手
不良信息举报
您举报文章:Android scrollView和viewpager嵌套 指示器吸顶 根据viewpager每个页面的内容适配高度
举报原因:
原因补充:

(最多只允许输入30个字)