很多app的首页都会有一个用于显示热点消息的banner,通过垂直切换文本的方式动态展示消息。垂直切换的方式可以有效利用空间显示更多的内容,动态的效果也更能吸引用户的注意力。
实现这个效果,我能想到的方式大概有两种:
1、继承一个LineLayout,在里面添加两个TextView,通过动画实现TextView的移动、显示、隐藏。
2、继承TextView,手动去绘制文字,然后动态的改变文字的绘制,以实现切换的动效。
相比之下,第一种方式要简单一些,而且方法1不只可以添加TextVIew,还可以添加两个ViewGroup,然后构建更加复杂的布局,如添加图片等。为了体现自定义控件的特点,这里使用第二种方式来实现这个功能。具体看下代码的实现:
private static final int DEFAULT_SWITCH_DURATION = 500;
private static final int DEFAULT_IDLE_DURATION = 2000;
private Context mContext;
private List<String> lists;//会循环显示的文本内容
private int contentSize;
private String outStr;//当前滑出的文本内容
private String inStr;//当前滑入的文本内容
private float textBaseY;//文本显示的baseline
private int currentIndex = 0;//当前显示到第几个文本
private int switchDuaration = DEFAULT_SWITCH_DURATION;//切换时间
private int idleDuaration = DEFAULT_IDLE_DURATION;//间隔时间
private int switchOrientation = 0;
private float currentAnimatedValue = 0.0f;
private ValueAnimator animator;
private int verticalOffset = 0;
private int mWidth;
private int mHeight;
private int paddingLeft = 0;
private int paddingBottom = 0;
private int paddingTop = 0;
private Paint mPaint;
//回调接口,用来通知调用者控件当前的状态
public VerticalSwitchTextViewCbInterface cbInterface;
public VerticalSwitchTextView(Context context) {
this(context, null);
}
public VerticalSwitchTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public VerticalSwitchTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.VerticalSwitchTextView);
try {
switchDuaration = array.getInt(R.styleable.VerticalSwitchTextView_switchDuaration, DEFAULT_SWITCH_DURATION);
idleDuaration = array.getInt(R.styleable.VerticalSwitchTextView_idleDuaration, DEFAULT_IDLE_DURATION);
switchOrientation = array.getInt(R.styleable.VerticalSwitchTextView_switchOrientation, 0);
} finally {
array.recycle();
}
init();
}
首先定义一些常量和变量,并实现了三个构造方法。
常量的含义可以直接看代码的标注,构造方法中只有一个参数的方法是在代码里使用new生成View的时候调用的,两个参数的构造方法是在xml中定义View的时候调用,三个参数的构造方法不常用,当有自定义style的时候会用到。构造方法中对自定义属性进行了解析,后面会用到。
<resources>
<declare-styleable name="VerticalSwitc