背景 由于普通TextView的跑马灯效果与焦点获取有关 所以不能直接使用 之前查找到的控件在数据设置方面存在问题

所以通过寻找github上的开源控件 并修改源码 得到一个目前感觉不错的效果

原理 滚动效果其实就是文字在屏幕上的移动 根据找到的控件 发现有两种方案

一种是使用scrollTo方法 使得文字移动到一个指定的位置 但是使用过程中发现 超过屏幕长度的文字会在最后显示省略号 在这个问题没解决前 不采用此方案

另外一种是使用drawText方法 不断绘制文字 最后修改源码得到的效果感觉不错 代码也比较精简 唯一的不方便是文字颜色大小需要在代码中设置 在属性中设置无效 不过感觉影响不太 看以后是否有更好的优化

目前采用这种方案

具体分析和相关的坑

1 drawText绘制文字居住的问题

 canvas.drawText(text, x, y, paint),第一个参数是我们需要绘制的文本,第四个参数是我们的画笔,这两个不用多说

主要是第二和第三个参数的含义,这两个参数在不同的情况下的值还是不一样的,x默认是这个字符串的左边在屏幕的位置,
如果设置了paint.setTextAlign(Paint.Align.CENTER);那就是字符的中心,
y是指定这个字符baseline在屏幕上的位置,y不是这个字符中心在屏幕上的位置,而是baseline在屏幕上的位置
所以 要想让文字居中显示 正确的代码是这样的

 paint.setTextAlign(Paint.Align.LEFT);
Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();
int heigit = getMeasuredHeight();
y = (heigit - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top; //173

2 水平滚动x坐标的计算

当文字居中显示后 y坐标也就固定了 由于文字是在水平方向上滚动 所以主要是y坐标的计算

x值的变动 使得文字从头滚动到尾
最开始 文字起点在屏幕最右边不可见 所以初试值为屏幕宽度 比如1080
滚动后 x值慢慢变少 当变为0 在文字长度大于屏幕宽度的情况下 比如文字长度为4304 一个屏幕宽度的文字移出到了屏幕右侧
最后 在x值为负值的情况下 文字完全移出在屏幕左侧 具体的值为 -4304 其实就是文字长度的负值
于是循环开始 文字又在初试位置 即屏幕右侧 具体值为1080

3 其它

主要是相关属性的设置 另外 该控件还可以扩展 比如点击事件 暂停停止等

public class MainActivity extends Activity {

    private AutoScrollTextView auto_tv;

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); auto_tv = (AutoScrollTextView) findViewById(R.id.auto_textview); auto_tv.setText("特定的时间内"); //设置文字内容
auto_tv.setScrollTextColor(Color.parseColor("#AB82FF")); //设置文字颜色
auto_tv.setScrollTextSize(12); //设置字体大小 以sp为单位
auto_tv.setScrollSpeed(4); //设置文字滚动速度
auto_tv.init(); auto_tv.startScroll();
}
}
public class AutoScrollTextView extends TextView {

 public boolean isStarting = false; //是否开始滚动
private float textLength = 0f; //文本长度
private float screenWidth = 0f; //屏幕宽度
private float x = 0f; //文字横坐标
private float y = 0f; //文字纵坐标
private String text = ""; //文本内容
private Paint paint = null; //绘图样式 private Context context;
private int color; //字体颜色
private float textSize; //字体大小 像素为单位
private float speed = 5; //文字滚动速度 实际是一个偏移像素值 越大速度越快 public AutoScrollTextView(Context context) {
super(context);
this.context = context;
} public AutoScrollTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
} public AutoScrollTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
} public void init() {
paint = getPaint(); paint.setColor(color);
paint.setTextSize(textSize); screenWidth = getScreenWidth(context); //1080 屏幕宽度 x = screenWidth;
} public void startScroll() {
isStarting = true;
invalidate();
} public void stopScroll() {
isStarting = false;
invalidate();
} public void setScrollTextColor(int color) {
this.color = color;
} public void setScrollTextSize(int spValue) {
this.textSize = sp2px(context, spValue);
} public void setScrollSpeed(float speed) {
this.speed = speed;
} @Override
public void onDraw(Canvas canvas) { text = getText().toString();
textLength = paint.measureText(text); //4310 文字长度 相当于四个屏幕宽度 //在这里计算y坐标
paint.setTextAlign(Paint.Align.LEFT);
Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();
int heigit = getMeasuredHeight();
y = (heigit - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top; // Log.i("TAG", "x-----------------x=" + x);
//Log.i("TAG", "y-----------------" + y); canvas.drawText(text, x, y, paint);
if (!isStarting) {
return;
} if (x < -textLength){
x = screenWidth;
}else {
x = x - speed;
} invalidate();
} private float sp2px(Context context, int spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (spValue * fontScale + 0.5f);
} private int getScreenWidth(Context context) {
return context.getResources().getDisplayMetrics().widthPixels;
}
}

Android滚动栏控件的优化的更多相关文章

  1. Android滚动选择控件

    现在觉得github特别方便,我一般直接使用github中的内容, https://github.com/wangjiegulu/WheelView 这里面都有详细的介绍

  2. Android 性能优化——之控件的优化

    Android 性能优化——之控件的优化 前面讲了图像的优化,接下来分享一下控件的性能优化,这里主要是面向自定义View的优化. 1.首先先说一下我们在自定义View中可能会犯的3个错误: 1)Use ...

  3. Android RecyclerView滚动类控件修改、去掉滑动边界的阴影效果

    前言 滚动类控件,大家都用的很多,如 RecyclerView.NestedSrollView.... 下面以recyclerView为例讲解,其他滚动控件也同理. RecyclerView 滚动列表 ...

  4. Android 中常见控件的介绍和使用

    1 TextView文本框 1.1 TextView类的结构 TextView 是用于显示字符串的组件,对于用户来说就是屏幕中一块用于显示文本的区域.TextView类的层次关系如下: java.la ...

  5. Android中ListView控件的使用

    Android中ListView控件的使用 ListView展示数据的原理 在Android中,其实ListView就相当于web中的jsp,Adapter是适配器,它就相当于web中的Servlet ...

  6. 【转】Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用

    Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用 分类: Android UI ...

  7. 【转】Android M新控件之FloatingActionButton,TextInputLayout,Snackbar,TabLayout的使用

    Android M新控件之FloatingActionButton,TextInputLayout,Snackbar,TabLayout的使用 分类: Android UI2015-06-15 16: ...

  8. 【风马一族_Android】第4章Android常用基本控件

    第4章Android常用基本控件 控件是Android用户界面中的一个个组成元素,在介绍它们之前,读者必须了解所有控件的父类View(视图),它好比一个盛放控件的容器. 4.1View类概述 对于一个 ...

  9. [置顶] Android常用适配器控件

    Android常用适配器控件 列表控件用于显示数据集合,Android不是使用一种类型的控件管理显示和数据,而是将这两项功能分布用列表控件和适配器来实现.列表控件扩展了android.widget.A ...

随机推荐

  1. 【算法分析】如何理解快慢指针?判断linked list中是否有环、找到环的起始节点位置。以Leetcode 141. Linked List Cycle, 142. Linked List Cycle II 为例Python实现

    引入 快慢指针经常用于链表(linked list)中环(Cycle)相关的问题.LeetCode中对应题目分别是: 141. Linked List Cycle 判断linked list中是否有环 ...

  2. JS中Text节点总结

    文本节点有Text类型表示,包含的是可以找字面解释的纯文本内容.纯文本中可以包含转移后的HTML字符,但不能包含HTML代码.Text节点具有以下属性: 1.nodeType的值为3. 2.nodeN ...

  3. 实用的ES6特性

    1. 函数参数默认值 不使用ES6 为函数的参数设置默认值: function foo(height, color) { var height = height || 50; var color = ...

  4. jspSmartUpload上传下载使用例子

    --------------------------------------------------------------------- ServletUpload.java 上传 package ...

  5. js 拼接字符串时,本来想要’#1′ ,返回的却是’#01′

    今天在操作一个元素时,id值是拼接的. var index = $(this).attr(‘index’);    //0var id = ‘#’ + (index+1);    //#01$(id) ...

  6. lintcode-141-x的平方根

    141-x的平方根 实现 int sqrt(int x) 函数,计算并返回 x 的平方根. 样例 sqrt(3) = 1 sqrt(4) = 2 sqrt(5) = 2 sqrt(10) = 3 挑战 ...

  7. Debian实验机 常用命令

    1.开启中文输入法 fcitx 2. 开启无线连接 wicd 3. 远程连接 ssh root@XXX.XXX.XXX.XXX 4. 启动Ulipad ~/ulipad-master# python ...

  8. TCP系列13—重传—3、协议中RTO计算和RTO定时器维护

    从上一篇示例中我们可以看到在TCP中有一个重要的过程就是决定何时进行超时重传,也就是RTO的计算更新.由于网络状况可能会受到路由变化.网络负载等因素的影响,因此RTO也必须跟随网络状况动态更新.如果T ...

  9. Vue自定义事件,$on(eventName) 监听事件,$emit(eventName) 触发事件

    <!--自定义事件 使用 $on(eventName) 监听事件 使用 $emit(eventName) 触发事件--> <div id="app15"> ...

  10. WIN7使用过360系统急救箱后出现的任务计划程序文件夹删除的办法

    直接进主题(怀疑系统有问题用了下360系统急救箱,用完后发现计划任务多了个360superkiller文件夹,右键直接是删除不了的) 尝试了各种方法都是不爽,突然想到计划任务不是在在系统盘下的一个文件 ...