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<String> titles)
内部处理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 < coutns;i++)
{
View view = getChildAt(i);
LinearLayout.LayoutParams params = (LayoutParams)view.getLayoutParams();
params.weight = 0;
params.width = getScreenWidth() / mDefaultVisibleCounts;
view.setLayoutParams(params);
}
//设置监听
setItemClickListener();
//直线的宽度
mLineWidth = getScreenWidth() / mDefaultVisibleCounts;
}
@Override
protected void onSizeChanged(int width,int height,int oldWidth,int oldHeight)
{
super.onSizeChanged(width,height,oldWidth,oldHeight);
//创建三角形
createIndicatorTriangle();
}
@Override
protected void dispatchDraw(Canvas canvas)
{
canvas.save();
if(mDrawStyle == STYLE_LINE)
{
//绘制直线
canvas.drawLine(mMoveX,getHeight(),mMoveX + mLineWidth,getHeight(),mLinePaint);
}
if(mDrawStyle == STYLE_TRIANGLE)
{
//绘制三角形
canvas.translate(mStartX + mMoveX,getHeight());
canvas.drawPath(mTrianglePath,mTrianglePaint);
}
canvas.restore();
super.dispatchDraw(canvas);
}
/**
* 获取自定义的值
*
* @param attrs
*/
private void getCustomValue(Context context,AttributeSet attrs)
{
TypedArray attributes = context.obtainStyledAttributes(attrs,R.styleable.ChangeablePagerIndicator);
//获取默认显示的可见Tab的数量
mDefaultVisibleCounts = attributes.
getInt(R.styleable.ChangeablePagerIndicator_default_display_counts,DEFAULT_VISIBLE_COUNTS);
mDefaultVisibleCounts = Math.max(DEFAULT_VISIBLE_COUNTS,mDefaultVisibleCounts);
//高亮文本的颜色
mHighLightColor = attributes.getColor(R.styleable.ChangeablePagerIndicator_high_light_color,COLOR_TEXT_HIGHLIGHT);
//普通文本的颜色
mNormalTextColor = attributes.getColor(R.styleable.ChangeablePagerIndicator_normal_text_color,COLOR_TEXT_NORMAL);
//文本大小
mTextSize = attributes.getInt(R.styleable.ChangeablePagerIndicator_text_size,TAB_TEXT_SIZE);
//线的高度(strokeWidth)
mLineHeight = attributes.getInt(R.styleable.ChangeablePagerIndicator_graphics_height,LINE_HEIGHT);
//直线或者三角形的颜色
mGraphicsColor = attributes.getColor(R.styleable.ChangeablePagerIndicator_graphics_color,COLOR_GRAPHICS);
//绘制的类型
boolean drawStyle = attributes.getBoolean(R.styleable.ChangeablePagerIndicator_is_draw_line,true);
mDrawStyle = drawStyle ? STYLE_LINE : STYLE_TRIANGLE;
//直线的宽度
mLineWidth = getScreenWidth() / mDefaultVisibleCounts;
attributes.recycle();
}
/**
* 初始化三角形的画笔
*/
private void initTrianglePaint()
{
mTrianglePaint = new Paint();
mTrianglePaint.setAntiAlias(true);
//三角形的画笔颜色
mTrianglePaint.setColor(mGraphicsColor);
mTrianglePaint.setStyle(Paint.Style.FILL);
//绘制角时的弧度
mTrianglePaint.setPathEffect(new CornerPathEffect(2));
}
/**
* 初始化直线的画笔
*/
private void initLinePaint()
{
mLinePaint = new Paint(mTrianglePaint);
mLinePaint.setStrokeWidth(mLineHeight);
}
/**
* 创建指示器的三角形
*/
private void createIndicatorTriangle()
{
int tabWidth = getScreenWidth() / mDefaultVisibleCounts;
//三角形的宽度
mTriangleWidth = (int)(tabWidth * TRIANGLE_RADIO);
//初始位置时三角形的位置
mStartX = (tabWidth - mTriangleWidth) / 2;
//三角形的高度
mTriangleHeight = mTriangleWidth / 3;
//绘制三三角形路径
mTrianglePath = new Path();
mTrianglePath.moveTo(0,0);
mTrianglePath.lineTo(mTriangleWidth,0);
mTrianglePath.lineTo(mTriangleWidth / 2,- mTriangleHeight);
mTrianglePath.close();
}
/**
* 水平滚动
*
* @param position
* @param offset
*/
public void scroll(int position,float offset)
{
int tabWidth = getWidth() / mDefaultVisibleCounts;
//指示器移动的距离
mMoveX = (int)(tabWidth * (position + offset));
//移动Tab
if(position >= (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 < DEFAULT_VISIBLE_COUNTS)
mDefaultVisibleCounts = DEFAULT_VISIBLE_COUNTS;
//直线的宽度
mLineWidth = getScreenWidth() / mDefaultVisibleCounts;
}
/**
* 不用加载布局文件,代码生成
*
* @param titles
*/
public void setTabItems(List<String> 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 < getChildCount();i++)
{
//点击的位置
final int clickPosition = i;
View view = getChildAt(i);
if(view instanceof TextView)
{
view.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View view)
{
//ViewPager跳到对应的选中项
mViewPager.setCurrentItem(clickPosition);
}
});
}
}
}
/**
* 根据标题生成TextView
*
* @param title
* @return
*/
private View generateTitleView(String title)
{
TextView tv = new TextView(getContext());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
params.width = getScreenWidth() / mDefaultVisibleCounts;
tv.setGravity(Gravity.CENTER);
tv.setText(title);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP,mTextSize);
tv.setTextColor(mNormalTextColor);
tv.setLayoutParams(params);
return tv;
}
/**
* 设置高亮显示的文本
* 也就是当前选中的文本
*
* @param position
*/
private void setHighLightText(int position)
{
for(int i = 0;i < getChildCount();i++)
{
View view = getChildAt(i);
if(view instanceof TextView)
{
//高亮颜色
if(i == position)
((TextView)view).setTextColor(mHighLightColor);
//正常颜色
else
((TextView)view).setTextColor(mNormalTextColor);
}
}
}
/**
* 获取屏幕的宽度
*
* @return
*/
private int getScreenWidth()
{
WindowManager manager = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(metrics);
return metrics.widthPixels;
}
}
自定义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<SimpleFragment> mFragments;
public TopViewPagerAdapter(FragmentManager fm,Context context,List<SimpleFragment> 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<String> mTitles = Arrays.asList("国际","军事","社会","娱乐","体育","财经","历史","本地","中国");
private List<SimpleFragment> 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)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--默认的显示的Tab数量-->
<attr name="default_display_counts" format="integer"/>
<!--高亮文本的颜色-->
<attr name="high_light_color" format="color"/>
<!--正常文本的颜色-->
<attr name="normal_text_color" format="color"/>
<!--图形的颜色-->
<attr name="graphics_color" format="color"/>
<!--文本的大小-->
<attr name="text_size" format="integer"/>
<!--图形的高度-->
<attr name="graphics_height" format="integer"/>
<!--图形的类型-->
<attr name="is_draw_line" format="boolean"/>
<declare-styleable name="ChangeablePagerIndicator">
<!--默认的显示的Tab数量-->
<attr name="default_display_counts"/>
<!--高亮文本的颜色-->
<attr name="high_light_color"/>
<!--正常文本的颜色-->
<attr name="normal_text_color"/>
<!--图形的颜色-->
<attr name="graphics_color"/>
<!--文本的大小-->
<attr name="text_size"/>
<!--图形的高度-->
<attr name="graphics_height"/>
<!--图形的类型-->
<attr name="is_draw_line"/>
</declare-styleable>
</resources>
颜色值文件(colors.xml)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#009688</color>
<color name="colorPrimaryDark">#06776d</color>
<color name="colorAccent">#FF4081</color>
</resources>
代码地址:http://114.215.186.20/14551100130/toptab.zip
参考资料:
1.http://blog.csdn.net/scorplopan/article/details/6302827 ondraw() 和dispatchdraw()的区别
热门评论
请问下代码地址不能载可以分享下代码给我参考吗谢谢