您的位置:首页 > 其它

为自定义View添加属性

2017-07-15 22:22 260 查看

为自定义View添加属性

每一个控件在布局或是代码中都有其属性:

<TextView
android:id="@+id/tv_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="18sp"
android:maxLines="1"/>


像id,layout_width,gravity…这是Android已经定义好的控件属性,在java代码中还有setText()方法等,为空间的使用提供了很多便捷。

自定义属性的步骤:

1.在attrs.xml文件中声明属性,有属性名:name和格式:format.

<!--自定义ToggleButton,声明属性集的名称-->
<declare-styleable name="MyToggleButton">
<!--声明一个属性 name format-->
<attr name="my_background" format="reference"/>
<attr name="my_slide_btn" format="reference"/>
<attr name="curr_state" format="boolean"/>
</declare-styleable>


format常用类型:

reference 引用

color 颜色

boolean 布尔值

dimension 尺寸值

float 浮点值

integer 整型值

string 字符串

enum 布尔值

2.在布局文件中使用新属性,使用之前必须声明命名空间,如:

xmlns:myview="http://schemas.android.com/apk/res/com.example.myview"

<com.jeff.customview.view.MyToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
myview:curr_state="false"
myview:my_background="@mipmap/switch_background"
myview:my_slide_btn="@mipmap/slide_button"/>


3.在自定义view的构造方法中,通过AttributeSet对象,获得所需要的属性值

/**
* 自定义ToggleButton
*
* view对象显示在屏幕上的步骤
* 1.构造方法创建对象
* 2.测量view大小 onMeasure()
* 3.确定view的位置,view自身有一些建议权,决定权在父view手中, onlayout()
* 4.绘制view的内容,onDraw(Canvas)
*/

public class MyToggleButton extends View implements View.OnClickListener {
private static final String TAG = "MyToggleButton";

private Bitmap bgBitmap;//背景图片
private Bitmap slideBtn;//滑动按钮
private Paint paint;//画笔
private float slideBtn_left = 0;//slideBtn左边界

private int backgroundId;//背景图片的资源ID
private int slideBtnId;//滑动按钮的资源ID
private boolean currentState = false;//按钮状态

/**
* 在代码中创建对象时调用
*
* @param context
*/
public MyToggleButton(Context context) {
super(context);
}

/**
* 在布局文件声明的view,创建时由系统自动调用
*
* @param context
* @param attrs
*/
public MyToggleButton(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);

//无命名空间测试(未添加到attrs)
//获取的属性值为字符串
String testAttr=attrs.getAttributeValue(null,"testAttr");
Log.d(TAG, "MyToggleButton: testAttr= "+testAttr);

//获取自定义属性
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyToggleButton);
int count = ta.getIndexCount();
for (int i = 0; i < count; i++) {
//获取某个属性的ID
int itemId = ta.getIndex(i);
switch (itemId) {
case R.styleable.MyToggleButton_my_background:
backgroundId = ta.getResourceId(itemId, -1);
Log.d(TAG, "MyToggleButton: backgroundId= "+backgroundId);
if (backgroundId==-1){
throw new RuntimeException("please set the imgRec of background");
}
bgBitmap= BitmapFactory.decodeResource(getResources(), backgroundId);
break;
case R.styleable.MyToggleButton_my_slide_btn:
slideBtnId = ta.getResourceId(itemId, -1);
if (slideBtnId==-1){
throw new RuntimeException("please set the imgRec of slideBtn");
}
slideBtn= BitmapFactory.decodeResource(getResources(), slideBtnId);
break;
case R.styleable.MyToggleButton_curr_state:
currentState = ta.getBoolean(itemId, false);
break;
}
}

initView();
}

private void initView() {
//初始化图片
//        bgBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.switch_background);
//        slideBtn = BitmapFactory.decodeResource(getResources(), R.mipmap.slide_button);

//初始化画笔
paint = new Paint();
paint.setAntiAlias(true);//抗锯齿

//添加点击事件监听
setOnClickListener(this);

flushState();
}

/**
* 测量view大小时调用
*
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//设置当前view大小
setMeasuredDimension(bgBitmap.getWidth(), bgBitmap.getHeight());
}

/**
* 确定位置时调用
* 自定义view时作用不大
*
* @param changed
* @param left
* @param top
* @param right
* @param bottom
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}

/**
* 绘制view时调用
*
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
//绘制背景
canvas.drawBitmap(bgBitmap, 0, 0, paint);
//绘制可滑动按钮
canvas.drawBitmap(slideBtn, slideBtn_left, 0, paint);
}

@Override
public void onClick(View v) {
flushState();
currentState = !currentState;
}

/**
* 刷新当前状态
*/
private void flushState() {
if (currentState) {
slideBtn_left = bgBitmap.getWidth() - slideBtn.getWidth();
} else {
slideBtn_left = 0;
}

//刷新当前view,会重调onDraw方法
invalidate();
}
}


效果展示:

项目用到的图片:





效果图:



查看布局中控件的属性

//构造方法
public CustomAttrs(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
int count=attrs.getAttributeCount();
for (int i = 0; i < count; i++) {
String name=attrs.getAttributeName(i);
String value=attrs.getAttributeValue(i);
Log.d(TAG, "CustomAttrs:  name= "+name+"  value= "+value);
}
}

//log
CustomAttrs:  name= layout_width  value= -2
CustomAttrs:  name= layout_height  value= -2
CustomAttrs:  name= test_msg  value= @2131099681
CustomAttrs:  name= test_bitmap  value= @2130903052
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  自定义view