Android ViewPagerインジケータ

7834 ワード

多くの一般的なappにはインジケータが使われていますが、appの上部にはインジケータがありますが、インジケータの効果はどうすればいいのでしょうか.手順は、1、レイアウトの構築です.あなたのインジケータはどんな顔をしているべきですか.インタフェースのどこにあるべきですか.何ページあるべきですか.つまり、tabタブがいくつありますか.スライドに従うものは三角形ですか、鉄棒ですか.2、カスタムコントロール.カスタムコントロールを使わなくてもインジケータの効果が得られるようですが、複数のコントロールを個別に制御する必要があります.tabの内容はTextView、外層のLinearLayoutなどです.どのように制御すればいいですか.スライド追従の効果は誰に描くつもりですか?これらはすべて現実的な問題だ.しかし、カスタムコントロールは異なり、やりたいことをやり、描きたいことを描き、上記の複数のコントロールをカスタムコントロールに配置し、コントロールとして直接制御することができます.このような操作は爽やかです.3、UIを描きます.インジケータはカスタムコントロールを採用しています.そのため、インジケータのtab部分はカスタムコントロールを使用しています.それから、インジケータの本体(つまりView Pager)はv 4パッケージのView Pagerコントロールを直接使用すればいいです.4、ページングページを設計する.ここで言うページングページは1つ1つのFragmentで、インジケータが異なるインタフェースの内容を切り替えるのはずっとActivityを切り替えているのではなく、1つのActivityの中で絶えずページを変えているのです.例えば、1つのActivityは1冊の本で、各Fragmentは1ページ1ページの紙で、どのようにページをめくっても、この本の中にあります.Fragmentの数はtabの数に対応し、Fragmentが提示する内容は自分で定義し、Activityと同じようにレイアウトファイルを作成し、表示したい内容を入れることができます.以上の4歩を歩き終わったらViewPagerは動くはずです.5、スライド追従のマーク.これは完全に自分で描いたもので、appで一番よく見られるのは三角形と鉄棒で、他は自分で描きましょう.これは、カスタムペイントの内容に関連します.実は順番が分かっても難しくはありません.まずコンストラクション関数でブラシを初期化する、適切な場所にPathクラスオブジェクトであるパスを作成し、mPathを通過する.moveTo(x,y)パスの始点を(x,y)に移動し、mPath..lineTo(a,b)は点(x,y)から(a,b)に直接線をつなぎ、パスを描き終えた後、書き換えたdispatchDrawメソッドでキャンバスを調整しdrawPathメソッドでパスを描きます.6、スライド追従.ViewPagerページをスライドしてスライドをマークに従って同期して動かしますか?この中の原理は実は簡単で、私たちはキャンバスにスライド追従マークを描いたのではないでしょうか.キャンバスを平行に移動するだけで、表示が移動するのではないでしょうか.ページをめくると同時にキャンバスをパンすると動きが実現します.7、インジケータtab連動.私たちのtabが1つのインタフェースで表示できる個数を超えた場合(つまり、あなたは10個のtabを持っていますが、一度に3個のtabしか表示できません)、各tabがカスタムコントロールのサブコントロールTextViewであることを知っています.10個を決めた場合、デフォルトの効果は10回に1つのインタフェースに表示されます.これは私たちの理想的な効果ではありません.ここで、各TextViewの幅はカスタムコントロールクラスでパラメータを変更し、画面幅を3で割って(一度に3つのtabを表示したいと仮定します)、各tabの幅が画面の1/3を占めていることを決めます.超えた部分は自然に表示されません.8、tabをクリックしてpageページを切り替えます.これは簡単で、すべてのTextViewにクリックイベントをループするだけでいいです.次に、クリック時間のコールバック関数でViewPagerのsetCurrentItem(position)を呼び出し、モータと同時に対応するpagerページに切り替えます.そうしないと、通常のクリックイベントにすぎません.9、tab文字がハイライトされています.簡単です.その前に、効果に影響を与えないように、すべてのTextViewを取得し、フォントの色をすべて上書きする必要があります.次にクリックしたTextViewはループによってクリックイベントを設定するので,ループ変数iによって現在クリックしているtabのインデックスを決定することができ,各ループでfinal int j=iを使用し,クリックコールバックでjを使用して論理を行うだけでよい.jを手に入れると対応するTextViewを手に入れることができるのではないでしょうかgetChildAt(j)を通じて、フォントを設定すれば終わりです.
以上がViewPagerの基本的な使用手順で、次にコードを書きます.
    



MainActivity.java  

//        FragmentPagerAdapter,         ViewPager   
   pagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int position) {
    //arrayList         Fragment    
                return arrayList.get(position);
            }

            @Override
            public int getCount() {
                return arrayList.size();
            }
   tab  ,   viewpager      

public class ViewPagerIndicator extends LinearLayout {

    private Paint mPaint;
    private Path mPath;
    private int mTriangleWidth;
    private int mTriangleHeight;

    private static final float RADIO = 1/6F;
    //            
    private final int DIMENSION_TRIANGLE_MAX = (int)(getScreenWidth() / 3 * RADIO);
    private int mInitTranslationX;      //    
    private int mTranslationX;          //      

    private int mTabVisibleCount;

    private static final int COUNT_DEFAULT_TAB = 4;

    public ViewPagerIndicator(Context context) {
        this(context,null);
    }

    public ViewPagerIndicator(Context context,AttributeSet attrs) {
        super(context, attrs);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.WHITE);
        mPaint.setPathEffect(new CornerPathEffect(5));  //          ,           

        TypedArray typeArray = context.obtainStyledAttributes(attrs,R.styleable.ViewPagerIndicator);

        //                visible_tab_count  ,                          
        mTabVisibleCount = typeArray.getInt(R.styleable.ViewPagerIndicator_visible_tab_count,COUNT_DEFAULT_TAB);

        if(mTabVisibleCount < 0){
            mTabVisibleCount = COUNT_DEFAULT_TAB;
        }
        typeArray.recycle();
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.save();

        canvas.translate(mInitTranslationX + mTranslationX,getHeight());
        canvas.drawPath(mPath,mPaint);
        canvas.restore();
        super.dispatchDraw(canvas);

    }

    /**
     *              
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        int cCount = getChildCount();   //           

        if(cCount == 0){
            return ;
        }
        for(int i = 0;i= mTabVisibleCount - 2 && getChildCount() > mTabVisibleCount && offset > 0){
            if(mTabVisibleCount != 1){
                this.scrollTo((position - (mTabVisibleCount - 2)) * tabWidth + (int)(tabWidth * offset),0);
            }else{
                this.scrollTo((int)(tabWidth * position + tabWidth * offset),0);
            }

        }
        /**
         *         ,      dispatchDraw  ,  ,      ,              
         */
        invalidate();
    }


    /**
     *              ,             
     * @param w        
     * @param h        
     * @param oldw             
     * @param oldh             
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        /**
         *         
         *    min                             
         */
        mTriangleWidth = (int)( w / mTabVisibleCount * RADIO);
        mTriangleWidth = Math.min(mTriangleWidth,DIMENSION_TRIANGLE_MAX);

        /**
         *     ,       (          )   tab     ,        
         */
        mInitTranslationX = w / mTabVisibleCount / 2 - mTriangleWidth / 2;

        initTriangle();
    }
    //      
    public void initTriangle(){
        mPath = new Path();
        /**
         *            
         */
        mPath.moveTo(0,0);
        /**
         *          ,                     
         */
        mPath.lineTo(mTriangleWidth,0);
        mPath.lineTo(mTriangleWidth / 2,-(mTriangleWidth / 2 - 2));
        /**
         *                         
         */
        mPath.close();
    }

    /**
     *    tab          
     */
    public void resetTextViewColor(){
        for(int i = 0;i