scrollview嵌套viewpager(fragment里有listview)

项目地址:

demo的GitHub地址

经常用到scrollview嵌套listview,
效果是:listview自己不滚动,随着scrollview的滚动而滚动。

但是有个需求是scrollview嵌套viewpager,viewpager有三个fragment,fragment里有listview。

MainActivity布局

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    tools:context="example.com.myvplvsv.MainActivity">

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

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_gravity="center"
            android:gravity="center"
            android:text="Hello World!"
            android:textColor="@color/colorAccent"
            android:textSize="25sp" />

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

            <LinearLayout
                android:id="@+id/linearLayout1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:layout_marginTop="12dp">

                <TextView
                    android:id="@+id/tab1"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:gravity="center"
                    android:text="@string/tab1"
                    android:textColor="#cccccc"
                    android:textSize="10sp" />

                <TextView
                    android:id="@+id/tab2"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:gravity="center"
                    android:text="@string/tab2"
                    android:textColor="#cccccc"
                    android:textSize="10sp" />

                <TextView
                    android:id="@+id/tab3"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:gravity="center"
                    android:text="@string/tab3"
                    android:textColor="#cccccc"
                    android:textSize="10sp" />

            </LinearLayout>

            <View
                android:id="@+id/cursor"
                android:layout_width="150dp"
                android:layout_height="3dp"
                android:background="#ff7012" />
        </LinearLayout>

        <example.com.myvplvsv.view.ViewPagerForScrollView
            android:id="@+id/vp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#ff4081" />
    </LinearLayout>
</ScrollView>

知识点:

1、动画改变字体大小: tab2.animate().scaleX(1.5f).scaleY(1.5f).setDuration(200);
2、布局管理器的使用改变view的位置、大小等
3、viewpager的addOnPageChangeListener监听。

参考:

ViewPropertyAnimator的使用

ViewPager的setOnPageChangeListener方法详解

Android - 布局管理器LayoutInflater及LayoutParams动态设置宽高属性

MainActivity:


public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final int TAB_COUNT = 3;
    private TextView tab1;
    private TextView tab2;
    private TextView tab3;
    private ViewPager mVp;

    private int offset = 0;//初始位置
    private View cursor;
    private int scrollWidth;
    private int currentIndex;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViews();

        setListener();

        initVp();

        initTabs();
    }

    private void setListener() {
        tab1.setOnClickListener(this);
        tab2.setOnClickListener(this);
        tab3.setOnClickListener(this);
    }

    private void findViews() {
        tab1 = (TextView) findViewById(R.id.tab1);
        tab2 = (TextView) findViewById(R.id.tab2);
        tab3 = (TextView) findViewById(R.id.tab3);
        cursor = findViewById(R.id.cursor);
        mVp = ((ViewPager) this.findViewById(R.id.vp));
    }

    private void initTabs() {
        //将顶部文字恢复默认值
        setTabsColor(tab1);
        tab1.animate().scaleX(1.5f).scaleY(1.5f).setDuration(0);//设置时长为0

        //屏幕宽度
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int screenW = dm.widthPixels;

        //指示器滚动间隔
        scrollWidth = screenW / 3;
        //指示器宽度设定
        int cursorWidth = (screenW / 6);
        //指示器初始位置
        offset = (screenW / TAB_COUNT - cursorWidth) / 2;

        //布局管理器使用方法一:
//        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(cursor.getLayoutParams());
//        layoutParams.width = cursorWidth;
//        layoutParams.setMargins(offset, 0, 0, 0);
//        cursor.setLayoutParams(layoutParams);

        //布局管理器使用方法二:
        LinearLayout.LayoutParams cursorLayoutParams = (LinearLayout.LayoutParams) cursor.getLayoutParams();
        cursorLayoutParams.width = cursorWidth;
        cursorLayoutParams.leftMargin = offset;
        cursor.setLayoutParams(cursorLayoutParams);
    }

    private void initVp() {
        ArrayList<Fragment> fragmentLists = new ArrayList<>();
        fragmentLists.add(new Fragment1());
        fragmentLists.add(new Fragment2());
        fragmentLists.add(new Fragment3());
        FragmentManager fragmentManager = getSupportFragmentManager();

        mVp.setFocusable(false);
        mVp.setAdapter(new MyAdapter(fragmentManager, fragmentLists));
        mVp.setOffscreenPageLimit(2);
        mVp.setCurrentItem(0);
        mVp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                switch (position) {
                    //成功左滑一页(0到1):
                    // onPageScrolled执行,positionOffset从0开始变大,此时position=0,currentIndex=0
                    // onPageSelected执行:currentIndex变为1,此时position=0,currentIndex=1
                    // onPageScrolled继续执行,positionOffset从0开始变大直到无限接近1,此时position=0,currentIndex=1
                    // 最后onPageScrolled继续执行,positionOffset从无限接近1突然恢复到0,此时position=1,currentIndex=1
                    case 0:
                        if (currentIndex == 0) {
                            setIndicatorPosition(offset + (int) (scrollWidth * positionOffset));
                            Log.e("000", "0-->currentIndex == 0");
                        } else if (currentIndex == 1) {
                            setIndicatorPosition(offset + (int) (scrollWidth * (positionOffset)));
                            Log.e("000", "0-->currentIndex == 1");
                        }
                        break;

                    case 1:
                        if (currentIndex == 1) {
                            setIndicatorPosition(offset + scrollWidth + (int) (scrollWidth * positionOffset));
                            Log.e("000", "1-->currentIndex == 1");
                        } else if (currentIndex == 2) {
                            setIndicatorPosition(offset + scrollWidth + (int) (scrollWidth * (positionOffset)));
                            Log.e("000", "1-->currentIndex == 2");
                        }
                        break;

                    case 2:
                        if (currentIndex == 2) {
                            setIndicatorPosition(offset + scrollWidth * 2);
                            Log.e("000", "2-->currentIndex == 2");
                        }
                        break;
                }
            }

            @Override
            public void onPageSelected(int position) {
                currentIndex = position;//已选中位置:012
                Log.e("000", "onPageSelected==currentIndex==" + currentIndex);
                switch (position) {
                    case 0:
                        tab1.animate().scaleX(1.5f).scaleY(1.5f).setDuration(200);
                        tab2.animate().scaleX(1.0f).scaleY(1.0f).setDuration(200);
                        tab3.animate().scaleX(1.0f).scaleY(1.0f).setDuration(200);

                        setTabsColor(tab1);
//                        setIndicatorPosition(offset);
                        break;

                    case 1:
                        tab2.animate().scaleX(1.5f).scaleY(1.5f).setDuration(200);
                        tab1.animate().scaleX(1.0f).scaleY(1.0f).setDuration(200);
                        tab3.animate().scaleX(1.0f).scaleY(1.0f).setDuration(200);

                        setTabsColor(tab2);
//                        setIndicatorPosition(offset + scrollWidth);
                        break;

                    case 2:
                        tab3.animate().scaleX(1.5f).scaleY(1.5f).setDuration(200);
                        tab2.animate().scaleX(1.0f).scaleY(1.0f).setDuration(200);
                        tab1.animate().scaleX(1.0f).scaleY(1.0f).setDuration(200);

                        setTabsColor(tab3);
//                        setIndicatorPosition(offset + scrollWidth * 2);
                        break;
                }

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    private void setIndicatorPosition(int offset) {
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(cursor.getLayoutParams());
        layoutParams.setMargins(offset, 0, 0, 0);
        cursor.setLayoutParams(layoutParams);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tab1:
                mVp.setCurrentItem(0);
                break;
            case R.id.tab2:
                mVp.setCurrentItem(1);
                break;
            case R.id.tab3:
                mVp.setCurrentItem(2);
                break;

        }
    }

    private void setTabsColor(TextView textView) {
        tab1.setTextColor(ContextCompat.getColor(this, R.color.defalut_color));
        tab2.setTextColor(ContextCompat.getColor(this, R.color.defalut_color));
        tab3.setTextColor(ContextCompat.getColor(this, R.color.defalut_color));

        textView.setTextColor(ContextCompat.getColor(this, R.color.select_color));
    }


}

ViewPagerForScrollView

解决viewpager(内含listview)随scrollview一起滑动

/**
 * ScrollView嵌套viewpager
 */

public class ViewPagerForScrollView extends ViewPager {
    public ViewPagerForScrollView(Context context) {
        super(context);
    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int height = 0;
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if (h > height)
                height = h;
        }

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

MyListView

解决listview不显示


public class MyListView extends ListView {

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

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

    public MyListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    /**
     * 自适应
     */
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);

    }
}

Fragment1

需设置 mLv.setFocusable(false);解决不置顶的问题

public class Fragment1 extends Fragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment1_layout, container, false);
        ListView mLv = ((ListView) view.findViewById(R.id.lv));
        mLv.setDivider(new ColorDrawable(Color.parseColor("#ff0000")));
        mLv.setDividerHeight(5);

        mLv.setFocusable(false);
        return view;
    }
}

最后

这样就实现了viewpager随scrollview一起滚动 ,但是还有一个问题就是如果三个fragment页面的listview高度不统一,那么fragment将依靠最高的那一个为准,也就是说会有比较矮的fragment有空白。
比如:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值