• Android滚动栏控件的优化


    背景 由于普通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; //173
    
     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;
        }
    }
  • 相关阅读:
    OI回忆录——一个过气OIer的制杖历程
    博客园美化手记——CSS javascript html
    ProjectEuler && Rosecode && Mathmash做题记录
    算法竞赛推荐
    2020智算之道复赛E 树数数
    牛客编程巅峰赛S1第9场
    c++小学期大作业攻略(五)基于QSS的样式美化
    c++小学期大作业攻略(四)任务系统+站内信
    c++小学期大作业攻略(三)用户系统
    c++小学期大作业攻略(零)建议+代码结构(持续更新)
  • 原文地址:https://www.cnblogs.com/huanyi0723/p/5801720.html
Copyright © 2020-2023  润新知