文字逐渐变色(自定义View)

效果:
这里写图片描述


最核心的代码是: canvas.clipRect(startX, 0, endX, getMeasuredHeight());
实际上绘画了2种颜色,然后根据progress来剪切,形成这样的效果。


自定义属性和获取
attr.xml

<resources>
   <attr name="text" format="string"></attr>
   <attr name="text_size" format="dimension"></attr>
   <attr name="text_origin_color" format="color|reference"></attr>
   <attr name="text_change_color" format="color|reference"></attr>
   <attr name="progress" format="float"></attr>
   <attr name="direction">
       <enum name="left" value="0"></enum>
       <enum name="right" value="1"></enum>
   </attr>

   <declare-styleable name="ColorTrackView">
       <attr name="text"></attr>
       <attr name="text_size"></attr>
       <attr name="text_origin_color"></attr>
       <attr name="text_change_color"></attr>
       <attr name="progress"></attr>
       <attr name="direction"></attr>
   </declare-styleable>
</resources>

自定义View : ColorTrackView.java

package com.example.day0203;

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

public class ColorTrackView extends View{

    private int mTextStartX = 0; 
    private Paint mPaint = new Paint();
    private String mText;
    private int mTextSize =  30;
    private int mTextOriginColor = 0xff000000;
    private int mTextChangeColor = 0xffff0000;
    private Rect mTextBound = new Rect();
    private int mTextWidth = 0;
    public float mProgress = 0;

    public enum Direction  
    {  
        LEFT , RIGHT ;  
    }  

    private int mDirection = DIRECTION_LEFT;   

    private static final int  DIRECTION_LEFT = 0 ;   
    private static final int  DIRECTION_RIGHT= 1 ; 

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

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ColorTrackView);
        mText = ta.getString(R.styleable.ColorTrackView_text);
        mTextSize = ta.getDimensionPixelSize(R.styleable.ColorTrackView_text_size, mTextSize);
        mTextOriginColor = ta.getColor(R.styleable.ColorTrackView_text_origin_color, mTextOriginColor);
        mTextChangeColor = ta.getColor(R.styleable.ColorTrackView_text_change_color, mTextChangeColor);
        mProgress = ta.getFloat(R.styleable.ColorTrackView_progress, mProgress);
        mDirection = ta.getInt(R.styleable.ColorTrackView_direction, mDirection);
        ta.recycle();


        mPaint.setTextSize(mTextSize);
        mPaint.setAntiAlias(true);
        measureText();

        }

    private void measureText()  
    {  
        mTextWidth = (int) mPaint.measureText(mText);  
        mPaint.getTextBounds(mText, 0, mText.length(), mTextBound);  
    }  


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int r = (int) (mProgress * mTextWidth +mTextStartX );  //没用到, 本意是拿来封装的
        if(mDirection == DIRECTION_LEFT)  
        {  
            drawChangeLeft(canvas, r);  
            drawOriginLeft(canvas, r);  
        }else  
        {  
            drawOriginRight(canvas, r);  
            drawChangeRight(canvas, r);  
        }  
    }


    private void drawChangeRight(Canvas canvas, int r)  
    {  
        drawText(canvas, mTextChangeColor, (int) (mTextStartX +(1-mProgress)*mTextWidth), mTextStartX+mTextWidth );  
    }  
    private void drawOriginRight(Canvas canvas, int r)  
    {  
        drawText(canvas, mTextOriginColor, mTextStartX, (int) (mTextStartX +(1-mProgress)*mTextWidth) );  
    }  

    private void drawChangeLeft(Canvas canvas, int r)  
    {  
        drawText(canvas, mTextChangeColor, mTextStartX, (int) (mTextStartX + mProgress * mTextWidth) );  
    }  

    private void drawOriginLeft(Canvas canvas, int r)  
    {  
        drawText(canvas, mTextOriginColor, (int) (mTextStartX + mProgress * mTextWidth), mTextStartX +mTextWidth );  
    }  

    private void drawText(Canvas canvas , int color , int startX , int endX)  
    {  
        mPaint.setColor(color);  
        canvas.save(Canvas.CLIP_SAVE_FLAG);  
        canvas.clipRect(startX, 0, endX, getMeasuredHeight());  
        canvas.drawText(mText, mTextStartX, getMeasuredHeight() / 2  
                + mTextBound.height() / 2, mPaint);  
        canvas.restore();  


    }

    public int getDirection() {
        return mDirection;
    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
      int  width = measureWidth(widthMeasureSpec);//得到View的宽
      int height = measureHight(heightMeasureSpec);//得到View的高
        setMeasuredDimension(width,height);

    }

    public float getMProgress() {
        return mProgress;
    }

    public void setMProgress(float mProgress) {
        this.mProgress = mProgress;
        invalidate();

    }

    private int measureWidth(int widthMeasureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(widthMeasureSpec);
        int specSize = MeasureSpec.getSize(widthMeasureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            result = 200;
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    private int measureHight(int heightMeasureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(heightMeasureSpec);
        int specSize = MeasureSpec.getSize(heightMeasureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            result = 200;
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

}

xml使用

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.day0203.MainActivity"
     xmlns:app="http://schemas.android.com/apk/res-auto"  xmlns:app1="http://schemas.android.com/apk/res/com.example.day0203">

    <com.example.day0203.ColorTrackView
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv"
        android:layout_marginBottom="40dp" 
        app1:text="BOB_海贼王"  

         />
    <LinearLayout 
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv">

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


        <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/bt_right"
            android:text="right"/>

    </LinearLayout>

</RelativeLayout>

MainActivity.java

...
final ColorTrackView mView = (ColorTrackView) findViewById(R.id.tv);

        Button bt1 = (Button) findViewById(R.id.bt_left);
        bt1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                mView.setDirection(0);  
                ObjectAnimator.ofFloat(mView, "mProgress", 0, 1).setDuration(2000).start();  


            }
        });

        Button bt2 = (Button) findViewById(R.id.bt_right);
        bt2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                mView.setDirection(1);  
                ObjectAnimator.ofFloat(mView, "mProgress", 0, 1).setDuration(2000).start();  


            }
        });
        ...

注意事项:
1.canvas.drawText(text,x,y,paint); //这里x,y的点是Text的左下角的位置(T)

2.ObjectAnimator.ofFloat(mView, “mProgress”, 0, 1).setDuration(2000).start(); //Obeject mView 必须包含mProgress的get,set方法,并且方法的名字要是getMProgress(),和setMProgress(),即参数的的第一个字母得大写!(之前写成setmProgress()无效)。并且若是ofFloat,mProgress必须是float类型


和ViewPager搭配使用(今日头条效果)

效果:
这里写图片描述

xml

<LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.example.day0203">

    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal">

        <com.example.day0203.ColorTrackView
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:id="@+id/ctv_tab_1"
            app:text="首页"/>
           <com.example.day0203.ColorTrackView
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:id="@+id/ctv_tab_2"
            app:text="内容"/>
              <com.example.day0203.ColorTrackView
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:id="@+id/ctv_tab_3"
            app:text="设置"/>
    </LinearLayout>

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

MainActivity

package com.example.day0203;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;

public class MainActivity extends FragmentActivity {

    private ViewPager mViewPager;
    private List<ColorTrackView> mTabs = new ArrayList<ColorTrackView>();  
    private String[] mTitles = new String[] { "简介", "评价", "相关" };  
    private TabFragment[] mFragments = new TabFragment[mTitles.length];  
    private FragmentPagerAdapter mAdapter;  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initViews();
        initDatas();
        initEvents();

    }

    private void initEvents() {
    mViewPager.setOnPageChangeListener(new OnPageChangeListener() {

        @Override
        public void onPageSelected(int arg0) {
            // TODO Auto-generated method stub

        }

        @Override  
        public void onPageScrolled(int position, float positionOffset,  
                int positionOffsetPixels)  
        {  
            if (positionOffset > 0)    
            {    
                ColorTrackView left = mTabs.get(position);    
                ColorTrackView right = mTabs.get(position + 1);    

                left.setDirection(1);  
                right.setDirection(0);  
                left.setMProgress( 1-positionOffset);    
                right.setMProgress(positionOffset);    
            }    
        }  


        @Override
        public void onPageScrollStateChanged(int arg0) {
            // TODO Auto-generated method stub

        }
    });

    }

    private void initDatas() {
        for (int i = 0; i < mTitles.length; i++)  
        {  
            mFragments[i] = (TabFragment) TabFragment.newInstance(mTitles[i]);  
        }  
        mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {

            @Override
            public int getCount() {
                // TODO Auto-generated method stub
                return mFragments.length;
            }

            @Override
            public Fragment getItem(int arg0) {
                // TODO Auto-generated method stub
                return mFragments[arg0];
            }
        };

        mViewPager.setAdapter(mAdapter);
        mViewPager.setCurrentItem(0);

    }

    private void initViews() {
        mViewPager = (ViewPager) findViewById(R.id.vp);  

        mTabs.add((ColorTrackView) findViewById(R.id.ctv_tab_1));  
        mTabs.add((ColorTrackView) findViewById(R.id.ctv_tab_2));  
        mTabs.add((ColorTrackView) findViewById(R.id.ctv_tab_3));

    }

}

TabFragment

package com.example.day0203;

import java.util.Random;

import android.graphics.Color;
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;

public class TabFragment extends Fragment{

     public static final String TITLE = "title";  
     private String mTitle = "Defaut Value";  


     @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mTitle = getArguments().getString(TITLE);
        }
    }

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

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

}

转载于:http://blog.csdn.net/lmj623565791/article/details/44098729

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值