android 自定义view 怎么规定view的样式

2025-01-07 22:31:16
推荐回答(2个)
回答1:

android 自定义view的样式的实现:

1.在values文件夹下,打开attrs.xml,其实这个文件名称可以是任意的,写在这里更规范一点,表示里面放的全是view的属性。

2.因为我们下面的实例会用到2个长度,一个颜色值的属性,所以我们这里先创建3个属性。


 
 
 

举例说明:

蓝色的进度条

public class RainbowBar extends View {

 //progress bar color
 int barColor = Color.parseColor("#1E88E5");
 //every bar segment width
 int hSpace = Utils.dpToPx(80, getResources());
 //every bar segment height
 int vSpace = Utils.dpToPx(4, getResources());
 //space among bars
 int space = Utils.dpToPx(10, getResources());
 float startX = 0;
 float delta = 10f;
 Paint mPaint;

 public RainbowBar(Context context) {
   super(context);
 }

 public RainbowBar(Context context, AttributeSet attrs) {
   this(context, attrs, 0);
 }

 public RainbowBar(Context context, AttributeSet attrs, int defStyleAttr) {
   super(context, attrs, defStyleAttr);
   //read custom attrs
   TypedArray t = context.obtainStyledAttributes(attrs,
           R.styleable.rainbowbar, 0, 0);
   hSpace = t.getDimensionPixelSize(R.styleable.rainbowbar_rainbowbar_hspace, hSpace);
   vSpace = t.getDimensionPixelOffset(R.styleable.rainbowbar_rainbowbar_vspace, vSpace);
   barColor = t.getColor(R.styleable.rainbowbar_rainbowbar_color, barColor);
   t.recycle();   // we should always recycle after used
   mPaint = new Paint();
   mPaint.setAntiAlias(true);
   mPaint.setColor(barColor);
   mPaint.setStrokeWidth(vSpace);
 }

 .......
}

View有了三个构造方法需要我们重写,这里介绍下三个方法会被调用的场景,

第一个方法,一般我们这样使用时会被调用,View view = new View(context);

第二个方法,当我们在xml布局文件中使用View时,会在inflate布局时被调用,

第三个方法,跟第二种类似,但是增加style属性设置,这时inflater布局时会调用第三个构造方法。

回答2:

很多的Android入门程序猿来说对于Android自定义View,可能都是比较恐惧的,但是这又是高手进阶的必经之路,所有准备在自定义View上面花一些功夫,多写一些文章。先总结下自定义View的步骤:
1、自定义View的属性
2、在View的构造方法中获得我们自定义的属性
[ 3、重写onMesure ]
4、重写onDraw
我把3用[]标出了,所以说3不一定是必须的,当然了大部分情况下还是需要重写的。
1、自定义View的属性,首先在res/values/ 下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
















我们定义了字体,字体颜色,字体大小3个属性,format是值该属性的取值类型:
一共有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;不清楚的可以google一把。
然后在布局中声明我们的自定义View

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14

xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01"
android:layout_width="match_parent"
android:layout_height="match_parent" >

android:layout_width="200dp"
android:layout_height="100dp"
custom:titleText="3712"
custom:titleTextColor="#ff0000"
custom:titleTextSize="40sp" />



一定要引入 xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01"我们的命名空间,后面的包路径指的是项目的package

2、在View的构造方法中,获得我们的自定义的样式

?

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

/**
* 文本
*/
private String mTitleText;
/**
* 文本的颜色
*/
private int mTitleTextColor;
/**
* 文本的大小
*/
private int mTitleTextSize;

/**
* 绘制时控制文本绘制的范围
*/
private Rect mBound;
private Paint mPaint;

public CustomTitleView(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}

public CustomTitleView(Context context)
{
this(context, null);
}

/**
* 获得我自定义的样式属性
*
* @param context
* @param attrs
* @param defStyle
*/
public CustomTitleView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
/**
* 获得我们所定义的自定义样式属性
*/
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0);
int n = a.getIndexCount();
for (int i = 0; i < n; i++)
{
int attr = a.getIndex(i);
switch (attr)
{
case R.styleable.CustomTitleView_titleText:
mTitleText = a.getString(attr);
break;
case R.styleable.CustomTitleView_titleTextColor:
// 默认颜色设置为黑色
mTitleTextColor = a.getColor(attr, Color.BLACK);
break;
case R.styleable.CustomTitleView_titleTextSize:
// 默认设置为16sp,TypeValue也可以把sp转化为px
mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break;

}

}
a.recycle();

/**
* 获得绘制文本的宽和高
*/
mPaint = new Paint();
mPaint.setTextSize(mTitleTextSize);
// mPaint.setColor(mTitleTextColor);
mBound = new Rect();
mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);

}

我们重写了3个构造方法,默认的布局文件调用的是两个参数的构造方法,所以记得让所有的构造调用我们的三个参数的构造,我们在三个参数的构造中获得自定义属性。