想要详解Android自定义控件属性,我们需要明确三个核心的概念:自定义控件、属性和布局。自定义控件指的是继承自View或者其子类的自定义View;属性指的是我们可以通过在xml中设置的参数,来控制自定义View的展示;布局指的是如何将不同类型的View组合在一起形成一个整体。
在接下来的攻略中,我将围绕这三个核心的概念,一步一步地讲解如何创建一个具有自定义属性的LinearLayout自定义控件。
步骤1:创建布局文件
我们需要先创建一个布局文件,用来描述我们的自定义控件长什么样子。为了方便起见,我们创建一个LinearLayout布局文件,代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/icon"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_margin="16dp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/title"
android:textSize="24sp"
android:textColor="#000000"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/description"
android:textSize="18sp"
android:textColor="#444444"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
这个布局文件描述的是一个水平方向的LinearLayout,包含一个ImageView和一个垂直方向的LinearLayout,其中垂直方向的LinearLayout包含两个TextView。我们的目的是将这个布局文件封装成一个自定义控件,并添加一个自定义属性,用来控制ImageView中显示的图片的位置。
步骤2:创建自定义控件
我们需要创建一个类继承LinearLayout,代码如下:
public class CustomLayout extends LinearLayout {
private ImageView mIconView;
public CustomLayout(Context context) {
super(context);
init(context, null);
}
public CustomLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public CustomLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
LayoutInflater.from(context).inflate(R.layout.custom_layout, this, true);
mIconView = findViewById(R.id.icon);
// 读取自定义属性
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomLayout);
int iconGravity = typedArray.getInt(R.styleable.CustomLayout_icon_gravity, 0);
// 根据自定义属性设置ImageView的位置
LinearLayout.LayoutParams layoutParams = (LayoutParams) mIconView.getLayoutParams();
switch (iconGravity) {
case 0: // 左侧
layoutParams.gravity = Gravity.START;
mIconView.setLayoutParams(layoutParams);
break;
case 1: // 右侧
layoutParams.gravity = Gravity.END;
mIconView.setLayoutParams(layoutParams);
break;
}
typedArray.recycle();
}
}
我们在构造函数中调用init()方法来进行一些初始化工作。首先使用LayoutInflater从布局文件中将我们的布局添加为自定义控件的子View,然后读取自定义属性。自定义属性通过TypedArray对象进行读取,这个对象的创建方法需要传入当前Context和自定义属性的声明。在init()方法中,我们读取icon_gravity属性,并根据其值来设置ImageView的位置。
接下来,我们需要在values/attrs.xml文件中声明我们的自定义属性,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomLayout">
<attr name="icon_gravity">
<enum name="left" value="0" />
<enum name="right" value="1" />
</attr>
</declare-styleable>
</resources>
我们在declare-styleable标签中声明了CustomLayout这个自定义控件,然后在里面声明了一个名为icon_gravity的属性,这个属性类型是枚举类型,包含了left和right两个枚举常量。
步骤3:在布局文件中使用自定义控件
我们可以在布局文件中使用我们刚刚创建的CustomLayout布局,同时使用我们自定义的icon_gravity属性,代码如下:
<com.example.android.customlayout.CustomLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:icon_gravity="left">
<ImageView
android:id="@+id/icon"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_margin="16dp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/title"
android:text="@string/title"
android:textSize="24sp"
android:textColor="#000000"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/description"
android:text="@string/description"
android:textSize="18sp"
android:textColor="#444444"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</com.example.android.customlayout.CustomLayout>
我们通过将CustomLayout布局作为父布局,在自定义控件中引入ImageView和垂直方向的LinearLayout,同时使用app:icon_gravity属性来控制ImageView的位置。
至此,我们已经完成了一个具有自定义属性的自定义LinearLayout控件的创建过程,可以根据自己的需求来扩展自定义属性或者自定义其他类型的控件。
示例说明1:自定义属性为颜色
在步骤2中的init()方法中,我们可以通过TypedArray对象获取自定义属性,并根据其值来设置控件的颜色,代码如下:
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomView);
int color = typedArray.getColor(R.styleable.CustomView_custom_color, ContextCompat.getColor(context, R.color.default_color));
mPaint.setColor(color);
typedArray.recycle();
我们在values/attrs.xml文件中声明一个名为custom_color的属性,代码如下:
<declare-styleable name="CustomView">
<attr name="custom_color" format="color" />
</declare-styleable>
我们在布局文件中使用CustomView控件,并设置custom_color属性,代码如下:
<com.example.android.customview.CustomView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:custom_color="#FF4081"/>
示例说明2:自定义属性为布尔值
在步骤2中的init()方法中,我们可以通过TypedArray对象获取自定义属性,并根据其值来设置控件的状态,代码如下:
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomView);
boolean isShowText = typedArray.getBoolean(R.styleable.CustomView_show_text, true);
if (isShowText) {
mText = "Hello World";
}
typedArray.recycle();
我们在values/attrs.xml文件中声明一个名为show_text的属性,代码如下:
<declare-styleable name="CustomView">
<attr name="show_text" format="boolean" />
</declare-styleable>
我们在布局文件中使用CustomView控件,并设置show_text属性,代码如下:
<com.example.android.customview.CustomView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:show_text="false"/>
以上就是详解Android自定义控件属性的完整攻略,希望对你有所帮助!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Android自定义控件属性 - Python技术站