0.前言

上一篇文章中,我们讲解了Android的动画

有兴趣的可以去看一看

准备工作

在读本文前,你最好有以下准备:

(1)安装Android Stuido(以下简称AS)

(2)有一定的Java基础

(3)有一台安卓机

(可以用模拟器来代替,包括AS自带的以及网上的一些著名模拟器)

若想要了解有关Java的文章等其他主要知识,可以去看前面的文章

(不会使用AS的读者可以参考下面这篇文章中的例子)

《[Java]开发安卓,你得掌握的Java知识2》

1.本文内容简介

自定义控件基础

组合方式自定义控件

2.基础知识讲解

自定义控件

自定义控件的最主要原因,是系统的控件无法满足自身需求

自定义控件有多种方法:

(1)组合方式——纯粹用系统控件拼接,实现相应功能

(2)继承方式——自定义一个继承于对应容器(Layout)的类,然后在已有的控件基础上添加新的功能

(3)自绘方式——自己画一个新的控件

自定义控件——继承方式

组合方式属于自定义控件里面较常用的一种

通过自定义一个(继承于某layout)类,对原有的控件进行组合(这方面类似组合方式),并且通过更多的java代码来使得这个控件变得像一个系统控件

核心思想就是:

1.创建一个类,然后看情况让这个类继承与某种布局(layout)

2.继承之后,重写对应的3个方法

3.通过3个方法完成两种创建控件的方法(java代码和xml文件)

具体操作在第3部分

这个内含多个控件的容器,就相当于是一个自定义的控件

3.具体代码操作

组合方式自定义控件的效果图:

自定义一个导航栏形式的控件

左右两边的按钮可以设置点击事件

这里设置的就是变颜色的点击事件

继承方式的控件

java代码部分

第零步 准备好drawable资源

1.找到drawable

2.右键->New->Drawable resource file

3.取名叫做title_shape

4.把select改成layer-list,并且添加对应代码

android:color="#000000"/>

同理,创建一个button_shape.xml

android:height="10dp"/>

第一步 创建一个类

第二步 继承于某个容器

第三步(一) 重写三个具体的方法

选择这前三个(第四个不是)

第三步(二) 搞清楚三个构造函数的作用

第一个构造函数,是用于java代码创建的

第二个构造函数,是用于xml文件创建的

第三个构造函数,是用于xml文件创建的,最后一个属性的style

第四步 在对应的构造函数中添加代码

找到第一个构造方法

在这个代码中添加固定的控件

在这里面像之前一样添加控件

素材(右键另存为):

//1.定义一个返回按钮

ImageView returnButton = new ImageView(context);

//2.返回按钮设置资源

returnButton.setBackgroundResource(R.drawable.return_btn2);

//3.设置属性

LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

layoutParams.width = dpToPixel(20);

layoutParams.height = dpToPixel(20);

layoutParams.addRule(CENTER_VERTICAL);

//4.将返回按钮添加到容器中

addView(returnButton,layoutParams);

ViewGroup.LayoutParams.WRAP_CONTENT表示内容多大,控件多大

addRule(CENTER_VERTICAL)表示垂直方向居中

其中,dpToPixel,是一个自己写的一个方法,将dp变为pixel

public int dpToPixel(int dp){

float density = getResources().getDisplayMetrics().density;

return (int) (density * dp);

}

效果图:

第五步 把添加返回按钮的代码封装起来

就是把原来的代码复制到一个独立的函数中,然后把这个函数名留在原地

private void setReturnBtn(Context context) {

//1.定义一个返回按钮

returnButton = new ImageView(context);

//2.返回按钮设置资源

returnButton.setBackgroundResource(R.drawable.return_btn2);

//3.设置属性

LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

layoutParams.width = dpToPixel(20);

layoutParams.height = dpToPixel(20);

layoutParams.addRule(CENTER_VERTICAL);

//4.将返回按钮添加到容器中

addView(returnButton,layoutParams);

}

第六步 重复上述步骤,添加标题和右边的编辑按钮

设置标题:

private void setTitle(Context context,String title) {

//1.定义

TextView textView = new TextView(context);

//2.设置标题

textView.setText(title);

//3.设置字体大小

textView.setTextSize(15.0f);

//4.设置参数

LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

// params.gravity = Gravity.CENTER_HORIZONTAL;

params.addRule(CENTER_IN_PARENT);

//5.添加控件

addView(textView,params);

}

设置右边按钮:

private void setRightBtn(Context context,String contain) {

//1.定义

rightBtn = new TextView(context);

//2.设置背景

rightBtn.setBackgroundResource(R.drawable.button_shape);

//3.设置属性

LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

layoutParams.addRule(ALIGN_PARENT_RIGHT);

layoutParams.width = dpToPixel(60);

layoutParams.height = dpToPixel(30);

rightBtn.setText(contain);

rightBtn.setGravity(Gravity.CENTER);

//添加到容器中

addView(rightBtn,layoutParams);

}

最后构造函数的样子:

public Title(Context context,boolean hasReturnBtn, int background,String title,String rightBtn) {

super(context);

//设置水平布局以及背景色

setBackgroundResource(background);

//设置内边距,保证按钮什么的不会贴着边

setPadding(20,20,20,20);

//-------------返回按钮---------------//

if (hasReturnBtn) {

setReturnBtn(context);

}

//-------------中间标题---------------//

if (title != null) {

setTitle(context,title);

}

//-------------最右边的分享按钮---------------//

if (rightBtn != null) {

setRightBtn(context,rightBtn);

}

}

可能有些读者觉得有点快,但是如果真的要一点一点来的话,整篇文章会极其长,后面两个控件的书写思想其实和返回按钮是一样的,都是先在构造函数中书写对应代码进行测试,然后再取出来进行封装

2.有些眼尖的观众可能已经发现了,构造函数跟原来不一样了,多了很多参数,其实一开始书写确实是按照之前说的那个构造函数里面写的,但是后来发现一个参数并不够用,就需要自己写一个独立的构造函数

3.为什么构造函数要这么多参数?

这些参数与setBackgroundResource(background);等函数的参数有关,这些参数是必须设置的

为避免用户忘记设置,或者是搞错设置顺序,就需要在构造函数中进行设置

第七步 在MainActivity中完成控件的添加

完整代码:

//找到这个RelativeLayout容器

rl = findViewById(R.id.rl_root);

//1.定义一个

title = new Title(this,true,R.drawable.title_shape,"Title","分享");

//设置属性用的

RelativeLayout.LayoutParams rLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

rl.addView(title,rLayoutParams);

效果:

第八步 添加点击事件

在Title中添加点击事件的入口:

这样就能用原先控件自带的点击事件了,代码:

//设置返回按钮事件

public void setReturnBtnClickListener(OnClickListener onClickListener){

returnButton.setOnClickListener(onClickListener);

}

//设置右边的按钮事件

public void setRightBtnClickListener(OnClickListener onClickListener) {

rightBtn.setOnClickListener(onClickListener);

}

在MainActivity中,使用这两个方法

title.setReturnBtnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

rl.setBackgroundColor(Color.BLACK);

}

});

title.setRightBtnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

rl.setBackgroundColor(Color.RED);

}

});

这里输入是有一定的技巧的,如果不太清楚的读者,可以去看

[Android]开发App,你得知道这些3——触摸事件等

截图出自上述文章

最后运行,就可以点击进行换颜色了(效果跟一开始的截图一样,就不再贴一遍了)

还没完,由于篇幅原因,剩下的内容下回分解