自定义View动态布局实现顶部序号栏和ViewPager联动切换

版权声明:本文为博主原创文章,未经博主允许不得转载。转载请注明出处。 https://blog.csdn.net/qq_36882793/article/details/82382806

不知道怎么改GIF,所以用的图片。话不多说,效果图如下。

这里写图片描述

这里写图片描述

这里写图片描述

这里顶部序号右上角的勾勾是加上去的,设置是否显示或者设置展示图片。
可以通过左右两端的箭头点击切换下一个Fragment,也可以直接点击顶部序号切换相应Fragment,互动ViewPager时顶部选中序号也会随之切换。

具体看代码:

MainActivity

package com.example.qxb_810.pagecontrollviewdemo;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import com.example.qxb_810.widgets.CommonPageControlView;
import com.example.qxb_810.widgets.MyFragmentPagerAdapter;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.pcv_title)
    CommonPageControlView pcvTitle;
    @BindView(R.id.vp_content)
    ViewPager vpContent;

    private PagerAdapter mPagerAdapter;
    private List<Fragment> mFragments = new ArrayList<>();
    private CommonPageControlView.PageControlListener pageControlListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        initFragments();
        initListener();
        pcvTitle.setmListener(pageControlListener);     // 设置回调
        pcvTitle.setTotalPage(mFragments.size());       // 设置总页数
        pcvTitle.setCurrPage(0);    // 设置默认显示第一页

    }

    /**
     *  初始化Fragment
     */
    private void initFragments(){
        mFragments.add(MyTestFragment.newInstance("1"));
        mFragments.add(MyTestFragment.newInstance("2"));
        mFragments.add(MyTestFragment.newInstance("3"));
        mFragments.add(MyTestFragment.newInstance("4"));
        mFragments.add(MyTestFragment.newInstance("5"));
        mFragments.add(MyTestFragment.newInstance("6"));
        mFragments.add(MyTestFragment.newInstance("7"));
        mPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), mFragments);
        vpContent.setAdapter(mPagerAdapter);
    }
    /**
     *  设置监听事件
     */
    private void initListener(){
        pageControlListener = new CommonPageControlView.PageControlListener() {
            @Override
            public void selectedPage(int postion) {
                vpContent.setCurrentItem(postion);
            }
        };

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

            @Override
            public void onPageSelected(int position) {
                selectOneFragment(position);
            }

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

    /**
     *  切换到某一个Fragment
     * @param position
     */
    private void selectOneFragment(int position){
        pcvTitle.setCurrPage(position);
    }
}

MainActivity 布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

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

    <com.example.qxb_810.widgets.CommonPageControlView
        android:id="@+id/pcv_title"
        android:layout_width="match_parent"
        android:background="@color/colorPrimaryDark"
        android:layout_height="wrap_content"></com.example.qxb_810.widgets.CommonPageControlView>

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"></android.support.v4.view.ViewPager>
</LinearLayout>

自定义顶部序号View

package com.example.qxb_810.widgets;

import android.content.Context;
import android.graphics.Color;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.example.qxb_810.pagecontrollviewdemo.R;

import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

import javax.xml.transform.stream.StreamResult;

/**
 * create 2018/9/3 15:10
 * desc 左右滑动顶部栏
 */

public class CommonPageControlView extends LinearLayout implements View.OnClickListener {
    private static final int MAX_DISPLAY_COUNT = 5;     // 显示最大数量
    private static final int NUMBER_DISPLAY_WIDTH = 40;     // 数字展示宽度

    private Context mContext;
    private ImageView mLeftImageView;
    private ImageView mRightImageView;
    private LinearLayout mContentLayout;
    private LinearLayout mNumberContentLayout;
    private PageControlListener mListener;

    private int mCurrPage = 0;
    private boolean isShowHint = true;  // 是否显示勾勾
    private List<TextView> mTextViewList = new ArrayList<>();
    private List<ImageView> mImageViewList = new ArrayList<>();

    private int mImgHint = R.mipmap.img_gougou;     // 左上角的勾勾
    private int mSelectedDrawable = R.drawable.shape_base_control_blue;     // 被选中的背景图
    private int mUnSelectedDrawable = R.drawable.shape_page_control_white;    // 选中的背景图

    public CommonPageControlView(Context context) {
        super(context);
        initView(context);
    }

    public CommonPageControlView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public CommonPageControlView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    public void setmListener(PageControlListener mListener) {
        this.mListener = mListener;
    }

    private void initView(Context Context) {
        mContext = Context;
        // 水平居中布局
        setGravity(Gravity.CENTER);
        setOrientation(LinearLayout.HORIZONTAL);

        // 左箭头布局
        LinearLayout.LayoutParams leftArrowParams = new LinearLayout.LayoutParams(dip2px(mContext, 20), dip2px(mContext, 25));
        leftArrowParams.rightMargin = dip2px(mContext, 20);
        mLeftImageView = new ImageView(mContext);
        mLeftImageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);    // 设置图片显示方式
        mLeftImageView.setBackgroundResource(R.mipmap.img_left_arrow_white);
        mLeftImageView.setClickable(true);
        mLeftImageView.setOnClickListener(this);
        addView(mLeftImageView, leftArrowParams);

        // 中心区域
        LinearLayout.LayoutParams contentLayoutParams = new LinearLayout.LayoutParams(dip2px(this.mContext, NUMBER_DISPLAY_WIDTH * MAX_DISPLAY_COUNT), dip2px(mContext, 50));
        mContentLayout = new LinearLayout(mContext);
        mContentLayout.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
        mContentLayout.setOrientation(LinearLayout.HORIZONTAL);
        addView(mContentLayout, contentLayoutParams);

        // 数字布局
        LinearLayout.LayoutParams numberContentLayoutParams = new LinearLayout.LayoutParams(dip2px(this.mContext, NUMBER_DISPLAY_WIDTH * MAX_DISPLAY_COUNT), ViewGroup.LayoutParams.MATCH_PARENT);
        mNumberContentLayout = new LinearLayout(mContext);
        mNumberContentLayout.setGravity(Gravity.CENTER);
        mNumberContentLayout.setOrientation(LinearLayout.HORIZONTAL);
        mContentLayout.addView(mNumberContentLayout, numberContentLayoutParams);

        // 右箭头布局
        LinearLayout.LayoutParams rightArrowParams = new LinearLayout.LayoutParams(dip2px(mContext, 20), dip2px(mContext, 25));
        rightArrowParams.leftMargin = dip2px(mContext, 20);
        mRightImageView = new ImageView(mContext);
        mRightImageView.setBackgroundResource(R.mipmap.img_right_arrow_white);
        mRightImageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);    // 设置图片显示方式
        mRightImageView.setClickable(true);
        mRightImageView.setOnClickListener(this);
        addView(mRightImageView, rightArrowParams);

    }

    /**
     * 设置总页数
     *
     * @param totalPage
     */
    public void setTotalPage(int totalPage) {
        LinearLayout.LayoutParams layoutParams = (LayoutParams) mNumberContentLayout.getLayoutParams();
        layoutParams.width = dip2px(mContext, (totalPage <= MAX_DISPLAY_COUNT ? (NUMBER_DISPLAY_WIDTH * MAX_DISPLAY_COUNT) : (NUMBER_DISPLAY_WIDTH * totalPage)));
        layoutParams.leftMargin = 0;
        this.mNumberContentLayout.setLayoutParams(layoutParams);

        for (int i = 0; i < totalPage; i++) {
            // 设置数字布局
            LinearLayout.LayoutParams numberTextViewParams = new LinearLayout.LayoutParams(dip2px(mContext, 30), dip2px(this.mContext, 30));
            TextView textView = new TextView(mContext);
            textView.setPadding(0, 0, 0, 0);
            textView.setBackgroundResource(R.drawable.shape_page_control_white);
            textView.setText((i + 1) + "");
            textView.setTextSize(15);
            textView.setTextColor(Color.BLUE);
            textView.setGravity(Gravity.CENTER);
            final int postion = i;
            textView.setEnabled(true);
            textView.setOnClickListener(v -> {
                mCurrPage = postion;
                mListener.selectedPage(postion);
            });

            // 设置图片布局
            ImageView imageView = new ImageView(mContext);
            RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(dip2px(mContext, 15), dip2px(mContext, 15));
            imageParams.setMargins(50, -14, 0, 40);

            // 添加布局
            RelativeLayout.LayoutParams rlLayoutParams = new RelativeLayout.LayoutParams(dip2px(mContext, NUMBER_DISPLAY_WIDTH), ViewGroup.LayoutParams.MATCH_PARENT);
            RelativeLayout titlelayout = new RelativeLayout(mContext);   // 设置每个标题的布局
            titlelayout.setGravity(Gravity.CENTER);
            titlelayout.addView(textView, numberTextViewParams);  // 在标题布局中添加控件
            titlelayout.addView(imageView, imageParams);

            mImageViewList.add(imageView);
            mTextViewList.add(textView);
            mNumberContentLayout.addView(titlelayout, rlLayoutParams);
        }
    }

    /**
     * 选择某一页
     *
     * @param currPage
     */
    public void setCurrPage(int currPage) {
        mCurrPage = currPage;
        mLeftImageView.setAlpha(0 == currPage ? 0.5F : 1.0F);
        mRightImageView.setAlpha(mTextViewList != null && mTextViewList.size() - 1 == currPage ? 0.5F : 1.0F);

        setDisplay(currPage);
        for (int i = 0; i < mTextViewList.size(); i++) {
            TextView textView = mTextViewList.get(i);
            if (currPage == i) {
                textView.performClick();    // 触发textView点击事件
                textView.setTextColor(Color.WHITE);
                textView.setBackgroundResource(R.drawable.shape_base_control_blue);

            } else {
                textView.setTextColor(Color.BLUE);
                textView.setBackgroundResource(R.drawable.shape_page_control_white);
            }
            mImageViewList.get(i).setBackgroundResource(mCurrPage == i && isShowHint ? mImgHint : Color.alpha(0));    // 设置背景图
        }
    }

    /**
     * 设置展示到超过设置最大页数后的效果
     *
     * @param currPage
     */
    private void setDisplay(int currPage) {
        int increment = 0;
        if (currPage >= MAX_DISPLAY_COUNT) {
            increment = MAX_DISPLAY_COUNT - currPage - 1;
        }
        LayoutParams layoutParams = (LayoutParams) mNumberContentLayout.getLayoutParams();
        layoutParams.leftMargin = dip2px(mContext, increment * NUMBER_DISPLAY_WIDTH);
        mNumberContentLayout.setLayoutParams(layoutParams);
    }


    /**
     * 设置左箭头图案
     *
     * @param mLeftImageView
     */
    public void setmLeftImageView(ImageView mLeftImageView) {
        this.mLeftImageView = mLeftImageView;
    }

    /**
     * 设置右箭头图案
     *
     * @param mRightImageView
     */
    public void setmRightImageView(ImageView mRightImageView) {
        this.mRightImageView = mRightImageView;
    }

    /**
     * 设置选中背景图
     *
     * @param mSelectedDrawable
     */
    public void setmSelectedDrawable(int mSelectedDrawable) {
        this.mSelectedDrawable = mSelectedDrawable;
    }

    /**
     * 设置未选中背景图
     *
     * @param mUnSelectedDrawable
     */
    public void setmUnSelectedDrawable(int mUnSelectedDrawable) {
        this.mUnSelectedDrawable = mUnSelectedDrawable;
    }

    /**
     * 设置左上角勾勾提示图片提示资源
     *
     * @param mImgHint 图片资源
     */
    public void setmImgHintResource(int mImgHint) {
        this.mImgHint = mImgHint;
    }

    /**
     * 是否显示勾勾
     *
     * @param showHint 是否显示
     */
    public void setShowHint(boolean showHint) {
        isShowHint = showHint;
    }

    private int dip2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    @Override
    public void onClick(View v) {
        if (v == mLeftImageView) {
            mListener.selectedPage(mCurrPage - 1 < 0 ? 0 : mCurrPage - 1);
        } else {
            mListener.selectedPage(mCurrPage + 1 > mTextViewList.size() - 1 ? mTextViewList.size() - 1 : mCurrPage + 1);
        }
    }

    public interface PageControlListener {
        void selectedPage(int postion);
    }

}

MyTestFragment

package com.example.qxb_810.pagecontrollviewdemo;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;


public class MyTestFragment extends Fragment {
    @BindView(R.id.tv_content)
    TextView tvContent;
    Unbinder unbinder;

    public MyTestFragment() {
    }

    public static MyTestFragment newInstance(String param1) {
        MyTestFragment fragment = new MyTestFragment();
        Bundle args = new Bundle();
        args.putString("name", param1);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_my_test, container, false);
        ButterKnife.bind(this, view);
        unbinder = ButterKnife.bind(this, view);
        if (getArguments() != null) {
            tvContent.setText(getArguments().getString("name"));
        }
        return view;
    }


    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
    }
}

MyFragmentPagerAdapter : ViewPager Fragment适配器

package com.example.qxb_810.widgets;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import java.util.List;

/**
* create 2018/9/3 16:14
* desc PageAdapter
*/

public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
    private List<Fragment> fragments;

    public MyFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }
}

shape_base_control_blue

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#0990dd" />
    <corners
        android:bottomLeftRadius="25dp"
        android:bottomRightRadius="25dp"
        android:topLeftRadius="25dp"
        android:topRightRadius="25dp" />
</shape>

shape_page_control_white

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/white" />
    <corners
        android:bottomLeftRadius="25dp"
        android:bottomRightRadius="25dp"
        android:topLeftRadius="25dp"
        android:topRightRadius="25dp" />
</shape>

猜你喜欢

转载自blog.csdn.net/qq_36882793/article/details/82382806