結果を示す
主成分分析
1.一目で、上のインジケーターにLinearLayout +下のレイアウトにViewPagerを使用します。他の方法も確かに可能であり、時間が許せば自分で試すことができます。
2.複数の「カスタムTextView」をLinearLayoutレイアウトで動的にロードします
3. ViewPagerのスクロールイベントを監視して、上記のインジケーターとのリンクを実現します
ソースコード分析
ステップ1: TextViewを継承するようにColorTrackTextViewをカスタマイズ する
ここで、疑問があるかもしれませんが、なぜTextViewを継承するのですか、Viewは良くありませんか?
私の答えはこれです:Viewは確かに可能ですが、TextViewの方が優れています。その理由は、TextViewがすでにonMeasureメソッドを実装しているため、自分で作成する必要がないためです。次に、いくつかの機能を十分に活用できます。 TextSize、TextColorなどのTextViewのプロパティなので、TextViewを選択します。
ビューを継承するとパフォーマンスが向上すると言う人もいますが、質問したいのですが、パフォーマンスを測定するための良い方法はありますか?
ステップ2:カスタムプロパティファイルを作成する
ここには主に、元の色と変更された色の2つの属性があります。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ColorTrackTextView">
<attr name="originColor" format="color"/>
<attr name="changeColor" format="color"/>
</declare-styleable>
</resources>
3番目のステップ:レイアウトファイルで使用します。ここでは動的読み込みを使用します。つまり、データに応じてコードにインジケーターを動的に追加します。したがって、次は線形レイアウト+ ViewPagerです。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/ll_indicator_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="10dp"
android:paddingBottom="10dp"/>
<androidx.viewpager.widget.ViewPager
android:id="@+id/vp_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
ステップ4:カスタム属性を取得し、関連するコードを記述します
package com.example.view_day04;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.TextView;
import android.annotation.SuppressLint;
@SuppressLint("AppCompatCustomView")
public class ColorTrackTextView extends TextView {
private int mOriginColor = Color.BLACK;
private int mChangeColor = Color.RED;
//1、实现一个文字两种颜色 --- 绘制不变色字体的画笔
private Paint mOriginPaint;
//1、实现一个文字两种颜色 --- 绘制变色字体的画笔
private Paint mChangePaint;
//1、实现一个文字两种颜色 --- 当前进度
private float mCurrentProgress = 0.0f;
//2、实现不同朝向
public Direction mDirection = Direction.LEFT_TO_RIGHT;
public enum Direction{
LEFT_TO_RIGHT,RIGHT_TOLEFT
}
public ColorTrackTextView(Context context) {
this(context,null);
}
public ColorTrackTextView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public ColorTrackTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint(context,attrs);
}
/**
*1.1初始化画笔
*@Author yiqi
*@created 2021/2/26 15:35
*@param
*@return
*/
private void initPaint(Context context, AttributeSet attrs){
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ColorTrackTextView);
int originColor = typedArray.getColor(R.styleable.ColorTrackTextView_originColor,mOriginColor);
int changeColor = typedArray.getColor(R.styleable.ColorTrackTextView_changeColor,mChangeColor);
mOriginPaint = getPaintByColor(originColor);
mChangePaint = getPaintByColor(changeColor);
typedArray.recycle();
}
/**
*1、根据颜色获取画笔
*@Author yiqi
*@created 2021/2/26 15:48
*@param
*@return
*/
private Paint getPaintByColor(int color) {
Paint paint = new Paint();
//设置抗锯齿
paint.setAntiAlias(true);
//设置防抖动
paint.setDither(true);
//设置颜色
paint.setColor(color);
//设置字体大小 就是TextView的字体大小
paint.setTextSize(getTextSize());
return paint;
}
//1、一个文字两种颜色
//利用canvas.clipRect(rect); 可以裁剪 左边用一个画笔去画 右边用另一个画笔去画 不断的改变中间值
@Override
protected void onDraw(Canvas canvas) {
//super.onDraw(canvas); //不能执行这个,要不然会执行 TextView 的 onDraw() 方法,用他的方式把文字画出来
//canvas.clipRect(); 裁剪区域
//根据进度把中间值算出来
int middle = (int) (mCurrentProgress*getWidth());
if (mDirection == Direction.LEFT_TO_RIGHT){
//绘制不变色的
drawText(canvas,mOriginPaint,middle,getWidth());
//绘制变色的
drawText(canvas,mChangePaint,0,middle);
}else {
// System.out.println("middle=" +middle + "__getwidth()-middle=" + (getWidth()-middle));
//绘制不变色的
drawText(canvas,mOriginPaint,0,getWidth() - middle);
//绘制变色的
drawText(canvas,mChangePaint,getWidth() - middle,getWidth());
}
}
/**
*绘制 Text
*@Author yiqi
*@created 2021/2/26 17:40
*@param
*@return
*/
private void drawText(Canvas canvas,Paint paint,int start,int end){
canvas.save();
//绘制不变色的
Rect rect = new Rect(start,0,end,getHeight());
canvas.clipRect(rect);
//我们自己来画
String text = getText().toString();
//获取字体基线
Paint.FontMetricsInt fontMetricsInt = paint.getFontMetricsInt();
int dy = (fontMetricsInt.bottom - fontMetricsInt.top)/2 - fontMetricsInt.bottom;
int baseLine = getHeight()/2 + dy;
//获取字体的宽度
Rect bounds = new Rect();
paint.getTextBounds(text,0,text.length(),bounds);
int x = getWidth()/2 - bounds.width()/2;
canvas.drawText(text,x,baseLine,paint); //这么画,其实还是只有一种颜色
canvas.restore();
}
public void setDirection(Direction direction){
this.mDirection = direction;
}
public void setCurrentProgress(float currentProgress){
this.mCurrentProgress = currentProgress;
System.out.println("invalidate()被调用了");
invalidate();
}
public void setChangeColor(int changeColor){
this.mChangeColor = changeColor;
}
public void setOriginColor(int originColor){
this.mOriginColor = originColor;
}
}
ステップ5:電話する
package com.example.view_day04;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import java.util.ArrayList;
import java.util.List;
public class ViewPagerActivity extends Activity {
private String[] items = {"直播","推荐","视频","图片","段子","精华"};
private List<ColorTrackTextView> mIndicators;
private LinearLayout ll_indicator_view;
private ViewPager vp_view_pager;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewpager);
initView();
initData();
}
private void initView() {
ll_indicator_view = findViewById(R.id.ll_indicator_view);
vp_view_pager = findViewById(R.id.vp_view_pager);
}
private void initData() {
mIndicators = new ArrayList<>();
//初始化可变色指示器
for (int i = 0; i < items.length; i++) {
ColorTrackTextView colorTrackTextView = new ColorTrackTextView(this);
//设置位置参数
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.weight = 1;
colorTrackTextView.setLayoutParams(params);
//设置文字的基本信息
colorTrackTextView.setText(items[i]);
colorTrackTextView.setTextSize(20);
colorTrackTextView.setChangeColor(Color.RED);
//加入到LinearLayout容器中
ll_indicator_view.addView(colorTrackTextView);
//加入到集合
mIndicators.add(colorTrackTextView);
}
//初始化ViewPager
vp_view_pager.setAdapter(new PagerAdapter() {
@Override
public int getCount() {
return items.length;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
TextView textView =new TextView(getApplicationContext());
textView.setText(items[position]);
container.addView(textView);
return textView;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView((View) object);
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
});
//监听ViewPager的事件
vp_view_pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
System.out.println("position=" + position + "positionOffset+" + positionOffset + "mIndicators.get(position)=" + mIndicators.get(position));
//1、左边
ColorTrackTextView left = mIndicators.get(position);
left.setDirection(ColorTrackTextView.Direction.RIGHT_TOLEFT);
left.setCurrentProgress(1-positionOffset);
//右边
//1、左边
try {
ColorTrackTextView right= mIndicators.get(position+1);
right.setDirection(ColorTrackTextView.Direction.LEFT_TO_RIGHT);
right.setCurrentProgress(positionOffset);
}catch (Exception e){
}
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
}
このように、あなたは成功しています、それは簡単ではありません
最後に、ソースコードを添付します:カスタムテキストカラー効果