码迷,mamicode.com
首页 > 移动开发 > 详细

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

时间:2015-12-18 11:48:29      阅读:602      评论:0      收藏:0      [点我收藏+]

标签:

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

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

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

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

技术分享

view的实现:

 

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

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

1 <declare-styleable name="verticalstraighttextview">
2         <attr name= "text" format ="string" />
3         <attr name= "textColor" format ="reference|color" />
4         <attr name= "textColorPicked" format="reference|color" />
5         <attr name= "textSize" format="reference|dimension" />
6         <attr name= "charGap" format ="reference|dimension" />
7     </declare-styleable >

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

1 <cn.carbs.verticalstraighttextview.view.VerticalStraightTextView
2         android:id="@+id/kk"
3         android:layout_width="wrap_content"
4         android:padding="5dp"
5         android:layout_height="fill_parent"
6         android:background="#33333333"
7         app:textSize="20sp"
8         app:text= "#ABCEDFGHIJKLMN" />

 

在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             @Override
13             public boolean onTouch(View view, MotionEvent event) {
14                 switch(event.getAction()){
15                 case MotionEvent.ACTION_DOWN:
16                     verticalView.setPickedCharIndex(verticalView.getPickedCharIndex(event.getY()));
17                     break;
18                 case MotionEvent.ACTION_MOVE:
19                     verticalView.setPickedCharIndex(verticalView.getPickedCharIndex(event.getY()));
20                     break;
21                 case MotionEvent.ACTION_UP:
22                     verticalView.setPickedCharIndex(-1);
23                     break;
24                 case MotionEvent.ACTION_CANCEL:
25                     verticalView.setPickedCharIndex(-1);
26                     break;
27                 }
28                 return true;
29             }
30         });

 

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

标签:

原文地址:http://www.cnblogs.com/carbs/p/5056568.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!