Android_フォントの変色、viewpagerインジケータ


概要
本編は鴻洋からのものです大神のAndroidカスタムコントロールがフォントを変えてクールなViewPagerインジケータを作るこのブログは、最初はよく理解できなかったと思っていましたが、今は自分でコードを減らして、自分で書いたものも、同じ効果を実現して、よく理解しました.まず、実装後の効果を見てみましょう.
このような文字がviewpagerのスライドに従って徐々に色を変える効果を実現するには、ここでは明らかにベース色の字がずっとあるので、主に赤いフォントの描画を考慮します.赤いフォントを描くにはcanvasのclipRect()メソッドを使用します.変更する幅係数に応じて、描画する位置をカットします.ここではカスタムプロパティを使用して、コントロールのプロパティを変更するのに便利です.
1、カスタム属性
attrs.xmlファイル
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <attr name="text" format="string"/>
    <attr name="textSize" format="dimension"/>
    <attr name="textOriginColor" format="color"/>
    <attr name="textChangeColor" format="color"/>
    <attr name="progress" format="float"/>
    <attr name="direction" >
        <enum name="left" value="0" />  
        <enum name="right" value="1" />  
    </attr>

    <declare-styleable name = "colortractview">
         <attr name="text" />  
        <attr name="textSize" />  
        <attr name="textOriginColor" />  
        <attr name="textChangeColor" />  
        <attr name="progress" />  
        <attr name="direction" />  
    </declare-styleable>
</resources>

activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:raise="http://schemas.android.com/apk/res/com.raise.colortrackview" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#fff" >

    <com.raise.colortrackview.ColorTrackView  android:id="@+id/colortractview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="#ddd" raise:text="ColorTract  " raise:textChangeColor="#ff0000" raise:textSize="30sp" />

    <LinearLayout  android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|center_horizontal" >

        <Button  android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="left" />

        <Button  android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="rihgt" />
    </LinearLayout>

</FrameLayout>

ColorTrackView.JAvaソース
package com.raise.colortrackview;

import com.raise.colortrackview.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

public class ColorTrackView extends View {

    //     
    private static final int DEFAULT_TEXTSIZE = 20;
    private static final int DIRECTION_LEFT = 0;
    private static final int DIRECTION_RIGHT = 1;
    private static final int DEFAULT_ORIGHT_COLOR = Color.BLACK;
    private static final int DEFAULT_CHANGE_COLOR = Color.RED;
/** *           * @author raise * */
    public enum Direction{
        Left,Right
    }
    /** *      */
    private Paint mPaint;
    /** *        */
    private String mText;
    /** *      */
    private int mTextSize;
    /** *       */
    private int mOriginColor;
    /** *          */
    private int mChangeColor;
    /** *      */
    private float mProgress;
    /** *      */
    private int mDirection;
    /** * view   */
    private int mWidth;
    /** * view   */
    private int mHeight;

    public ColorTrackView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mPaint = new Paint();
        //       
        initDatas(context, attrs);
        //      
        mText = mText == null ? "  " : mText;
        mPaint.setTextSize(mTextSize);
        //        ,           
        mWidth = (int) mPaint.measureText(mText);
        mHeight = (int) (mPaint.descent() - mPaint.ascent());

// setBackgroundColor(Color.parseColor("#f1f1f1"));
    }

    private void initDatas(Context context, AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs,
                R.styleable.colortractview);
        mText = ta.getString(R.styleable.colortractview_text);
        mTextSize = ta.getDimensionPixelOffset(
                R.styleable.colortractview_textSize, sp2px(DEFAULT_TEXTSIZE));
        mDirection = ta.getInt(R.styleable.colortractview_direction,
                DIRECTION_LEFT);
        mOriginColor = ta.getColor(R.styleable.colortractview_textOriginColor,
                DEFAULT_ORIGHT_COLOR);
        mChangeColor = ta.getColor(R.styleable.colortractview_textChangeColor,
                DEFAULT_CHANGE_COLOR);
        mProgress = ta.getFloat(R.styleable.colortractview_progress, 0f);
        ta.recycle();
    }

    public ColorTrackView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // view width,height     
        widthMeasureSpec = MeasureSpec.makeMeasureSpec(mWidth,
                MeasureSpec.EXACTLY);
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(mHeight,
                MeasureSpec.EXACTLY);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int startX = (int) (mProgress * mWidth);
        //         
        mPaint.setColor(mOriginColor);
        canvas.drawText(mText, 0, mHeight - mPaint.descent(), mPaint);
        mPaint.setColor(mChangeColor);
        canvas.save();
        //         
        if (mDirection == DIRECTION_LEFT) {
            //        ,     (0,0)
            canvas.clipRect(0, 0, startX, mHeight);
        } else if (mDirection == DIRECTION_RIGHT) {
            //        ,     (mWidth,mHeight)
            canvas.clipRect(mWidth-startX, 0, mWidth, mHeight);
        }
        //          
        canvas.drawText(mText, 0, mHeight - mPaint.descent(), mPaint);
        canvas.restore();
    }

    private int dp2px(int value) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                value, getResources().getDisplayMetrics());
    }

    private int sp2px(int value) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                value, getResources().getDisplayMetrics());
    }
    public int getmDirection() {
        return mDirection;
    }

    public void setDirection(int direction) {
        this.mDirection = direction;
    }

    public void setProgress(float progress) {
        this.mProgress = progress;
        //       
        invalidate();
    }

}

オオカミとの違いは、フォントの大きさを使って、そのビューの大きさとして、このように理解するのは簡単で、使うときは、外部にLinearlayoutを追加すればいいということです.MainActivity.JAvaソース:
public class MainActivity extends Activity implements OnClickListener {

    ColorTrackView view ;
    Button leftbButton;
    Button rightButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        view = (ColorTrackView) findViewById(R.id.colortractview);
        leftbButton = (Button) findViewById(R.id.button1);
        rightButton = (Button) findViewById(R.id.button2);

        leftbButton.setOnClickListener(this);
        rightButton.setOnClickListener(this);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onClick(View v) {
        if (v == leftbButton) {
            view.setDirection(0);
            Toast.makeText(MainActivity.this, "left", 1).show();
            ObjectAnimator.ofFloat(view, "progress", 0f,1f).setDuration(2000).start();
        }else if (v == rightButton) {
            Toast.makeText(MainActivity.this, "right", 1).show();
            view.setDirection(1);
            ObjectAnimator.ofFloat(view, "progress", 0f,1f).setDuration(2000).start();

        }

    }

}

予想通り、簡略化して大丈夫そうです.以下、viewpagerに使用します.TabFragment.java
public class TabFragment extends Fragment {

    private static final String TITLE = "title";

    private String mTitle = "default title";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        Bundle bundle = getArguments();
        if (bundle!=null) {
            mTitle = bundle.getString(TITLE);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        TextView view = new TextView(getActivity());
        view.setTextSize(30);
        Random r = new Random();
        view.setBackgroundColor(Color.argb(r.nextInt(120), r.nextInt(255),
                r.nextInt(255), r.nextInt(255)));
        view.setGravity(Gravity.CENTER);
        view.setText(mTitle);
        return view;
    }

    public static Fragment newInstance(String title) {
        TabFragment fragment = new TabFragment();
        Bundle bundle = new Bundle();
        bundle.putString(TITLE, title);
        fragment.setArguments(bundle);
        return fragment;

    }

}

TestActivity.java
public class TestActivity extends FragmentActivity implements OnPageChangeListener {

    private String[] mTitles = { "  ", "  ", "  " };
    private ViewPager viewPager;
    //      list
    private List<ColorTrackView> viewList = new ArrayList<ColorTrackView>();
    private ColorTrackView colorView1;
    private ColorTrackView colorView2;
    private ColorTrackView colorView3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        initView();
        viewPager.setAdapter(adapter);
        viewPager.setOnPageChangeListener(this);
        viewList.add(colorView1);
        viewList.add(colorView2);
        viewList.add(colorView3);

        viewList.get(0).setProgress(1);
    }

    private void initView() {
        viewPager = (ViewPager) findViewById(R.id.viewpage);
        colorView1 = (ColorTrackView) findViewById(R.id.view_color1);
        colorView2 = (ColorTrackView) findViewById(R.id.view_color2);
        colorView3 = (ColorTrackView) findViewById(R.id.view_color3);
    }

    FragmentPagerAdapter adapter = new FragmentPagerAdapter(
            getSupportFragmentManager()) {
        @Override
        public int getCount() {
            return mTitles.length;
        }
        @Override
        public Fragment getItem(int arg0) {
            return TabFragment.newInstance(mTitles[arg0]);
        }
    };

    @Override
    public void onPageScrollStateChanged(int arg0) {
    }
    /* * arg0    fragment  ,arg1,0-1    ,arg2      */
    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) {
        //        
        if (arg1 == 0f) {
            return;
        }
        //      view
        ColorTrackView leftView = viewList.get(arg0);
        //      view
        ColorTrackView rightView = viewList.get(arg0 + 1);
        //     view     
        leftView.setDirection(1);
        leftView.setProgress(1 - arg1);
        //     view     
        rightView.setDirection(0);
        rightView.setProgress(arg1);
    }

    @Override
    public void onPageSelected(int arg0) {
    }
}

activity_test.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:raise="http://schemas.android.com/apk/res/com.raise.colortrackview" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" >

    <LinearLayout  android:layout_width="match_parent" android:layout_height="60dp" android:background="#f1f1f1" android:gravity="center_vertical" android:orientation="horizontal" android:weightSum="3" >

        <LinearLayout  android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:orientation="horizontal" >

            <com.raise.colortrackview.ColorTrackView  android:id="@+id/view_color1" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" raise:text="  " raise:textChangeColor="#c96666" />
        </LinearLayout>

        <LinearLayout  android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:orientation="horizontal" >

            <com.raise.colortrackview.ColorTrackView  android:id="@+id/view_color2" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" raise:text="  " raise:textChangeColor="#c96666" />
        </LinearLayout>

        <LinearLayout  android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:orientation="horizontal" >

            <com.raise.colortrackview.ColorTrackView  android:id="@+id/view_color3" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" raise:text="  " raise:textChangeColor="#c96666" />
        </LinearLayout>
    </LinearLayout>

    <android.support.v4.view.ViewPager  android:id="@+id/viewpage" android:layout_width="match_parent" android:layout_height="match_parent" />

</LinearLayout>

ソース:ダウンロードします