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();
}
}
和大神区别在于,我使用了字体的大小,做为该View的大小,这样理解起来简单了许多,在使用的时候,只要在外部多加一层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>
源码:点我下载
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。