自定义View从实现到原理(六)
终于回到了实现这一部分,经过了之前的解析,我们从实现到原理,这次再次回到实现,这一次的实现·就不会是像之前那次的简单实现了,经过梳理我们已经有能力写出一些复杂的自定义View,实现自定义组合控件。
实现自定义组合控件
所谓自定义组合控件,就是多个控件组合起来成为了一个新的控件,主要用于解决多次重复的使用同一类型的布局,就比如说我们常用的顶部标题栏以及弹出的样式dialog等,这些都很常用,所以将他们所需要的控件组合起来形成一个新的控件,就可以提高代码可读性以及实现效率,那么这一次我们就来实现一个顶部的标题栏。
定义标题栏(组合控件)的布局
首先我们来布置一下这个标题栏的布局,很简单,就是两张图片加一串文字,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/titleBar"
android:layout_width="match_parent"
android:layout_height="45dp">
<ImageView
android:id="@+id/titleBarLeft"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/titlebarleft"
android:layout_alignParentStart="true"
android:layout_centerHorizontal="true"
android:layout_marginStart="15dp"/>
<TextView
android:id="@+id/titleBarTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:maxLength="11"
android:singleLine="true"
android:ellipsize="end"
android:textStyle="bold"/>
<ImageView
android:id="@+id/titleBarRight"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/titlebarright"
android:layout_alignParentEnd="true"
android:layout_centerHorizontal="true"
android:layout_marginEnd="15dp"/>
</RelativeLayout>
就是这样,包含两个ImageView以及一个TextView,其中maxLength含义是最多显示的文本数量,ellipsize是设置省略号的位置,textStyle是设置文本字体,其他的没什么问题,接下来就开始编写之前说过的titleattrs.xml这个属性文件:
定义View属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TitleBar">
<attr name="titleBackground" format="color"/>
<attr name="titleTextColor" format="color"/>
<attr name="titleText" format="string"/>
</declare-styleable>
</resources>
和之前一样,先写好了styleable的name,这个地方在构造函数中调用,剩下的就是自定义的属性以及属性类别了,接下来正式进入Java代码部分:
自定义组合控件
/**
* 自定义的标题栏
*/
public class TitleBar extends RelativeLayout {
//定义属性中的标题栏背景颜色
private int titleBackground;
//定义属性中的标题颜色
private int titleTextColor;
//定义属性中的标题内容
private String titileText;
//定义布局中的控件
private ImageView titleBarLeft, titleBarRight;
private TextView titleBarTitle;
private RelativeLayout titleBar;
public TitleBar(Context context) {
this(context, null);
}
/**
* 之前的构造方法传到这里·载入属性
*
* @param context 当前位置
* @param attrs 也就是
*/
public TitleBar(Context context, AttributeSet attrs) {
super(context, attrs);
@SuppressLint("Recycle")
TypedArray titleTypeArray = context.obtainStyledAttributes(attrs, R.styleable.TitleBar);
titleBackground = titleTypeArray.getColor(R.styleable.TitleBar_titleBackground, Color.BLACK);
titleTextColor = titleTypeArray.getColor(R.styleable.TitleBar_titleTextColor, Color.WHITE);
titileText = titleTypeArray.getString(R.styleable.TitleBar_titleText);
//回收
titleTypeArray.recycle();
initView(context);
}
/**
* 载入布局以及设置属性
*
* @param context 当前位置
*/
public void initView(Context context) {
LayoutInflater.from(context).inflate(R.layout.titlebar, this, true);
titleBarLeft = findViewById(R.id.titleBarLeft);
titleBarRight = findViewById(R.id.titleBarRight);
titleBarTitle = findViewById(R.id.titleBarTitle);
titleBar = findViewById(R.id.titleBar);
//设置布局的背景颜色以及标题文字颜色
titleBar.setBackgroundColor(titleBackground);
titleBarTitle.setTextColor(titleTextColor);
}
/**
* 设置标题的函数
*
* @param TitleText 标题内容
*/
public void setTitle(String TitleText) {
if (TitleText != null) {
titleBarTitle.setText(TitleText);
}
}
/**
* 点击左侧图片的点击事件
*
* @param onClickListener 点击事件:eg:new View.OnCLickListener(){}
*/
public void setLeftListener(OnClickListener onClickListener) {
//外部设置的点击事件就是组合控件中左面图片的点击事件
titleBarLeft.setOnClickListener(onClickListener);
}
/**
* 点击右侧图片的点击事件
*
* @param onClickListener 点击事件:eg:new View.OnCLickListener(){}
*/
public void setRightListener(OnClickListener onClickListener) {
//外部设置的点击事件就是组合控件中右面图片的点击事件
titleBarRight.setOnClickListener(onClickListener);
}
}
注释已经写的很详细了,反正我写的时候我是明白了,就这样,我们定义组合控件已经完成,下面在我们想要实现的界面引用:
xml引用
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activity.ShelfActivity">
<com.example.day1.View.TitleBar
android:id="@+id/shelfTitleBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
截取了一部分,我们下面会在对应的Activity中进行设置标题内容以及点击事件:
代码(Activity)引用
private TitleBar shelfTitleBar;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shelf);
shelfTitleBar = findViewById(R.id.shelfTitleBar);
shelfTitleBar.setTitle("自定义组合控件");
shelfTitleBar.setLeftListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(ShelfActivity.this, "点击左侧控件", Toast.LENGTH_SHORT).show();
}
});
shelfTitleBar.setRightListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(ShelfActivity.this, "点击右侧控件", Toast.LENGTH_SHORT).show();
}
});
}
如此这样,我这个也是截取了一部分,不全面,运行可能会有点小错误没截取完整,见谅,那么就让我们来看看最终运行效果:
好的,成功,点击事件也是ok的,当然现在看起来不好看,所以以后会慢慢完善的,小场面,溜了。