1、自定义viewIndicator,使它继承linearLayout
2、画三角形,计算三角形所在的位置
3、vIEwpage与tab之间产生联动。
分开一步步来说:
一、tab栏中自定义viewIndicator,主要代码为:
public class VIEwIndicator extends linearLayout { private TypedArray array; //画笔 private Paint mPaint; //三角形 private Path mPath; //三角形的宽和高 private int mTrianleWIDth; private int mTrianleHeight; private static final float RAdio_TRIANGLE_WIDTH=1/6F; //设置初始化的位置 private int mInitTranslationX; //设置偏移量 private int mTranslationX; private int mTabvisibleCount; //默认显示的数量为4 private static final int COUNT_DEFAulT_TAB = 4; private List<String> mTitles; //正常状态下的字体颜色 private static final int color_TEXT_norMAL=0x77FFFFFF; //正常状态下的字体颜色 private static final int color_TEXT_HIGH=0xFFFFFFFF; @OverrIDe protected voID onSizeChanged(int w, int h, int olDW, int oldh) { super.onSizeChanged(w, h, olDW, oldh); mTrianleWIDth= (int) (w/mTabvisibleCount*RAdio_TRIANGLE_WIDTH); mInitTranslationX=w/mTabvisibleCount/2-mTrianleWIDth/2; initTriangle(); }//初始化三角形 private voID initTriangle() { mTrianleHeight=mTrianleWIDth/2; mPath=new Path(); //首先是在原点的位置 mPath.moveto(0,0); //三角形的底边首先移动,x轴是x的宽度,y轴为0;(0,0)△(三角形宽度mTrianleWIDth,0) mPath.lineto(mTrianleWIDth,0); //再向左上方移动,如果为等腰三角形,Y轴方向的高度与mTrianleWIDth/2相等,y轴向下是正数 mPath.lineto(mTrianleWIDth/2,-mTrianleHeight); //闭合,形成三角形。 mPath.close(); } public VIEwIndicator(Context context) { this(context,null); } @OverrIDe protected voID dispatchDraw(Canvas canvas) { canvas.save(); canvas.translate(mInitTranslationX+mTranslationX,getHeight() +2); canvas.drawPath(mPath,mPaint); canvas.restore(); super.dispatchDraw(canvas); } public VIEwIndicator(Context context, AttributeSet attrs) { super(context, attrs); //获取自定义属性,可见Tab的数量 array=context.obtainStyledAttributes(attrs,R.styleable.VIEwIndicator); mTabvisibleCount=array.getInt(R.styleable.VIEwIndicator_visible_tab_count,COUNT_DEFAulT_TAB); if (mTabvisibleCount<0){ mTabvisibleCount=COUNT_DEFAulT_TAB; }array.recycle(); //初始化画笔 mPaint=new Paint(); mPaint.setAntiAlias(true); mPaint.setcolor(color.WHITE); mPaint.setStyle(Paint.Style.FILL); //设置圆角效果,不至于太尖锐 mPaint.setPathEffect(new CornerPathEffect(3)); }//当xml加载完后运行该方法 @OverrIDe protected voID onFinishInflate() { super.onFinishInflate(); //拿到子元素的个数 int cCount=getChildCount(); if (cCount==0){ return; } for (int i = 0; i <cCount ; i++) { VIEw vIEw=getChildAt(i); //获取参数,重新动态布局 linearLayout.LayoutParams lp= (LayoutParams) vIEw.getLayoutParams(); //如果设置了权重,此时将权重设置为0 lp.weight=0; //将宽度设置为平分。屏幕宽度除以可见数量 lp.wIDth=getScreenWIDth()/mTabvisibleCount; //设置参数 vIEw.setLayoutParams(lp); } }//获取屏幕宽度 private int getScreenWIDth() { WindowManager wm= (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); displayMetrics outMetrics=new displayMetrics(); wm.getDefaultdisplay().getMetrics(outMetrics); return outMetrics.wIDthPixels; }; /** * 指示器跟随着vIEwpager一起移动。 * @param position * @param offset */ public voID scoll(int position,float offset) { int tabwIDth=getWIDth()/mTabvisibleCount; mTranslationX= (int) (tabwIDth*(offset+position)); //容器移动,当tab处于移动的最后一个时,当可见tab不为1 if (mTabvisibleCount!=1) { if (position >= (mTabvisibleCount - 2) && offset > 0 && getChildCount() > mTabvisibleCount) { this.scrollTo((position - (mTabvisibleCount - 2)) * tabwIDth + (int) (tabwIDth * offset), 0); } }else { this.scrollTo((int)(tabwIDth*(position+offset)),0); } //三角形发生改变,需要重新绘制 invalIDate(); } public voID setTabItemTitles(List<String> Titles){ if (Titles!=null&&Titles.size()>0){ this.removeAllVIEws(); mTitles=Titles; for (String Title : Titles) { addVIEw(generateTexeVIEw(Title)); } } setItemOnclick(); }//根据Title创建Tab private VIEw generateTexeVIEw(String Title) { TextVIEw tv=new TextVIEw(getContext()); linearLayout.LayoutParams lp=new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT); lp.wIDth=getScreenWIDth()/mTabvisibleCount; tv.setText(Title); tv.setGravity(Gravity.CENTER); tv.setTextSize(TypedValue.COMPLEX_UNIT_SP,16); tv.setTextcolor(color.WHITE); tv.setLayoutParams(lp); return tv; } private VIEwPager vIEwPager; //设置可显示的tab数目。public voID setVisibleTabCount(int count){ mTabvisibleCount=count;} //简化activity中的代码 public voID setPageOnchangListen(VIEwPager vp, int pos){ vIEwPager=vp; //为vIEwpage设置监听器 vIEwPager.addOnPagechangelistener(new VIEwPager.OnPagechangelistener() { @OverrIDe public voID onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { //当页面发生滚动的时候,偏移量为tabwIDth*positionOffset(这是0-1的页面)+position*tabwIDth(第二个页面到第三个页面) scoll(position,positionOffset); //为Onpagerchangelistener中的方法设置 if(Listener!=null) { Listener.onPageScrolled(position, positionOffset, positionOffsetPixels); } } @OverrIDe public voID onPageSelected(int position) { if(Listener!=null) Listener.onPageSelected(position); highlightTextVIEw(position); } @OverrIDe public voID onPageScrollStateChanged(int state) { if(Listener!=null) Listener.onPageScrollStateChanged(state); } }); vIEwPager.setCurrentItem(pos); highlightTextVIEw(pos); } private OnPagechangelistener Listener; //设置vIEwpager的回调供选择者使用 public interface OnPagechangelistener{ voID onPageScrolled(int position, float positionOffset, int positionOffsetPixels); voID onPageSelected(int position); voID onPageScrollStateChanged(int state); } //设置一个方法供调用者使用 public voID setonpagechangelistener(OnPagechangelistener mListener){ this.Listener=mListener; } //重置颜色 public 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 highlightTextVIEw(int pos){ //重置颜色 resetTextVIEwcolor(); VIEw vIEw=getChildAt(pos); if (vIEw instanceof TextVIEw){ ((TextVIEw) vIEw).setTextcolor(color_TEXT_HIGH); } } //设置监听器 public voID setItemOnclick(){ for (int i = 0; i <getChildCount() ; i++) { final int j =i; VIEw vIEw =getChildAt(i); vIEw.setonClickListener(new OnClickListener() { @OverrIDe public voID onClick(VIEw v) { vIEwPager.setCurrentItem(j); } }); } }}
代码中都有注释,这里主要是想讲解下有关于画三角形:
图片比较粗糙,各位将就看下~毕竟不是专业美工出身。首先是设置三角形的起点,调用mpath.lineto()函数,移动坐标。需要注意的是Y轴向上是负,向下为正。最后闭合三角形。
//起点 mPath.moveto(0,0); //三角形的底边首先移动,x轴是x的宽度,y轴为0;(0,0)△(三角形宽度mTrianleWIDth,0) mPath.lineto(mTrianleWIDth,0); //再向左上方移动,如果为等腰三角形,Y轴方向的高度与mTrianleWIDth/2相等,y轴向下是正数 mPath.lineto(mTrianleWIDth/2,-mTrianleHeight); //闭合,形成三角形。 mPath.close();
在MainActivity中的调用:
public class MainActivity extends FragmentActivity { VIEwPager vIEwPager; VIEwIndicator vIEwIndicator; private List<String> mTitles= Arrays.asList("短信1","收藏2","推荐3","短信4","收藏5","推荐6","短信7","收藏8","推荐9"); private List<VpsimpleFragment> fragments=new ArrayList<VpsimpleFragment>(); //fragment的adapter private FragmentPagerAdapter mAdapter; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestwindowFeature(Window.FEATURE_NO_Title); setContentVIEw(R.layout.activity_main2);// ButterKnife.bind(this); initVIEw(); initDatas(); //先设置可显示的数量 vIEwIndicator.setVisibleTabCount(4); vIEwIndicator.setTabItemTitles(mTitles); vIEwPager.setAdapter(mAdapter);//在vIEwIndicator中设置监听,避免在 vIEwIndicator.setPageOnchangListen(vIEwPager,0); } private voID initVIEw() { vIEwPager= (VIEwPager) findVIEwByID(R.ID.vIEwpager); vIEwIndicator= (VIEwIndicator) findVIEwByID(R.ID.ID_indicator); } private voID initDatas() { for (String mTitle : mTitles) { fragments.add(VpsimpleFragment.newInstance(mTitle)); } mAdapter=new FragmentPagerAdapter(getSupportFragmentManager()) { @OverrIDe public Fragment getItem(int position) { return fragments.get(position); } @OverrIDe public int getCount() { return fragments.size(); } }; }
实现代码比较简单。就不一一阐述了。
关于VpsimpleFragment.java的代码如下:
private String mTitle; public static final String BUNDLE_title="Title"; @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; } //获取实例 public static VpsimpleFragment newInstance(String Title){ Bundle bundle=new Bundle(); bundle.putString(BUNDLE_Title,Title); VpsimpleFragment fragment=new VpsimpleFragment(); fragment.setArguments(bundle); return fragment; }
总结 以上是内存溢出为你收集整理的Android指示器。全部内容,希望文章能够帮你解决Android指示器。所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)