Android指示器。

Android指示器。,第1张

概述主要实现的思路:1、自定义viewIndicator,使它继承LinearLayout2、画三角形,计算三角形所在的位置3、viewpage与tab之间产生联动。分开一步步来说:一、tab栏中自定义viewIndicator,主要代码为:publicclassViewIndicatorextendsLinearLayout{privateTypedArrayarr 主要实现的思路:

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指示器。所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1004333.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存