2016-11-13 第一篇 ViewPagerIndicator
根据鸿洋的视频编写,然后自己添加了可以滑动的图形方式,直线或者三角形。还添加了可以在xml中自定义样式的功能。
最后效果演示图

ChangeablePagerIndicator类(顶部的指示器类)
重写父类主要的方法:
1.dispatchDraw(Canvas canvas) 绘制直线或者三角形
2.onFinishInflate() xml文件加载完成之后调用此放过,在xml中设置item时,在此方法重新设置item的宽度
Tab item移动的方法:
1.scroll(int position,float offset)
代码生成Items的方法
1.setTabItems(List
内部处理ViewPager的滑动
1.设置ViewPager :setViewPager(ViewPager viewPager,int currentPos)
2.设置监听事件(这里的IndicatorListener是实现ViewPager.OnPageChangeListener接口)
点击Item跳转ViewPager
1.setItemClickListener()
xml中自定义的属性值

全部代码
指示器类代码(ChangeablePagerIndicator.java)
package jfsl.view.toptab.view;
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.Path;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.List;
import jfsl.view.toptab.R;
import jfsl.view.toptab.listener.IndicatorListener;
/**
* 顶部Tab的导航区域
* 固定的顶部Indicator
*
* @version 1.0
* @aduthor JFSL
* @date 2016/11/12
* @date 2016-11-13 15:08 完成
*/
public class ChangeablePagerIndicator extends LinearLayout
{
//默认的高亮文本颜色:白色
public static final int COLOR_TEXT_HIGHLIGHT = Color.parseColor("#FFFFFFFF");
//默认的正常文本颜色:灰色
public static final int COLOR_TEXT_NORMAL = Color.parseColor("#77FFFFFF");
//默认绘制图形的颜色:白色
public static final int COLOR_GRAPHICS = Color.parseColor("#FFFFFFFF");
//默认Tab的文本大小 16sp
public static final int TAB_TEXT_SIZE = 16;
//直线的高度 10dp
public static final int LINE_HEIGHT = 10;
//最小的显示Tab的数量
public static final int DEFAULT_VISIBLE_COUNTS = 3;
//绘制的类型:1.直线 2.三角形
public static final int STYLE_LINE = 100;
public static final int STYLE_TRIANGLE = 200;
//三角形的比例
public static final float TRIANGLE_RADIO = 1 / 6F;
//绘制三角形的画笔
private Paint mTrianglePaint;
//绘制三角形的路径
private Path mTrianglePath;
//三角形的宽
private int mTriangleWidth;
//三角形的高
private int mTriangleHeight;
//绘制直线的画笔
private Paint mLinePaint;
//线的宽度
private int mLineWidth;
//初始位置时三角形的位置
private int mStartX;
//移动时三角形的位置
private int mMoveX;
//绘制的类型
private int mDrawStyle = STYLE_LINE;
//默认显示的tab item数量
private int mDefaultVisibleCounts;
//高亮文本的颜色
private int mHighLightColor;
//普通文本的颜色
private int mNormalTextColor;
//文本大小
private int mTextSize;
//线的高度(strokeWidth)
private int mLineHeight;
//直线或者三角形的颜色
private int mGraphicsColor;
public ChangeablePagerIndicator(Context context)
{
this(context,null);
}
public ChangeablePagerIndicator(Context context,AttributeSet attrs)
{
super(context,attrs);
//获取自定义的值
getCustomValue(context,attrs);
//初始化三角形的画笔
initTrianglePaint();
//初始化直线的画笔
initLinePaint();
}
/**
* 加载完XML时,调用此方法
*/
@Override
protected void onFinishInflate()
{
super.onFinishInflate();
int coutns = getChildCount();
if(coutns == 0)
return;
for(int i = 0;i = (mDefaultVisibleCounts - 2) && offset > 0
&& getChildCount() > mDefaultVisibleCounts
&& position != getChildCount() - 2)
{
if(mDefaultVisibleCounts != 1)
{
int scrollX = (position - (mDefaultVisibleCounts - 2)) * tabWidth
+ (int)(tabWidth * offset);
this.scrollTo(scrollX,0);
} else
{
this.scrollTo((position * tabWidth
+ (int)(tabWidth * offset)),0);
}
}
//重新绘制
invalidate();
}
/**
* 设置绘制的类型
* 1.STYLE_LINE 直线
* 2.STYLE_TRIANGLE 三角形
*/
public void setDrawStyle(int style)
{
mDrawStyle = style;
invalidate();
}
public void setDefaultVisibleCounts(int counts)
{
mDefaultVisibleCounts = counts;
if(counts titles)
{
if(titles == null)
return;
//首先移除所有的View
this.removeAllViews();
//根据标题生成TextView
for(String title : titles)
{
this.addView(generateTitleView(title));
}
//设置监听
setItemClickListener();
}
/**
* 设置ViewPager
*
* @param viewPager
* @param currentPos 当前选的位置
*/
private ViewPager mViewPager;
public void setViewPager(ViewPager viewPager,int currentPos)
{
mViewPager = viewPager;
viewPager.addOnPageChangeListener(mListener);
//设置当前选中项
viewPager.setCurrentItem(currentPos);
}
/**
* ViewPager监听
*/
private IndicatorListener mListener = new IndicatorListener()
{
@Override
public void scrollChanged(int position,float offset)
{
//进行Tab滚动
scroll(position,offset);
}
@Override
public void selected(int position)
{
//设置高亮文本,当前ViewPager与Tab一一对应
setHighLightText(position);
}
};
/**
* Tab Item的点击监听
*/
private void setItemClickListener()
{
for(int i = 0;i 自定义ViewPager监听类(IndicatorListener.java)
package jfsl.view.toptab.listener;
import android.support.v4.view.ViewPager;
/**
* @version 1.0
* @aduthor JFSL
* @date 2016/11/13 0013
*/
public abstract class IndicatorListener implements ViewPager.OnPageChangeListener
{
@Override
public void onPageScrolled(int position,float positionOffset,int positionOffsetPixels)
{
scrollChanged(position,positionOffset);
}
@Override
public void onPageSelected(int position)
{
selected(position);
}
@Override
public void onPageScrollStateChanged(int state)
{
}
/**
* ViewPager滑动
* @param position
* @param offset
*/
public abstract void scrollChanged(int position,float offset);
/**
* 选择当前页
* @param position
*/
public abstract void selected(int position);
}
ViewPager指示器类(TopViewPagerAdapter.java)
package jfsl.view.toptab.adapter;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import java.util.List;
import jfsl.view.toptab.fragment.SimpleFragment;
/**
* @version 1.0
* @aduthor JFSL
* @date 2016/11/12 0012
*/
public class TopViewPagerAdapter extends FragmentPagerAdapter
{
private Context mContext;
private List mFragments;
public TopViewPagerAdapter(FragmentManager fm,Context context,List fragments)
{
super(fm);
mContext = context;
mFragments = fragments;
}
@Override
public Fragment getItem(int position)
{
return mFragments.get(position);
}
@Override
public int getCount()
{
return mFragments.size();
}
}
测试用的Fragment(SimpleFragment.java)
package jfsl.view.toptab.fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**测试用的Fragment
* @version 1.0
* @aduthor JFSL
* @date 2016/11/12 0012
*/
public class SimpleFragment extends Fragment
{
public static final String BUNDLE_TITLE = "title";
private String mTitle;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState)
{
Bundle bundle = getArguments();
if(bundle != null)
mTitle = bundle.getString(BUNDLE_TITLE);
TextView textView = new TextView(getActivity());
textView.setText(mTitle);
textView.setGravity(Gravity.CENTER);
return textView;
}
/**
* 获取实例
* @param title
* @return
*/
public static SimpleFragment newInstance(String title)
{
Bundle bundle = new Bundle();
bundle.putString(BUNDLE_TITLE,title);
SimpleFragment fragment = new SimpleFragment();
fragment.setArguments(bundle);
return fragment;
}
}
测试的Activity(ChangeableMainActivity .java)
package jfsl.view.toptab;
import android.os.Bundle;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.Window;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import jfsl.view.toptab.adapter.TopViewPagerAdapter;
import jfsl.view.toptab.fragment.SimpleFragment;
import jfsl.view.toptab.view.ChangeablePagerIndicator;
/**
* 测试自定义View的效果
*/
public class ChangeableMainActivity extends AppCompatActivity
{
private ViewPager mViewPager;
private ChangeablePagerIndicator mIndicator;
private List mTitles = Arrays.asList("国际","军事","社会","娱乐","体育","财经","历史","本地","中国");
private List mFragments = new ArrayList();
private FragmentPagerAdapter mPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main_changeable2);
initViews();
initDatas();
initEvent();
}
private void initEvent()
{
}
private void initDatas()
{
for(String title : mTitles)
{
mFragments.add(SimpleFragment.newInstance(title));
}
mPagerAdapter = new TopViewPagerAdapter(getSupportFragmentManager(),this,mFragments);
mViewPager.setAdapter(mPagerAdapter);
// mIndicator.setDefaultVisibleCounts(3);
//设置绘制的类型
// mIndicator.setDrawStyle(ChangeablePagerIndicator.STYLE_TRIANGLE);
//注意:其他设置要放在这个之前
mIndicator.setTabItems(mTitles);
mIndicator.setViewPager(mViewPager,1);
}
private void initViews()
{
mIndicator = (ChangeablePagerIndicator)findViewById(R.id.id_pager_indicator);
mViewPager = (ViewPager)findViewById(R.id.id_viewpager);
}
}
自定义属性文件(indicator_attrs.xml)
<!--默认的显示的Tab数量--> <!--高亮文本的颜色--> <!--正常文本的颜色--> <!--图形的颜色--> <!--文本的大小--> <!--图形的高度--> <!--图形的类型--><!--默认的显示的Tab数量--> <!--高亮文本的颜色--> <!--正常文本的颜色--> <!--图形的颜色--> <!--文本的大小--> <!--图形的高度--> <!--图形的类型--> 颜色值文件(colors.xml)
#009688 #06776d #FF4081 代码地址:http://114.215.186.20/14551100130/toptab.zip
参考资料:
1.http://blog.csdn.net/scorplopan/article/details/6302827 ondraw() 和dispatchdraw()的区别
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/813/viewspace-2798354/ ,如需转载,请注明出处,否则将追究法律责任。