概述
自定义控件以及自定义控件属性
一.自定义控件
![](https://file2.kaopuke.com:8081/files_image/2023060522/202306052208005425264.png)
1.为什么要用自定义控件?
我们所有的控件都是直接或者简介继承自view,所用的布局都是直接或者间接继承自ViewGroup的。View是android中最基本的UI组件,他可以在屏幕上绘制一块矩形区域,并且能响应这块区域的各种事件,因此我们使用的各种控件其实就是在View的基础上又添加了各自特有的功能。而ViewGroup则是一中队特殊的View,他可以包含很多的子View和子ViewGroup,是一个用于放置空间和布局的容器(引用郭霖大神的第一行代码上),因此当系统的空间不能够满足我们的要求时,我们。可以自定义各种控件,例如:
![](https://file2.kaopuke.com:8081/files_image/2023060522/202306052208004484919.jpg)
![](https://file2.kaopuke.com:8081/files_image/2023060522/202306052208019724290.png)
![](https://file2.kaopuke.com:8081/files_image/2023060522/202306052208018919710.png)
这些控件可以被反复利用,我们不想在用到的时候反复写,因此可以创建我们自己的控件。
2.怎么创建自定义控件?
(1)所见即所得:写布局文件
既然是控件,那么他肯定是有形状有作用的,我们可以通过布局文件将其描述出来(这里我写一个软件经常用到的控件,在很多软件的设置里都有开启/关闭某项功能的选项,这个控件需要反复利用,上面第三个控件),所见即所得,这个控件包含4个控件,即两个TextView和一个CheckBox还有一个View(下划线),那就顺理成章的写出布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="70dp">
<TextView
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:textSize="22dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_setting_text"
android:text="设置是否进行自动更新"
android:textColor="#000000"/>
<TextView
android:layout_marginLeft="10dp"
android:textSize="20dp"
android:layout_below="@id/tv_setting_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_setting_content"/>
//这里的clickable和focusable是为了后来能够点击整个控件进行选择而不是只能点击CheckBox
<CheckBox
android:clickable="false"
android:focusable="false"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:id="@+id/cb_setting_choose"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<View
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="0.5dp"
android:layout_alignParentBottom="true"
android:background="#000000"
></View>
</RelativeLayout>
(1)所见即所得:写布局文件
既然是控件,那么他肯定是有形状有作用的,我们可以通过布局文件将其描述出来(这里我写一个软件经常用到的控件,在很多软件的设置里都有开启/关闭某项功能的选项,这个控件需要反复利用,上面第三个控件),所见即所得,这个控件包含4个控件,即两个TextView和一个CheckBox还有一个View(下划线),那就顺理成章的写出布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="70dp">
<TextView
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:textSize="22dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_setting_text"
android:text="设置是否进行自动更新"
android:textColor="#000000"/>
<TextView
android:layout_marginLeft="10dp"
android:textSize="20dp"
android:layout_below="@id/tv_setting_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_setting_content"/>
//这里的clickable和focusable是为了后来能够点击整个控件进行选择而不是只能点击CheckBox
<CheckBox
android:clickable="false"
android:focusable="false"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:id="@+id/cb_setting_choose"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<View
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="0.5dp"
android:layout_alignParentBottom="true"
android:background="#000000"
></View>
</RelativeLayout>
(2)静态页面给他添加逻辑:创建控件的类实现某些逻辑
这里因为上面的控件是RelatieLayout,因此创建一个类继承自RelativeLayout,在这里面我们需要做的有两件事:第一我们
要将上面的布局文件加载进来(inflate),第二我们要实现各个部分控件的逻辑(比如点击过后有哪些逻辑需要实现)。
package com.blossoming.mobilesafe.UI;
这里因为上面的控件是RelatieLayout,因此创建一个类继承自RelativeLayout,在这里面我们需要做的有两件事:第一我们
要将上面的布局文件加载进来(inflate),第二我们要实现各个部分控件的逻辑(比如点击过后有哪些逻辑需要实现)。
package com.blossoming.mobilesafe.UI;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.blossoming.mobilesafe.R;
/**
* Created by Blossoming on 2016/8/3.
*/
public class SettingItemUI extends RelativeLayout {
private TextView tv_setting_content;
private CheckBox cb_setting_choose;
private String title,desc_on,desc_off;
private void initView(Context context)
{
View.inflate(context, R.layout.setting_item,this);
tv_setting_content=(TextView) findViewById(R.id.tv_setting_content);
cb_setting_choose=(CheckBox) findViewById(R.id.cb_setting_choose);
// title=attrs.getAttributeValue("http://schemas.android.com/apk/com.blossoming.mobilesafe","title");
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.blossoming.mobilesafe.R;
/**
* Created by Blossoming on 2016/8/3.
*/
public class SettingItemUI extends RelativeLayout {
private TextView tv_setting_content;
private CheckBox cb_setting_choose;
private String title,desc_on,desc_off;
private void initView(Context context)
{
View.inflate(context, R.layout.setting_item,this);
tv_setting_content=(TextView) findViewById(R.id.tv_setting_content);
cb_setting_choose=(CheckBox) findViewById(R.id.cb_setting_choose);
// title=attrs.getAttributeValue("http://schemas.android.com/apk/com.blossoming.mobilesafe","title");
}
public SettingItemUI(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
public SettingItemUI(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
public SettingItemUI(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
desc_on=attrs.getAttributeValue("http://schemas.android.com/apk/com.blossoming.mobilesafe","desc_on");
desc_off=attrs.getAttributeValue("http://schemas.android.com/apk/com.blossoming.mobilesafe","desc_off");
super(context, attrs);
initView(context);
desc_on=attrs.getAttributeValue("http://schemas.android.com/apk/com.blossoming.mobilesafe","desc_on");
desc_off=attrs.getAttributeValue("http://schemas.android.com/apk/com.blossoming.mobilesafe","desc_off");
}
public SettingItemUI(Context context)
{
super(context);
initView(context);
}
{
super(context);
initView(context);
}
public void setChecked(boolean bool)
{
if(bool) {
cb_setting_choose.setChecked(bool);
setText(desc_off);
}
else
{
cb_setting_choose.setChecked(bool);
setText(desc_on);
}
}
public boolean getChecked()
{
return cb_setting_choose.isChecked();
}
public void setText(String text)
{
tv_setting_content.setText(text);
}
}
下面我们细说一下过程:一开始我们需要导入3个构造方法,每个构造方法中都需要加载自定义的布局文件,其中我们注意到第二个
构造方法中getAttributeValue( , ),这个函数作用是的到我们自定义控件属性的具体的值(暂时不说)。加载进布局之后我
们就要写逻辑了,当点击控件之后我们需要实现CheckBox打勾/取消打勾,因此自然有方法setChecked,点击之后传入bool值,
但是我们还需要获取点击之前的状态,因此自然有了getChecked来获取控件的状态;在点击之后我们需要改变第二个TextView
的内容(自动更新已经开启/关闭),因此自然有方法setText。
{
if(bool) {
cb_setting_choose.setChecked(bool);
setText(desc_off);
}
else
{
cb_setting_choose.setChecked(bool);
setText(desc_on);
}
}
public boolean getChecked()
{
return cb_setting_choose.isChecked();
}
public void setText(String text)
{
tv_setting_content.setText(text);
}
}
下面我们细说一下过程:一开始我们需要导入3个构造方法,每个构造方法中都需要加载自定义的布局文件,其中我们注意到第二个
构造方法中getAttributeValue( , ),这个函数作用是的到我们自定义控件属性的具体的值(暂时不说)。加载进布局之后我
们就要写逻辑了,当点击控件之后我们需要实现CheckBox打勾/取消打勾,因此自然有方法setChecked,点击之后传入bool值,
但是我们还需要获取点击之前的状态,因此自然有了getChecked来获取控件的状态;在点击之后我们需要改变第二个TextView
的内容(自动更新已经开启/关闭),因此自然有方法setText。
二.自定义控件属性
1.自定义控件属性只是自定义控件里的一个小技巧,我们举个例子:在TextView的布局文件中我们可以这样写text=”哈哈“,那么
TextView的内容就会是”哈哈“,但是我们也可以通过在程序中textView.setText("哈哈"),这两者有什么联系???
其实这就是自定义属性的体现,即比较方便(上面的是我个人的理解)。那么我们能不能给我们的自定义控件加上我们的自定义属
呢?当然可以。下面我贴出代码
TextView的内容就会是”哈哈“,但是我们也可以通过在程序中textView.setText("哈哈"),这两者有什么联系???
其实这就是自定义属性的体现,即比较方便(上面的是我个人的理解)。那么我们能不能给我们的自定义控件加上我们的自定义属
呢?当然可以。下面我贴出代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:blossoming="http://schemas.android.com/apk/com.blossoming.mobilesafe"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.blossoming.mobilesafe.UI.SettingItemUI
blossoming:title_item="设置是否进行自动更新"
blossoming:desc_on="自动更新已经开启"
blossoming:desc_off="自动更新已经关闭"
android:id="@+id/si"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.blossoming.mobilesafe.UI.SettingItemUI>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:blossoming="http://schemas.android.com/apk/com.blossoming.mobilesafe"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.blossoming.mobilesafe.UI.SettingItemUI
blossoming:title_item="设置是否进行自动更新"
blossoming:desc_on="自动更新已经开启"
blossoming:desc_off="自动更新已经关闭"
android:id="@+id/si"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.blossoming.mobilesafe.UI.SettingItemUI>
</LinearLayout>
这个就是在布局文件中引入了我们自定义的控件,这里我们发现了一个android中没有的属性blossoming,这个其实就是我自定义
的属性,步骤如下:
①自定义命名空间,例如:
xmlns:blossoming(可以任意)="http://schemas.android.com/apk/res/《包名》"
xmlns:="http://schemas.android.com/apk/res/com.itheima.mobilesafe"
这个就是在布局文件中引入了我们自定义的控件,这里我们发现了一个android中没有的属性blossoming,这个其实就是我自定义
的属性,步骤如下:
①自定义命名空间,例如:
xmlns:blossoming(可以任意)="http://schemas.android.com/apk/res/《包名》"
xmlns:="http://schemas.android.com/apk/res/com.itheima.mobilesafe"
②自定义我们的属性,在Res/values/attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TextView">
<attr name="title_item" format="string" />
<attr name="desc_on" format="string" />
<attr name="desc_off" format="string" />
</declare-styleable>
</resources>
③使用我们自定义的属性
例如:
itheima:title="设置自动更新"
itheima:desc_on="设置自动更新已经开启"
itheima:desc_off="设置自动更新已经关闭"
2.这些属性并没有生命,即到现在我们并没有使用,我们要在我们自定义控件的类当中去get到这些属性的值,这里回到上面的自定
义控件的第二个构造函数里的getAttributeValue即得到我们属性的值。但是这个值有什么用呢,这里面有个逻辑就是当我们点击
控件的时候我们需要切换文字(开启关闭),我们只用利用get到的属性值,通过setText来设置就ok了。
义控件的第二个构造函数里的getAttributeValue即得到我们属性的值。但是这个值有什么用呢,这里面有个逻辑就是当我们点击
控件的时候我们需要切换文字(开启关闭),我们只用利用get到的属性值,通过setText来设置就ok了。
三.应用场景
如果我们又需要写一个控件来设置软件是否能够通过在4G网络下访问网络,那么们只需要在大的布局文件里加入我们自定义的控件,
只需改变一下我们自定义的属性值是不是就ok了呢。确实很方便啊,很符合现在人偷懒的性格啊。
只需改变一下我们自定义的属性值是不是就ok了呢。确实很方便啊,很符合现在人偷懒的性格啊。
最后
以上就是忧虑汽车为你收集整理的初学android-自定义控件以及控件属性 自定义控件以及自定义控件属性的全部内容,希望文章能够帮你解决初学android-自定义控件以及控件属性 自定义控件以及自定义控件属性所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复