<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
-- xmlns:myAttr="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.gjl.day03_after.MainActivity">
<!--
使用自定义TextView
1.将自定属性引入到布局文件
2。在控件里面使用
-->
<com.gjl.day03_after.views.MyTextView
android:id="@+id/mytextview"
--myAttr:content="hello----niaho"
android:background="#f00"
-- myAttr:myColor="#0f0"
-- myAttr:mySize="25sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
public class MyTextView extends View {
private static final String TAG = "MyTextView";
private String content;
private int color;
private float size;
private Paint mPaint;
public MyTextView(Context context) {
this(context, null);
}
public MyTextView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//在这里获取在布局文件里面的属性,然后将属性绘制到控件里面
// attrs 就是在xml布局文件里面设置的属性
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyTextView, defStyleAttr, 0);//获取样式属性的
//取出属性
//获取字符串
content = ta.getString(R.styleable.MyTextView_content);
color = ta.getColor(R.styleable.MyTextView_myColor, Color.BLUE);
size = ta.getDimension(R.styleable.MyTextView_mySize, 40);
android.util.Log.d(TAG, "MyTextView() returned: " + content + "--" + color + "--" + size);
//初始化画笔
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(color);
mPaint.setTextSize(size);
}
//绘制
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制文本
//参数1.要绘制的内容
//参数2.开始的x轴坐标
//参数3.开始的y轴坐标
//画笔
Rect rect = new Rect();
mPaint.getTextBounds(content,0,content.length(),rect);
canvas.drawText(content, 0, rect.height(), mPaint);
}
//测量的方法
//测量宽高的
//测量模式 和 测量尺寸
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//获取测量模式和测量的尺寸
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
//如果测量模式是EXACTLY 就直接显示测量尺寸就行
int width;
int height;
if (widthMode==MeasureSpec.EXACTLY){
width = widthSize;
}else {
//控件的宽度需要测量,
//控件的宽度 = 文字的宽度+左边距+右边距
Rect bound = new Rect();
mPaint.getTextBounds(content,0,content.length(),bound);//将文字用矩形括起来,那么矩形的尺寸就是文字的尺寸
int width1 = bound.width();
width = width1+getPaddingLeft()+getPaddingRight();
}
//处理高度
if (heightMode==MeasureSpec.EXACTLY){
height = heightSize;
}else {
//控件的高度 = 文字的高度+上边距+下边距
Rect bound = new Rect();
mPaint.getTextBounds(content,0,content.length(),bound);//将文字用矩形括起来,那么矩形的尺寸就是文字的尺寸
int height1 = bound.height();
height = height1+getPaddingTop()+getPaddingBottom();
}
//将宽高重新赋值
setMeasuredDimension(width,height);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
}
//attrs
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--
attr
attribute 属性
name 属性名
format 属性的属性类型
-->
<attr name="content" format="string"></attr>
<attr name="myColor" format="color"></attr>
<attr name="mySize" format="dimension"></attr>
<!--
将定义好的属性放入属性列表
-->
<declare-styleable name="MyTextView">
<attr name="content"></attr>
<attr name="myColor"></attr>
<attr name="mySize"></attr>
</declare-styleable>
</resources>
/*
//android自定义控件实现跟随手指移动的小球
1.自定义控件类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
package
com.dc.customview.view;
import
android.content.Context;
import
android.graphics.Canvas;
import
android.graphics.Color;
import
android.graphics.Paint;
import
android.util.AttributeSet;
import
android.view.MotionEvent;
import
android.view.View;
import
android.view.WindowManager;
public
class
DrawCircle
extends
View {
//圆的初始位置
private
int
x =
100
;
private
int
y =
100
;
Context context;
/**
* 有style资源文件时调用
* @param context
* @param attrs
* @param defStyle
*/
public
DrawCircle(Context context, AttributeSet attrs,
int
defStyle) {
super
(context, attrs, defStyle);
this
.context = context;
}
/**
* xml创建时调用
* @param context
* @param attrs
*/
public
DrawCircle(Context context, AttributeSet attrs) {
super
(context, attrs);
this
.context = context;
}
/**
* java代码创建时调用
* @param context
*/
public
DrawCircle(Context context) {
super
(context);
this
.context = context;
}
@Override
protected
void
onDraw(Canvas canvas) {
super
.onDraw(canvas);
// 画笔
Paint paint =
new
Paint();
paint.setColor(Color.RED);
//绘制圆
//cx :圆心的x坐标
//cy :圆心的y坐标
//radius :圆的半径
//paint :画笔
canvas.drawCircle(x, y,
20
, paint);
}
@Override
public
boolean
onTouchEvent(MotionEvent event) {
switch
(event.getAction()) {
case
MotionEvent.ACTION_DOWN:
case
MotionEvent.ACTION_MOVE:
case
MotionEvent.ACTION_UP:
// 获取当前触摸点的x,y坐标
x = (
int
) event.getX();
y = (
int
) event.getY();
break
;
}
//获取屏幕宽高
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
int
width = manager.getDefaultDisplay().getWidth();
int
heigh = manager.getDefaultDisplay().getHeight();
//重新绘制圆 ,控制小球不会被移出屏幕
if
(x>=
20
&& y>=
20
&& x<=width-
20
&& y<=heigh-
90
){
invalidate();
}
// 自己处理触摸事件
return
true
;
}
}
|
2.引用自定义控件
第一种:xml中引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
android:id
=
"@+id/rl"
>
<!-- 自定义控件的全类名 -->
<
com.dc.customview.view.DrawCircle
android:id
=
"@+id/circle"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
>
</
com.dc.customview.view.DrawCircle
>
</
RelativeLayout
>
|
第二种:代码中引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
package
com.dc.customview;
import
com.dc.customview.view.DrawCircle;
import
android.os.Bundle;
import
android.app.Activity;
import
android.view.Menu;
import
android.view.View;
import
android.widget.RelativeLayout;
public
class
MainActivity
extends
Activity {
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取容器
RelativeLayout container = (RelativeLayout) findViewById(R.id.rl);
//创建自定义控件
DrawCircle circle =
new
DrawCircle(
this
);
//添加到容器
container.addView(circle);
}
}*/
|