自定义viewpager指示器

先上效果图:
这里写图片描述

看到这儿,有的人会说这个不是开源的ViewPagerIndictor嘛。是的,这种效果可以用ViewPagerIndictor。不过,用它实现这个效果要修改很多style,本人改完之后确实是眼花了,所以在这里给大家提供一个自定义的效果。
布局:

整体的布局是这样的:
viewpager里两个frgment
头部文字是两个TextView,指示器的白线是一个View

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:background="#F4F4F4"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:fitsSystemWindows="true"
              android:orientation="vertical">

    <!--<com.viewpagerindicator.TabPageIndicator-->
        <!--android:id="@+id/indicator"-->
        <!--android:layout_width="match_parent"-->
        <!--android:layout_height="56dp"/>-->
    <include layout="@layout/community_top"/>

    <com.upc.learnmooc.view.CommunityViewPager
        android:id="@+id/vp_content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>
</LinearLayout>

community_top.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/rl_top"
                android:layout_width="match_parent"
                android:layout_height="56dp"
                android:background="@color/top_bar_color">

    <TextView
        android:id="@+id/tv_article"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginLeft="5dp"
        android:layout_marginStart="5dp"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:text="文章"
        android:textColor="@color/title_word_color"
        android:textSize="20sp"/>

    <TextView
        android:id="@+id/tv_rank"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginLeft="5dp"
        android:layout_marginStart="5dp"
        android:layout_toEndOf="@+id/tv_article"
        android:layout_toRightOf="@+id/tv_article"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:text="排位"
        android:textColor="@color/title_word_color"
        android:textSize="20sp"/>

    <View
        android:id="@+id/v_indictor_line"
        android:layout_width="48dp"
        android:layout_height="3dp"
        android:layout_alignParentBottom="true"
        android:layout_marginLeft="19dp"
        android:layout_marginStart="19dp"
        android:background="#fff"/>

</RelativeLayout>

frgment的两个布局就不写上来了 大家可以根据自己的需要来写。

两个frgment:


public class ArticleFragment extends BaseFragment {

    @Override
    public View initViews() {

        View view = View.inflate(mActivity, R.layout.community_article_frgment,null);

        ViewUtils.inject(view);
        return view;
    }
}
public class RankingFragment extends BaseFragment {

    @Override
    public View initViews() {

        View view = View.inflate(mActivity, R.layout.community_ranking_frgment,null);

        ViewUtils.inject(view);
        return view;
    }
}

主代码:

public class CommunityFragment extends BaseFragment {

    @ViewInject(R.id.rl_top)
    private RelativeLayout rlTop;

    @ViewInject(R.id.vp_content)
    private ViewPager mViewPager;

    @ViewInject(R.id.tv_article)
    private TextView tvArticle;
    @ViewInject(R.id.tv_rank)
    private TextView tvRank;
    @ViewInject(R.id.v_indictor_line)
    private View vIndicvtorLine;

    private FragmentPagerAdapter mAdapter;

    private List<Fragment> mFragments;
    private int mWidth;
    //  private final static String[] titleArray = new String[]{"文章", "排位"};

    @Override
    public View initViews() {
        View view = View.inflate(mActivity, R.layout.community_fragment, null);
        //注入view和事件
        ViewUtils.inject(this, view);

        //初始化文章和排位两个frgment
        Fragment articlrFrgment = new ArticleFragment();
        Fragment rankingFragment = new RankingFragment();

        //初始化viewpager数据源
        mFragments = new ArrayList<>();
        mFragments.add(articlrFrgment);
        mFragments.add(rankingFragment);

        mAdapter = new FragmentPagerAdapter(getChildFragmentManager()) {

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

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

        // 获取视图树, 对layout结束事件进行监听
        rlTop.getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {

                    // 当layout执行结束后回调此方法
                    @Override
                    public void onGlobalLayout() {
                        System.out.println("layout 结束");
                        rlTop.getViewTreeObserver()
                                .removeGlobalOnLayoutListener(this);
                        mWidth = rlTop.getChildAt(1).getLeft()
                                - rlTop.getChildAt(0).getLeft();
                        System.out.println("textview 距离 is: " + mWidth);
                    }
                });
        mViewPager.setAdapter(mAdapter);
        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                int len = (int) (mWidth * positionOffset) + position
                        * mWidth + 30;
                RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) vIndicvtorLine
                        .getLayoutParams();// 获取当前横线的布局参数
                params.leftMargin = len;// 设置左边距

                vIndicvtorLine.setLayoutParams(params);// 重新给横线设置布局参数
            }

            @Override
            public void onPageSelected(int position) {
                if (position == 0) {
                    tvArticle.setTextColor(getResources().getColor(R.color.colorWhite));
                    tvRank.setTextColor(getResources().getColor(R.color.normal_community_word));
                } else if (position == 1) {
                    tvArticle.setTextColor(getResources().getColor(R.color.normal_community_word));
                    tvRank.setTextColor(getResources().getColor(R.color.colorWhite));
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        return view;
    }

    @Override
    public void initData() {
    }

    @OnClick(R.id.tv_article)
    public void Article(View view) {
        mViewPager.setCurrentItem(0);
        tvArticle.setTextColor(getResources().getColor(R.color.colorWhite));
        tvRank.setTextColor(getResources().getColor(R.color.normal_community_word));
    }

    @OnClick(R.id.tv_rank)
    public void Rank(View view) {
        mViewPager.setCurrentItem(1);
        tvArticle.setTextColor(getResources().getColor(R.color.normal_community_word));
        tvRank.setTextColor(getResources().getColor(R.color.colorWhite));
    }
}

public abstract class BaseFragment extends Fragment {
public Activity mActivity;//依附的Activity

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.mActivity = getActivity();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return initViews();
}

/**
 * 依附的activity创建完成  初始化页面数据
 */
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    initData();
}

//初始化页面数据 不必须
public void initData() {

}

//子类必须实现布局初始化
public abstract View initViews();

}

这里写代码片

这个是从项目中抽取出来的,整体是Frgment 然后其中嵌套了两个frgment。大家如果整体是Activity的话只要继承FrgmentActivity,
然后设置Adpater的时候

mAdapter = new FragmentPagerAdapter(getChildFragmentManager())

把getChildFragmentManager()换成getSupportFrgmentManager就好了。

好的 就这样。有问题的欢迎留言

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值