自定义View实现文本水平方向的跑马灯效果,可以设置文本相关属性及滚动速度,以及滚动方式

/*** Created by wyl on 2018/10/10.*/
public class MarqueeView extends View {private static final String TAG = " MarqueeView  ";private final float DEF_SIZE = 250.0f;//默认字体大小private final int DEF_COLOR = 0xff0000;private float mSpeed = 4.0F; //默认滚动速度private boolean isScroll = true; //是否自动滚动private Context mContext;private Paint mPaint; //文字画笔private String mText;//展示内容private float mCoordinateX;//文字起始位置的X轴偏移量private float mCoordinateX_;//首尾紧跟滚动 新一轮文字起始位置的X轴偏移量private float mCoordinateY;//Y轴偏移量private float mTextWidth; //文本的宽度private int mViewWidth; //控件的宽度private int mViewHeight;//控件高度public static int SCROLL_ENDED = 1, SCROLL_FOLLOW = 2;private int mScrollType;//文本滚动方式  紧邻滚动、一行结束之后滚动private int mFollowSpace = 10;//相邻滚动 首尾文字间距public MarqueeView(Context context) {super(context);init(context);}public MarqueeView(Context context, AttributeSet attrs) {super(context, attrs);init(context);}public MarqueeView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(context);}private void init(Context context) {this.mContext = context;if (TextUtils.isEmpty(mText)) {mText = "欢迎光临";}mPaint = new Paint();mPaint.setTypeface(Typeface.DEFAULT_BOLD);mPaint.setAntiAlias(true);mPaint.setTextSize(DEF_SIZE);mPaint.setColor(DEF_COLOR);}public void setText(String text) {mText = text;if (TextUtils.isEmpty(mText)) {mText = "欢迎光临!";}requestLayout();//设置字体过后 需要重新测量Viewinvalidate();//重新绘制}public void setTextSize(float textSize) {mPaint.setTextSize(textSize <= 0 ? DEF_SIZE : textSize);requestLayout();invalidate();}public void setTextColor(int textColor) {mPaint.setColor(textColor);invalidate();}//设置滚动速度public void setTextSpeed(float speed) {this.mSpeed = speed < 1 ? 1 : speed;invalidate();}/*** //设置滚动相邻距离* //根据控件宽度设置最好** @param space*/public void setFollowSpace(int space) {this.mFollowSpace = space < 10 ? 10 : space;invalidate();}//设置滚动方式public void setScrollType(int type) {mScrollType = type;invalidate();}//设置滚动public void setScroll(boolean isScroll) {this.isScroll = isScroll;invalidate();}//是否滚动public boolean isScroll() {return isScroll;}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);mCoordinateX = getWidth();mCoordinateX_ = mCoordinateX;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {mTextWidth = mPaint.measureText(mText);//测量文本长度//从屏幕最右端开始//  mCoordinateX = getResources().getDisplayMetrics().widthPixels;//测量控件宽度mViewWidth = measureW(widthMeasureSpec);//测量控件高度mViewHeight = measureH(heightMeasureSpec);//测量文本起始位置Y轴的偏移量  使其水平居中Paint.FontMetricsInt fm = mPaint.getFontMetricsInt();mCoordinateY = getHeight() / 2 - fm.descent + (fm.descent - fm.ascent) / 2;//根据文本显示内容选择//----------------------top//----------------------ascent//   内容(中文/英文)//----------------------baseline//----------------------descent//----------------------bottom//mCoordinateY = getHeight() / 2 - fm.descent + (fm.bottom- fm.top) / 2mCoordinateX = mViewWidth;mCoordinateX_ = mCoordinateX;setMeasuredDimension(mViewWidth, mViewHeight);}private int measureW(int measureSpec) {int result = 0;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);if (specMode == MeasureSpec.EXACTLY) {//match_parent 或者 具体的值result = specSize;} else {//wrap_content 由文本长度 及左右padding决定result = (int) mPaint.measureText(mText) + getPaddingLeft()+ getPaddingRight();if (specMode == MeasureSpec.AT_MOST) {result = Math.min(result, specSize);}}return result;}private int measureH(int measureSpec) {int result = 0;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);if (specMode == MeasureSpec.EXACTLY) {//match_parent 或者 具体的值result = specSize;} else {//wrap_content 控件高度由字体大小 及 上下padding决定result = (int) mPaint.getTextSize() + getPaddingTop()+ getPaddingBottom();if (specMode == MeasureSpec.AT_MOST) {result = Math.min(result, specSize);}}return result;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if ((Math.abs(mCoordinateX) > mTextWidth && mCoordinateX < 0)) {mCoordinateX = mCoordinateX_;mCoordinateX_ = getWidth();}Paint.FontMetricsInt fm = mPaint.getFontMetricsInt();mCoordinateY = getHeight() / 2 - fm.descent + (fm.descent - fm.ascent) / 2;//绘制文本canvas.drawText(mText, mCoordinateX, mCoordinateY, mPaint);//如果不能滚动 则停止绘制if (!isScroll) {return;}//每绘制一次 X轴的偏移量 减去滚动速度 再进行绘制mCoordinateX -= mSpeed;if (mScrollType == SCROLL_ENDED) {//当文本向左偏移text的宽度后 即所有文字都从屏幕左侧出去后 重置X轴的偏移量 让文字重新由右边进入if (Math.abs(mCoordinateX) > mTextWidth && mCoordinateX < 0) {mCoordinateX = mViewWidth;//重置X轴偏移量为控件宽度}} else {//当文本剩余内容快要结束(快要离开屏幕mFollowSpace距离)时,开始绘制新一轮的文字if ((Math.abs(mCoordinateX) + mFollowSpace) > mTextWidth && mCoordinateX < 0 && mCoordinateX_ > -4) {canvas.drawText(mText, mCoordinateX_, mCoordinateY, mPaint);mCoordinateX_ -= mSpeed;}}invalidate();}
}

Android 自定义View实现文本水平方向的跑马灯效果相关推荐

  1. Android 自定义View(四)实现股票自选列表滑动效果

    一.前言 Android 开发过程中自定义 View 真的是无处不在,随随便便一个 UI 效果,都会用到自定义 View.前面三篇文章已经讲过自定义 View 的一些案例效果,相关类和 API,还有事 ...

  2. android 图片跑马灯动画,【Android自定义View】- 文本跑马灯效果

    简介 有些时候,文字过长,或者有多条需要展示的文本时,我们需要将文本进行左右滚动,多条文本时,还得上下滚动以实现展示不同的文本内容.这时候就需要我们自定义view来实现文本跑马灯效果了. 效果图 jj ...

  3. android自定义起止时间的时间刻度尺,Android 自定义View篇(六)实现时钟表盘效果...

    前言 Android 自定义 View 是高级进阶不可或缺的内容,日常工作中,经常会遇到产品.UI 设计出花里胡哨的界面.当系统自带的控件不能满足开发需求时,就只能自己动手撸一个效果. 本文就带自定义 ...

  4. Android自定义View分享——仿微信朋友圈图片合并效果

    写在前面 笔者近来在学习Android自定义View,收集了一些不算复杂但又"长得"还可以的自定义View效果实现,之前分享过两个效果:一个水平的进度条,一个圆形温度显示器,如果你 ...

  5. Android自定义View——仿ViVO X6 极速闪充动画效果

    一直都在看自定义View,经过一个星期的坚持,基本上能够写出一些比较实用的控件效果了,今天天气太热,就待在家里玩手机,然后手机没电了,在充电的时候,看到了手机的充电动画,觉得挺酷,然后自己我就仔细的分 ...

  6. 【Android 自定义 View】--> 绘制时钟(表)效果

    前言 本篇文章主要介绍使用自定义 View 来实现时钟效果,灵活地使用 Android 的 Canvas,Paint, Path 的 API 以及理清 Canvas 的 save 和 restore ...

  7. android吉他谱组件,Android - 自定义View 实现 文本吉他谱的 动态控制 实现

    1.背景 前天同学推荐,要做一个吉他谱的显示,与控制功能:想了想,感觉难度有些大,主要有几个难点: 难点1 :显示:文本吉他谱是txt ,需要 和弦键与对应的文字对应显示出来: 难点2: 控制:需要通 ...

  8. Android 自定义view 实现点击 展示下拉选项效果

    思路: 使用PopWindow ,里面布局为listview,点击展示PopWindow,点击其他区域或者选择完成时 关闭PopWindow~ 关键点: 1,实现头部视图(本文名为:pop_out_t ...

  9. Android studio | From Zero To One ——TextView实现跑马灯效果及聊天室、文字直播间

    ================================================ 博主github:https://github.com/MichaelBeechan 博主CSDN:h ...

最新文章

  1. prometheus连续查询_Prometheus查询
  2. 天高任鸟飞,海阔凭鱼跃
  3. 【Mood-9】搬家至博客园喽~~~
  4. 三态门三个状态vhdl_人防门是什么?为什么会侵线导致重庆地铁事故
  5. Java面向对象(六)接口
  6. c语言设计一个万年历的需求分析,万年历设计报告
  7. linux 权限管理命令chown、chgrp、umask、linux新建文件或目录的默认权限755
  8. Python入门学习笔记(4)
  9. supercharge快充_电荷泵?双电芯?高压低流?盘点目前最全快充技术
  10. javascript--返回顶部效果
  11. 【SSM】企业差旅管理系统-李兴华-专题视频课程
  12. 最可怕联想win7 64位旗舰版下载
  13. 分享Silverlight/WPF/Windows Phone一周学习导读(07月11日-07月17日)
  14. dot全称_dot是什么格式
  15. 程序员与颈椎病(一) 我得了什么病
  16. 一元享移动怎么样_移动终于良心了?月费6元享46G流量,网友:后悔携号转网了!...
  17. 如何搭建App自动化测试框架?
  18. MATLAB:镜像图片
  19. python安装环境配置linux_[Python学习] Linux环境下的Python配置,必备库的安装配置...
  20. 项目资源管理-日历图

热门文章

  1. 如何将多台物理机整合成一台
  2. Qt读写JSON,以及使用QTreeView展示和编辑JSON数据
  3. 2022-2028年中国电磁兼容产品行业市场发展前景及投资风险评估报告
  4. Nvidia-docker2 for ubuntu18.04初试!
  5. matlab灰度图转rgb原理,RGB图像转化为灰度图原理以及MATLAB实现
  6. 1075 习题5-3-4 求最小公倍数
  7. 【面试题】CSS 中几种最常用的水平垂直居中的方法
  8. idea插件开发(5)-Swing图形化设计
  9. SAP删除成本中心组
  10. 用于生成随机数的python标准库模块是_详解Python基础random模块随机数的生成