利用ViewPagerIndicator制作带指示器的顶部导航

来源:互联网 发布:java和net哪个比较好 编辑:程序博客网 时间:2024/05/29 13:27

今日在网上找了一个带有不错指示器效果的ViewPager,稍微做了改动,拿来与大家分享一下,也是借助网上的ViewPagerIndicator这个框架来做的,废话少说,上代码:
一致惯例,先上布局文件:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"                android:paddingLeft="@dimen/activity_horizontal_margin"                android:paddingRight="@dimen/activity_horizontal_margin"                android:paddingTop="@dimen/activity_vertical_margin"                tools:context=".MainActivity" >    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/app_name" /></RelativeLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    xmlns:li="http://schemas.android.com/apk/res/com.example.viewpager"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#ffffffff"    android:orientation="vertical" >    <com.example.viewpager.ViewPagerIndicator        android:id="@+id/id_indicator"        android:layout_width="match_parent"        android:layout_height="45dp"        android:background="@color/colorAccent"        android:orientation="horizontal"        li:item_count="3" >        <TextView            android:layout_width="0dp"            android:layout_height="fill_parent"            android:layout_weight="1"            android:gravity="center"            android:text="短信1"            android:textColor="#CCFFFFFF"            android:textSize="16sp" />        <TextView            android:layout_width="0dp"            android:layout_height="fill_parent"            android:layout_weight="1"            android:gravity="center"            android:text="收藏2"            android:textColor="#CCFFFFFF"            android:textSize="16sp" />        <TextView            android:layout_width="0dp"            android:layout_height="fill_parent"            android:layout_weight="1"            android:gravity="center"            android:text="推荐3"            android:textColor="#CCFFFFFF"            android:textSize="16sp" />    </com.example.viewpager.ViewPagerIndicator>    <android.support.v4.view.ViewPager        android:id="@+id/id_vp"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1" >    </android.support.v4.view.ViewPager></LinearLayout>

ViewPagerIndicator的代码:

package com.example.viewpager;import java.util.List;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.CornerPathEffect;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.Path;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.util.Log;import android.util.TypedValue;import android.view.Gravity;import android.view.View;import android.view.WindowManager;import android.widget.LinearLayout;import android.widget.TextView;/** * http://blog.csdn.net/lmj623565791/article/details/42160391 * @author zhy * */public class ViewPagerIndicator extends LinearLayout {    /**     * 绘制三角形的画笔     */    private Paint mPaint;    /**     * path构成一个三角形     */    private Path mPath;    /**     * 三角形的宽度     */    private int mTriangleWidth;    /**     * 三角形的高度     */    private int mTriangleHeight;    /**     * 三角形的宽度为单个Tab的1/6     */    private static final float RADIO_TRIANGEL = 1.0f / 6;    /**     * 三角形的最大宽度     */    private final int DIMENSION_TRIANGEL_WIDTH = (int) (getScreenWidth() / 3 * RADIO_TRIANGEL);    /**     * 初始时,三角形指示器的偏移量     */    private int mInitTranslationX;    /**     * 手指滑动时的偏移量     */    private float mTranslationX;    /**     * 默认的Tab数量     */    private static final int COUNT_DEFAULT_TAB = 4;    /**     * tab数量     */    private int mTabVisibleCount = COUNT_DEFAULT_TAB;    /**     * tab上的内容     */    private List<String> mTabTitles;    /**     * 与之绑定的ViewPager     */    public ViewPager mViewPager;    /**     * 标题正常时的颜色     */    private static final int COLOR_TEXT_NORMAL = 0x77FFFFFF;    /**     * 标题选中时的颜色     */    private static final int COLOR_TEXT_HIGHLIGHTCOLOR = 0xFFFFFFFF;    public ViewPagerIndicator(Context context)    {        this(context, null);    }    public ViewPagerIndicator(Context context, AttributeSet attrs)    {        super(context, attrs);        // 获得自定义属性,tab的数量        TypedArray a = context.obtainStyledAttributes(attrs,                R.styleable.ViewPagerIndicator);        mTabVisibleCount = a.getInt(R.styleable.ViewPagerIndicator_item_count,                COUNT_DEFAULT_TAB);        if (mTabVisibleCount < 0)            mTabVisibleCount = COUNT_DEFAULT_TAB;        a.recycle();        // 初始化画笔        mPaint = new Paint();        mPaint.setAntiAlias(true);        mPaint.setColor(Color.parseColor("#ffffffff"));        mPaint.setStyle(Style.FILL);        mPaint.setPathEffect(new CornerPathEffect(3));    }    /**     * 绘制指示器     */    @Override    protected void dispatchDraw(Canvas canvas)    {        canvas.save();        // 画笔平移到正确的位置        canvas.translate(mInitTranslationX + mTranslationX, getHeight() + 1);        canvas.drawPath(mPath, mPaint);        canvas.restore();        super.dispatchDraw(canvas);    }    /**     * 初始化三角形的宽度     */    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh)    {        super.onSizeChanged(w, h, oldw, oldh);        mTriangleWidth = (int) (w / mTabVisibleCount * RADIO_TRIANGEL);// 1/6 of                                                                        // width        mTriangleWidth = Math.min(DIMENSION_TRIANGEL_WIDTH, mTriangleWidth);        // 初始化三角形        initTriangle();        // 初始时的偏移量        mInitTranslationX = getWidth() / mTabVisibleCount / 2 - mTriangleWidth                / 2;    }    /**     * 设置可见的tab的数量     *      * @param count     */    public void setVisibleTabCount(int count)    {        this.mTabVisibleCount = count;    }    /**     * 设置tab的标题内容 可选,可以自己在布局文件中写死     *      * @param datas     */    public void setTabItemTitles(List<String> datas)    {        // 如果传入的list有值,则移除布局文件中设置的view        if (datas != null && datas.size() > 0)        {            this.removeAllViews();            this.mTabTitles = datas;            for (String title : mTabTitles)            {                // 添加view                addView(generateTextView(title));            }            // 设置item的click事件            setItemClickEvent();        }    }    /**     * 对外的ViewPager的回调接口     *      * @author zhy     *      */    public interface PageChangeListener    {        public void onPageScrolled(int position, float positionOffset,                                   int positionOffsetPixels);        public void onPageSelected(int position);        public void onPageScrollStateChanged(int state);    }    // 对外的ViewPager的回调接口    private PageChangeListener onPageChangeListener;    // 对外的ViewPager的回调接口的设置    public void setOnPageChangeListener(PageChangeListener pageChangeListener)    {        this.onPageChangeListener = pageChangeListener;    }    // 设置关联的ViewPager    public void setViewPager(ViewPager mViewPager, int pos)    {        this.mViewPager = mViewPager;        mViewPager.setOnPageChangeListener(new OnPageChangeListener()        {            @Override            public void onPageSelected(int position)            {                // 设置字体颜色高亮                resetTextViewColor();                highLightTextView(position);                // 回调                if (onPageChangeListener != null)                {                    onPageChangeListener.onPageSelected(position);                }            }            @Override            public void onPageScrolled(int position, float positionOffset,                    int positionOffsetPixels)            {                // 滚动                scroll(position, positionOffset);                // 回调                if (onPageChangeListener != null)                {                    onPageChangeListener.onPageScrolled(position,                            positionOffset, positionOffsetPixels);                }            }            @Override            public void onPageScrollStateChanged(int state)            {                // 回调                if (onPageChangeListener != null)                {                    onPageChangeListener.onPageScrollStateChanged(state);                }            }        });        // 设置当前页        mViewPager.setCurrentItem(pos);        // 高亮        highLightTextView(pos);    }    /**     * 高亮文本     *      * @param position     */    protected void highLightTextView(int position)    {        View view = getChildAt(position);        if (view instanceof TextView)        {            ((TextView) view).setTextColor(COLOR_TEXT_HIGHLIGHTCOLOR);        }    }    /**     * 重置文本颜色     */    private void resetTextViewColor()    {        for (int i = 0; i < getChildCount(); i++)        {            View view = getChildAt(i);            if (view instanceof TextView)            {                ((TextView) view).setTextColor(COLOR_TEXT_NORMAL);            }        }    }    /**     * 设置点击事件     */    public void setItemClickEvent()    {        int cCount = getChildCount();        for (int i = 0; i < cCount; i++)        {            final int j = i;            View view = getChildAt(i);            view.setOnClickListener(new OnClickListener()            {                @Override                public void onClick(View v)                {                    mViewPager.setCurrentItem(j);                }            });        }    }    /**     * 根据标题生成我们的TextView     *      * @param text     * @return     */    private TextView generateTextView(String text)    {        TextView tv = new TextView(getContext());        LayoutParams lp = new LayoutParams(                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);        lp.width = getScreenWidth() / mTabVisibleCount;        tv.setGravity(Gravity.CENTER);        tv.setTextColor(COLOR_TEXT_NORMAL);        tv.setText(text);        tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);        tv.setLayoutParams(lp);        return tv;    }    /**     * 初始化三角形指示器     */    private void initTriangle()    {        mPath = new Path();        mTriangleHeight = (int) (mTriangleWidth / 2 / Math.sqrt(2));        mPath.moveTo(0, 0);        mPath.lineTo(mTriangleWidth, 0);        mPath.lineTo(mTriangleWidth / 2, -mTriangleHeight);        mPath.close();    }    /**     * 指示器跟随手指滚动,以及容器滚动     *      * @param position     * @param offset     */    public void scroll(int position, float offset)    {        /**         * <pre>         *  0-1:position=0 ;1-0:postion=0;         * </pre>         */        // 不断改变偏移量,invalidate        mTranslationX = getWidth() / mTabVisibleCount * (position + offset);        int tabWidth = getScreenWidth() / mTabVisibleCount;        // 容器滚动,当移动到倒数最后一个的时候,开始滚动        if (offset > 0 && position >= (mTabVisibleCount - 2)                && getChildCount() > mTabVisibleCount)        {            if (mTabVisibleCount != 1)            {                this.scrollTo((position - (mTabVisibleCount - 2)) * tabWidth                        + (int) (tabWidth * offset), 0);            } else            // 为count为1时 的特殊处理            {                this.scrollTo(                        position * tabWidth + (int) (tabWidth * offset), 0);            }        }        invalidate();    }    /**     * 设置布局中view的一些必要属性;如果设置了setTabTitles,布局中view则无效     */    @Override    protected void onFinishInflate()    {        Log.e("TAG", "onFinishInflate");        super.onFinishInflate();        int cCount = getChildCount();        if (cCount == 0)            return;        for (int i = 0; i < cCount; i++)        {            View view = getChildAt(i);            LayoutParams lp = (LayoutParams) view                    .getLayoutParams();            lp.weight = 0;            lp.width = getScreenWidth() / mTabVisibleCount;            view.setLayoutParams(lp);        }        // 设置点击事件        setItemClickEvent();    }    /**     * 获得屏幕的宽度     *      * @return     */    public int getScreenWidth()    {        WindowManager wm = (WindowManager) getContext().getSystemService(                Context.WINDOW_SERVICE);        DisplayMetrics outMetrics = new DisplayMetrics();        wm.getDefaultDisplay().getMetrics(outMetrics);        return outMetrics.widthPixels;    }}

Activity:

package com.example.viewpager;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.view.ViewPager;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.Window;import java.util.ArrayList;import java.util.Arrays;import java.util.List;public class MainActivity extends AppCompatActivity {    private List<Fragment> mTabContents = new ArrayList<>();    private FragmentPagerAdapter mAdapter;    private ViewPager mViewPager;    private List<String> mDatas = Arrays.asList("短信1", "短信2", "短信3");    private ViewPagerIndicator mIndicator;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.vp_indicator);        initView();        initDatas();        //设置Tab上的标题        mIndicator.setTabItemTitles(mDatas);        mViewPager.setAdapter(mAdapter);        //设置关联的ViewPager        mIndicator.setViewPager(mViewPager, 0);    }    private void initView() {        mViewPager = (ViewPager) findViewById(R.id.id_vp);        mIndicator = (ViewPagerIndicator) findViewById(R.id.id_indicator);    }    private void initDatas() {       /* for (String data : mDatas) {            VpSimpleFragment fragment = VpSimpleFragment.newInstance(data);            mTabContents.add(fragment);        }*/        //利用回调关联上三个fragment        VpSimpleFragment fragment = VpSimpleFragment.newInstance();        mTabContents.add(fragment);        BlankFragment fragment1=BlankFragment.newInstance();        mTabContents.add(fragment1);        lankFragment fragment2=lankFragment.newInstance();        mTabContents.add(fragment2);        mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {            @Override            public int getCount() {                return mTabContents.size();            }            @Override            public Fragment getItem(int position) {                return mTabContents.get(position);            }        };    }}

最后就是三个Fragment:

public class BlankFragment extends Fragment {    public BlankFragment() {        // Required empty public constructor    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        // Inflate the layout for this fragment        return inflater.inflate(R.layout.fragment_blank, container, false);    }    public static BlankFragment newInstance() {        BlankFragment fragment = new BlankFragment();        return fragment;    }}

三个写法都一样,就只写一个了。
效果图如下:
这里写图片描述

demo下载地址:http://download.csdn.net/detail/kuaizilanqiu/9601316

1 0
原创粉丝点击