上下滚动文字自定义控件
来源:互联网 发布:龟头增大知乎 编辑:程序博客网 时间:2024/05/21 12:39
创建自定义控件VerticalRollingTextView
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 = 2000; 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(); } @Override protected 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() { @Override public void run() { mAnimationEnded = false; startAnimation(mAnimation); postDelayed(this, mAnimInterval); } }; public void animationEnd() { //1.角标+1 mCurrentIndex++; //2.计算出正确的角标 mCurrentIndex = mCurrentIndex < mDataSetAdapter.getItemCount() ? mCurrentIndex : mCurrentIndex % mDataSetAdapter.getItemCount(); //3.计算下一个待显示文字角标 confirmNextIndex(); //3.位置复位 mCurrentOffsetY = mOrgOffsetY; mAnimationEnded = true; } @Override protected 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); } @Override public void setOnClickListener(OnClickListener l) { } public void setOnItemClickListener(final OnItemClickListener onItemClickListener) { super.setOnClickListener(new OnClickListener() { @Override public 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; @Override protected void applyTransformation(float interpolatedTime, Transformation t) { if (mAnimationEnded) return; mCurrentOffsetY = evaluate(interpolatedTime, startValue, endValue); if (mCurrentOffsetY == endValue) { animationEnd(); } postInvalidate(); } public void updateValue(float startValue, float endValue) { this.startValue = startValue; this.endValue = endValue; } }}
然后在values文件夹下创建attrs,自定义属性
<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>
最后在布局中调用
<com.bawei.redchild.view.VerticalRollingTextView android:id="@+id/home_rolling_tv" android:layout_height="40dp" android:layout_width="match_parent" android:layout_alignParentLeft="true" myattrs:animInterval="3000" android:layout_marginLeft="75dp" android:layout_marginTop="8dp" android:textSize="18sp" /> <!-- animInterval 滚动间隔时间 -->
在代码中获取控件,并给控件设置数据
mVerticalRollingView.setDataSetAdapter(new DataSetAdapter<String>(Arrays.asList(mStrs)) { @Override protected String text(String s) { return s; } });
可以设置点击监听
mVerticalRollingView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(VerticalRollingTextView view, int index) { Toast.makeText(MainActivity.this, mStrs[index], Toast.LENGTH_SHORT).show(); } });
最后开始,或者停止这个滚动字幕
if (mVerticalRollingView.isRunning()) { //停止滚动 mVerticalRollingView.stop(); button.setText("滚动"); } else { //开始滚动 mVerticalRollingView.run(); button.setText("停止"); }
0 0
- 上下滚动文字自定义控件
- 文字上下滚动
- 使文字上下滚动
- 文字上下滚动
- 文字上下滚动特效
- 上下滚动的文字
- 文字上下无缝滚动
- 文字上下滚动
- 文字上下滚动
- 文字上下滚动
- jq 文字上下滚动
- 文字上下滚动(javascript)
- 自定义textview控件实现文字滚动效果
- 自定义组合控件(密码锁的数字上下滚动效果)
- 文字或图片上下滚动
- div内容文字上下滚动
- android 页面文字上下滚动
- 文字上下滚动的效果
- NBA总决赛中提高篮球水平的神器
- Win7命令行使用MySQL
- 字符串正则表达式匹配
- VC++ 兼容性 资料收集
- MyEclipse10.6 myeclipse2013下添加jadClipse反编译插件
- 上下滚动文字自定义控件
- 足球守门机器人(附视频)——智能机器人守门员—— 梅西足球机器人守门员——守门员机器人介绍
- 女友没救了~追美国队长还要入手KIMON~
- 函数调用--函数栈
- eclipse打开当前文件所在文件夹的两种方法
- ISP与IAP的区别
- CXF内容总结
- 在winfrom窗体中使用漂亮的窗体样式。
- Python学习之基础总结--3