首先values文件夹下添加或创建attrs文件,如下:
<?xml version="1.0" encoding="utf-8"?> <resources><!--//垂直滚动字幕--><declare-styleable name="VerticalRollingTextView"><!--文字颜色--><attr name="android:textColor"/><!--文字大小--><attr name="android:textSize"/><!--滚动动画时长--><attr name="android:duration"/><!--两次动画之间的间隔--><attr name="animInterval" format="integer"/></declare-styleable></resources>
1、自定义上下滚动字幕textview、VerticalRollingTextView
/*** 作者:created by meixi* 邮箱:13164716840@163.com* 日期:2018/8/30 10*/public class VerticalRollingTextView extends View {DataSetAdapter mDataSetAdapter;private final Paint mPaint;private int mCurrentIndex;private int mNextIndex;Rect bounds = new Rect();private float mCurrentOffsetY;private float mOrgOffsetY = -1;private final float mTextTopToAscentOffset;private float mOffset;private InternalAnimation mAnimation = new InternalAnimation();/*防止动画结束的回调触发以后动画继续进行出现的错乱问题*/private boolean mAnimationEnded;private boolean isRunning;/*动画时间*/private int mDuration = 1000;/*动画间隔*/private int mAnimInterval = 5000;public VerticalRollingTextView(Context context, AttributeSet attrs) {super(context, attrs);mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setColor(Color.BLACK);mPaint.setTypeface(Typeface.DEFAULT);parseAttrs(context, attrs);Paint.FontMetricsInt metricsInt = mPaint.getFontMetricsInt();mTextTopToAscentOffset = metricsInt.ascent - metricsInt.top;mAnimation.setDuration(mDuration);}private void parseAttrs(Context context, AttributeSet attrs) {float density = getResources().getDisplayMetrics().density;TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.VerticalRollingTextView);mPaint.setColor(typedArray.getColor(R.styleable.VerticalRollingTextView_android_textColor, Color.BLACK));mPaint.setTextSize(typedArray.getDimensionPixelOffset(R.styleable.VerticalRollingTextView_android_textSize, (int) (density * 14)));mDuration = typedArray.getInt(R.styleable.VerticalRollingTextView_android_duration, mDuration);mAnimInterval = typedArray.getInt(R.styleable.VerticalRollingTextView_animInterval, mAnimInterval);typedArray.recycle();}@Overrideprotected void onDraw(Canvas canvas) {// 绘制文本if (mDataSetAdapter == null || mDataSetAdapter.isEmpty()) {return;}String text1 = mDataSetAdapter.getText(mCurrentIndex);String text2 = mDataSetAdapter.getText(mNextIndex);//只需要进行一次测量if (mOrgOffsetY == -1) {mPaint.getTextBounds(text1, 0, text1.length(), bounds);mOffset = (getHeight() + bounds.height()) * 0.5f;mOrgOffsetY = mCurrentOffsetY = mOffset - mTextTopToAscentOffset;mAnimation.updateValue(mOrgOffsetY, -2 * mTextTopToAscentOffset);}canvas.drawText(text1, 0, mCurrentOffsetY, mPaint);canvas.drawText(text2, 0, mCurrentOffsetY + mOffset + mTextTopToAscentOffset, mPaint);}public void setDataSetAdapter(DataSetAdapter dataSetAdapter) {mDataSetAdapter = dataSetAdapter;confirmNextIndex();invalidate();}/*** 开始转动,界面可见的时候调用*/public void run() {if (isRunning) {return;}isRunning = true;mAnimation.updateValue(mCurrentOffsetY, -2 * mTextTopToAscentOffset);post(mRollingTask);}/*** @return true代表正在转动*/public boolean isRunning() {return isRunning;}/*** 停止转动,界面不可见的时候调用*/public void stop() {isRunning = false;removeCallbacks(mRollingTask);}Runnable mRollingTask = new Runnable() {@Overridepublic void run() {mAnimationEnded = false;startAnimation(mAnimation);postDelayed(this, mAnimInterval);}};public void animationEnd() {//1.角标+1mCurrentIndex++;//2.计算出正确的角标mCurrentIndex = mCurrentIndex < mDataSetAdapter.getItemCount() ? mCurrentIndex : mCurrentIndex % mDataSetAdapter.getItemCount();//3.计算下一个待显示文字角标confirmNextIndex();//3.位置复位mCurrentOffsetY = mOrgOffsetY;mAnimationEnded = true;}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();removeCallbacks(mRollingTask);if (isRunning()) {mAnimation.cancel();}}/*** 计算第二个角标*/private void confirmNextIndex() {//3.计算第二个角标mNextIndex = mCurrentIndex + 1;//4.计算出正确的第二个角标mNextIndex = mNextIndex < mDataSetAdapter.getItemCount() ? mNextIndex : 0;}/*** float估值器** @param fraction* @param startValue* @param endValue* @return*/float evaluate(float fraction, float startValue, float endValue) {return startValue + fraction * (endValue - startValue);}@Overridepublic void setOnClickListener(OnClickListener l) {}public void setOnItemClickListener(final OnItemClickListener onItemClickListener) {super.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {onItemClickListener.onItemClick(VerticalRollingTextView.this, mCurrentIndex);}});}public interface OnItemClickListener {void onItemClick(VerticalRollingTextView view, int index);}class InternalAnimation extends Animation {float startValue;float endValue;@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) {if (mAnimationEnded) return;mCurrentOffsetY = evaluate(interpolatedTime, startValue, endValue);if (mCurrentOffsetY == endValue) {try {animationEnd();}catch (Exception e) {e.printStackTrace();}}postInvalidate();}public void updateValue(float startValue, float endValue) {this.startValue = startValue;this.endValue = endValue;}}}
2、layout.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><com.administrator.tests.VerticalRollingTextViewandroid:layout_width="match_parent"android:layout_height="40dp"android:background="@color/numtext"android:textColor="@color/colorAccent"android:id="@+id/myvtext"/></LinearLayout>
3、activity调用自定义textview赋值
VerticalRollingTextView verticalRollingTextView = (VerticalRollingTextView)findViewById(R.id.myvtext);TestEntity testEntity = new TestEntity();testEntity.setHttps("baidu.com");testEntity.setTitle("百度。com");TestEntity testEntity1 = new TestEntity();testEntity1.setTitle("谷歌。com");testEntity1.setHttps("guge.com");testEntities.add(testEntity);testEntities.add(testEntity1);verticalRollingTextView.setDataSetAdapter(new DataSetAdapter<TestEntity>(testEntities) {@Overrideprotected String text(TestEntity s) {return s.getTitle();}
});
verticalRollingTextView.run();
verticalRollingTextView.setOnItemClickListener(new VerticalRollingTextView.OnItemClickListener() {@Overridepublic void onItemClick(VerticalRollingTextView view, int index) {//点击链接String url = testEntities.get(index).getHttps();Toast.makeText(MainActivity.this,url,Toast.LENGTH_LONG).show();}
});