Android Api Demos登顶之路(104)View-->Custom
来源:互联网 发布:大师兄 知乎 编辑:程序博客网 时间:2024/05/22 10:26
/*这个demo演示了如何使用自定义的View。在本例中自定义了一个LableView,并且自定义了 * text、textColor、textSize三个自定义的属性*/public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }}
在resource/values目录下新建attrs.xml创建自定义属性:
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="LabelView"> <attr name="text" format="string"/> <attr name="textColor" format="color"/> <attr name="textSize" format="dimension"/> </declare-styleable></resources>
创建自定义视图LabelView
public class LabelView extends View { private Paint mTextPaint; // 需要绘制的文本 private String mText; // 文本的基准线至最高点的距离 private int mAscent; public LabelView(Context context) { super(context); initLabelView(); } // 重写该方法是为了在layout中使用自定义的属性 public LabelView(Context context, AttributeSet attrs) { super(context, attrs); initLabelView(); // 获取到自定义的属性集合 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LabelView); // 获取text属性的值 CharSequence s = a.getString(R.styleable.LabelView_text); if (s != null) { setText(s.toString()); } setTextColor(a.getColor(R.styleable.LabelView_textColor, 0xff000000)); int textSize = a.getDimensionPixelOffset( R.styleable.LabelView_textSize, 0); if (textSize > 0) { setTextSize(textSize); } // 注意用完之后一定要回收属性集合 a.recycle(); } private void setTextSize(int textSize) { mTextPaint.setTextSize(textSize); requestLayout(); invalidate(); } private void setTextColor(int color) { mTextPaint.setColor(color); invalidate(); } private void setText(String text) { mText = text; // view显示的文本发生变化,需要重新绘制,并改变layout的布局 requestLayout(); invalidate(); } private void initLabelView() { mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // 将大小转化为适合当前屏幕的尺寸 mTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density); mTextPaint.setColor(Color.BLACK); setPadding(3, 3, 3, 3); } /* * widthMeasureSpec是由父窗体传入的根据父窗体的布局、边距等属性计算出的子View的大小。 * 该值由高32位和低16位组成,高32位用来表示specMode:共有三个值:MeasureSpec.EXACTLY、 * MeasureSpec.AT_MOST、MeasureSpec.UNSPECIFIED */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } private int measureHeight(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); mAscent=(int) mTextPaint.ascent(); System.out.println("ascent:"+mAscent); //父视图希望子视图的大小应该是specSize中指定的。 if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else { result = (int) (-mAscent+mTextPaint.descent() + getPaddingBottom() + getPaddingTop()); if(specMode==MeasureSpec.AT_MOST){ result=Math.min(result, specSize); } } return result; } private int measureWidth(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else { result = (int) (mTextPaint.measureText(mText) + getPaddingLeft() + getPaddingRight()); if(specMode==MeasureSpec.AT_MOST){ result=Math.min(result, specSize); } } return result; } @Override protected void onDraw(Canvas canvas) { canvas.drawText(mText, getPaddingLeft(), getPaddingTop()-mAscent, mTextPaint); }}
在布局文件中应用自定义视图
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:lab="http://schemas.android.com/apk/res/com.fishtosky.customview" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.fishtosky.customview.LabelView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ffff0000" lab:text="Red" /> <com.fishtosky.customview.LabelView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ff0000ff" lab:text="Blue" lab:textSize="20sp"/> <com.fishtosky.customview.LabelView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ff00ff00" lab:text="Green" lab:textColor="#ffffffff" /></LinearLayout>
0 0
- Android Api Demos登顶之路(104)View-->Custom
- Android Api Demos登顶之路(四十六)Loader-->Custom
- Android Api Demos登顶之路(107)View-->ExpanableLists-->Custom Adapter
- Android Api Demos登顶之路(102)View-->Buttons
- Android Api Demos登顶之路(103)View-->Chronometer
- Android Api Demos登顶之路(106)View-->DragAndDrop
- Android Api Demos登顶之路(三十六)Fragment-->Custom Animation
- Android Api Demos登顶之路(100)View-->AutoComplete:Contacts
- Android Api Demos登顶之路(101)View-->AutoComplete:Multiple items
- Android Api Demos登顶之路(105)View-->Date widgets-->dialog
- Android Api Demos登顶之路(108)View-->ExpanableLists-->Cursor
- Android Api Demos登顶之路(109)View-->ExpanableLists-->Simple Adapter
- Android Api Demos登顶之路(110)View-->Lists-->Transcript
- Android Api Demos登顶之路(111)Views-->Seacure View
- Android Api Demos登顶之路(二)
- Android Api Demos登顶之路(三)
- Android Api Demos登顶之路(四)
- Android Api Demos登顶之路(五)
- 第几天?
- Android 命名规范 (提高代码可以读性)
- 起凡 群雄逐鹿 改键器 连发器 神器 v1.4
- 开启ubuntu默认root的权限(su: Authentication failure)
- 蟠桃记
- Android Api Demos登顶之路(104)View-->Custom
- 基于用户的协同过滤算法的讨论
- 利用Linux系统函数实现线程池(C++)
- 母牛的故事
- 查看和修改mysql5.6端口
- 实验一小下
- 论Android Adapter notifyDataSetChanged与notifyDataSetInvalidated无效原因
- SD卡
- android学习4:Service