博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android中自定义view---实现竖直方向的文字功能,文字方向朝上,同时提供接口,判断当前touch的是哪个字符,并改变颜色...
阅读量:6001 次
发布时间:2019-06-20

本文共 12386 字,大约阅读时间需要 41 分钟。

android自定义view,实现竖直方向的文字功能,文字方向朝上,同时提供接口,判断当前touch的是哪个字符,并改变颜色。

由于时间比较仓促,因此没有对代码进行过多的优化,功能远远不如android的自带的TextView强大,只是继承于view,而不是textview。

主要用途:电话本的侧边快速导航等

效果图:(自定义字符串 “#ABCDEFGHIJKLMN),可以实现自定义任意字符串

view的实现:

 

1 package cn.carbs.verticalstraighttextview.view;  2   3 import cn.carbs.verticalstraighttextview.R;  4 import android.content.Context;  5 import android.content.res.TypedArray;  6 import android.graphics.Canvas;  7 import android.graphics.Paint.Align;  8 import android.graphics.Rect;  9 import android.text.TextPaint; 10 import android.util.AttributeSet; 11 import android.util.Log; 12 import android.util.TypedValue; 13 import android.view.View; 14 /** 15  * 参考资料: 16  *         http://chris.banes.me/2014/03/27/measuring-text/ 17  *         http://blog.163.com/gobby_1110/blog/static/2928171520136304172378/ 18  * @author Rick.Wang 19  * 20  */ 21 public class VerticalStraightTextView extends View { 22      23     private final static int DEFAULT_TEXT_SIZE = 15;   24     private final static int DEFAULT_TEXT_COLOR = 0xFF000000; 25     private final static int DEFAULT_TEXT_COLOR_PICKED = 0xFF990000; 26     private final static int DEFAULT_CHAR_SPACE = 0; 27      28     private TextPaint mTextPaint;   29     private TextPaint mTextPaintPicked; 30     private String mText = ""; 31      32     private int mTextLength = 0; 33     private int mCharGap = 0; 34     private int mCharWidth = 0; 35     private int mCharHeight = 0; 36      37     private int currPickedCharIndex = -1; 38      39     float[] coordinates = null; 40      41     public float[] getCoordinates(){ 42         return coordinates; 43     } 44      45     public VerticalStraightTextView(Context context) {   46         super(context);   47         init();   48     }   49    50     public VerticalStraightTextView(Context context, AttributeSet attrs) {   51         super(context, attrs);   52         init();   53    54         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.verticalstraighttextview);   55          56         int n = a.getIndexCount();   57         for (int i = 0; i < n; i++) { 58             int attr = a.getIndex(i);   59             switch (attr) {   60             case R.styleable.verticalstraighttextview_text: 61                 mText = a.getString(attr); 62                 if(mText == null){ 63                     mText = ""; 64                     break; 65                 } 66                 mTextLength = mText.length(); 67                 break;   68             case R.styleable.verticalstraighttextview_textSize:   69                 int textSize = a.getDimensionPixelOffset(R.styleable.verticalstraighttextview_textSize, DEFAULT_TEXT_SIZE);   70                 if (textSize > 0) { 71                     mTextPaint.setTextSize(textSize); 72                     mTextPaintPicked.setTextSize(textSize); 73                 } 74                 break;   75  76             case R.styleable.verticalstraighttextview_charGap: 77                 mCharGap = a.getDimensionPixelSize(R.styleable.verticalstraighttextview_charGap, (int) TypedValue.applyDimension(   78                         TypedValue.COMPLEX_UNIT_PX, DEFAULT_CHAR_SPACE, getResources().getDisplayMetrics()));  79                 break;   80             case R.styleable.verticalstraighttextview_textColor:   81                 mTextPaint.setColor(a.getColor(R.styleable.verticalstraighttextview_textColor, DEFAULT_TEXT_COLOR)); 82                 break;   83             case R.styleable.verticalstraighttextview_textColorPicked:   84                 mTextPaintPicked.setColor(a.getColor(R.styleable.verticalstraighttextview_textColorPicked, DEFAULT_TEXT_COLOR_PICKED)); 85                 break;   86             }   87         }   88         a.recycle();   89          90         requestLayout();   91         invalidate();   92     }   93    94     private final void init() {   95         mTextPaint = new TextPaint();   96         mTextPaint.setAntiAlias(true);   97         mTextPaint.setTextSize(DEFAULT_TEXT_SIZE);   98         mTextPaint.setTextAlign(Align.CENTER); 99         mTextPaintPicked = new TextPaint(mTextPaint);100         mTextPaint.setColor(DEFAULT_TEXT_COLOR);101         mTextPaintPicked.setColor(DEFAULT_TEXT_COLOR_PICKED);102     }  103   104     public void setText(String text) {105         if(text == null){106             text = "";107         }108         if(!mText.equals(text)){109             mText = text;  110             mTextLength = text.length();111             requestLayout();  112             invalidate();  113         }114     }  115   116     public void setTextSize(int size) {117         if(mTextPaint.getTextSize() != size){118             mTextPaint.setTextSize(size);  119             mTextPaintPicked.setTextSize(size);120             requestLayout();  121             invalidate();  122         }123     }  124   125     public void setTextColor(int color) {126         if(color != mTextPaint.getColor()){127             mTextPaint.setColor(color);128             invalidate();  129         }130     }131     132     public void setTextColorPicked(int color) {133         if(color != mTextPaintPicked.getColor()){134             mTextPaintPicked.setColor(color);135             invalidate();  136         }137     }138     139     public int getCharHeight(){140         return mCharGap + mCharHeight;141     }142   143     @Override  144     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  145         Log.d("1218", "onMeasure");146         //获取字体宽度147         float maxCharWidth = 0f;148         for(int i = 0; i < mTextLength; i++){149              maxCharWidth = Math.max(mTextPaint.measureText(mText.substring(i, i+1)), maxCharWidth);150         }151         mCharWidth = (int)Math.ceil(maxCharWidth);152         153         //获取字体高度154         Rect textBounds = new Rect();155         mTextPaint.getTextBounds(mText, 0, mTextLength, textBounds);156         mCharHeight = textBounds.height();157         158         setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));159     }160     161     private int measureWidth(int measureSpec) {  162         int result = 0;  163         int specMode = MeasureSpec.getMode(measureSpec);  164         int specSize = MeasureSpec.getSize(measureSpec);  165   166         if (specMode == MeasureSpec.EXACTLY) {  167             result = specSize;168         } else {  169             result = this.getPaddingLeft() + this.getPaddingRight() + mCharWidth;170             if (specMode == MeasureSpec.AT_MOST) {171                 result = Math.min(result, specSize);  172             }173         }174         return result;  175     }  176   177     private int measureHeight(int measureSpec) {  178         int result = 0;  179         int specMode = MeasureSpec.getMode(measureSpec);  180         int specSize = MeasureSpec.getSize(measureSpec);  181 182         if (specMode == MeasureSpec.EXACTLY) {  183             result = specSize;  184         } else {  185             result = getPaddingTop() + getPaddingBottom();186             if(mTextLength > 0){187                 result += mTextLength * (mCharGap + mCharHeight) - mCharGap;188             }189             if (specMode == MeasureSpec.AT_MOST) {  190                 result = Math.min(result, specSize);  191             }  192         }  193         return result;194     }  195 196     @Override  197     protected void onDraw(Canvas canvas) {  198         super.onDraw(canvas);  199         Log.d("1218", "onDraw");200         if(mTextLength == 0){201             return;202         }203         204         int height = getMeasuredHeight();205         int measuredWidth = getMeasuredWidth();206         207         int paddingTop = getPaddingTop();208         int paddingBottom = getPaddingBottom();209         int paddingLeft = getPaddingLeft();210         int paddingRight = getPaddingRight();211         212         //默认居中213         int x = paddingLeft + (measuredWidth - paddingLeft - paddingRight)/2;214         int y = 0;215         216         int cellHeight = (height - paddingTop - paddingBottom)/ mTextLength;217         //TODO 可能会有bug218         if(coordinates == null || coordinates.length != mTextLength){219             coordinates = new float[mTextLength + 1];220         }221         coordinates[0] = 0;222         for(int i = 0; i < mTextLength; i++){223             y = paddingTop + i * cellHeight + cellHeight/2;224             coordinates[i + 1] = y + cellHeight/2;225             if(currPickedCharIndex != i){226                 canvas.drawText(mText, i, i + 1, x, y, mTextPaint);227             }else{228                 canvas.drawText(mText, i, i + 1, x, y, mTextPaintPicked);229             }230         }231         coordinates[mTextLength] = height;232     }233     234     //y is the coordinate-Y235     //this function can return the "touched char"236     public int getPickedCharIndex(float[] coordinates, float y){237         int start = 0;238         int end = coordinates.length - 1;239         while (start != end - 1) {240             int middle = (start + end) / 2;241             if (y < coordinates[middle]) {242                 end = middle;243             } else if (y > coordinates[middle]) {244                 start = middle;245             }246         }247         return start;248     }249     250     251     /***************************************252      * 253      *         +---------------+  <-- Y == coordinates[0]254      *         |        #        |255      *         |---------------|            coordinates[1]256      *         |        A        |257      *         |---------------|            coordinates[2]258      *         |        B        |259      *         |---------------|            coordinates[3]260      *         |        C        |261      *         +---------------|            coordinates[4]262      ***************************************/263     264     public int getPickedCharIndex(float y){265         //优化查询266         //如果当前的>-1,说明正在touchEvent267         if(currPickedCharIndex > -1){268             if(coordinates[currPickedCharIndex] < y && y < coordinates[currPickedCharIndex+1]){269                 return currPickedCharIndex;270             }271         }272         273         int start = 0;274         int end = coordinates.length - 1;275         while (start != end - 1) {276             int middle = (start + end) / 2;277             if (y < coordinates[middle]) {278                 end = middle;279             } else if (y > coordinates[middle]) {280                 start = middle;281             }282         }283         return start;284     }285     286     287     public void setCurrPickedCharIndex(int index){288         if(currPickedCharIndex != index){289             currPickedCharIndex = index;290             invalidate();291         }292     }293 294 }

style文件的定义:(将此代码写入values文件夹下的styles.xml文件中)

1 
2
3
4
5
6
7

布局文件引入此自定义view:

1 

 

在activity中的使用:

1 verticalView = (VerticalStraightTextView)this.findViewById(R.id.kk); 2          3         verticalView.setOnClickListener(new View.OnClickListener() { 4             @Override 5             public void onClick(View v) { 6                 Toast.makeText(getApplicationContext(), "onclick", Toast.LENGTH_SHORT).show(); 7             } 8         }); 9        10         verticalView.setOnTouchListener(new View.OnTouchListener() {11             12             @Override13             public boolean onTouch(View view, MotionEvent event) {14                 switch(event.getAction()){15                 case MotionEvent.ACTION_DOWN:16                     verticalView.setCurrPickedCharIndex(verticalView.getPickedCharIndex(event.getY()));17                     break;18                 case MotionEvent.ACTION_MOVE:19                     verticalView.setCurrPickedCharIndex(verticalView.getPickedCharIndex(event.getY()));20                     break;21                 case MotionEvent.ACTION_UP:22                     verticalView.setCurrPickedCharIndex(-1);23                     break;24                 case MotionEvent.ACTION_CANCEL:25                     verticalView.setCurrPickedCharIndex(-1);26                     break;27                 }28                 return true;29             }30         });

 

转载地址:http://djdmx.baihongyu.com/

你可能感兴趣的文章
linux上架设l2tp+ipsec ***服务器
查看>>
Facebook和用户界面会如何扭曲你说的话
查看>>
安卓混合开发之Cordova,NativeWebView两种实现
查看>>
桶排序
查看>>
石化数字化交付
查看>>
如何用windows Live writer 撰写blog
查看>>
RHEL6入门系列之十九,硬盘分区与格式化
查看>>
Linux下升级 OpenSSH
查看>>
标准功能模块组件 -- 名片管理组件,C\S 版本的标准用例程序,可以参考权限实现方法...
查看>>
zygote进程图
查看>>
ldap快速配置
查看>>
docker之docker-machine用法
查看>>
IIS 7启用static JSON文件能POST方法
查看>>
P5205 【模板】多项式开根
查看>>
微博mini for Windows Phone 8 开发那些事
查看>>
redis文章索引
查看>>
OpenSSH利用处理畸形长度密码造成的时间差,枚举系统用户(CVE-2016-6210)
查看>>
Javascript回调函数
查看>>
可能是最简单的面向对象入门教程(二)为什么要有类型
查看>>
配置Openfiler做ISCS实验
查看>>