Android自定义模版View
Android开发中有许多需要复用的组件,那么要如何才能自定义一个自定义的模版呢?接下来请看下面的例子。
1.新建完一个新的项目后,在res目录下的vulues目录单击右键,选择New->Vaules resource file,文件名填入attrs,点击确定。
pic01.png pic02.png2.在attrs.xml文件中声明样式,命名为HeaderBar,在其中通过attr标签声明所需要的属性名,及其对应的引用资源的类型。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="HeaderBar"> <!-- 声明样式HeaderBar-->
<attr name="titleText" format="string"/> <!--标题文字-->
<attr name="titleTextColor" format="color"/> <!--标题文字颜色-->
<attr name="titleTextSize" format="dimension"/> <!--标题文字大小-->
<attr name="leftButtonText" format="string"/> <!--左边按钮文字-->
<attr name="leftButtonTextSize" format="dimension"/> <!--左边按钮文字大小-->
<attr name="leftButtonBackground" format="reference|color"/> <!--左边按钮背景-->
<attr name="rightButtonText" format="string"/> <!--右边按钮文字-->
<attr name="rightButtonTextSize" format="dimension"/> <!--右边按钮文字大小-->
<attr name="rightButtonBackground" format="reference|color"/> <!--右边按钮背景-->
</declare-styleable>
</resources>
3.新建一个叫HeaderBar的类,继承自RelativeLayout,在出现红线警告的地方按下Alt+Enter,在弹出的提示框中选择第二个构造方法。
pic03.png pic04.png生成后的代码如下:
import android.content.Context;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
public class HeaderBar extends RelativeLayout {
public HeaderBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
4.之后声明控件所需要的属性,并在initStyles()方法中对这些属性进行赋值
//标题文字,左按钮文字,右按钮文字
private String titleText, leftButtonText, rightButtonText;
private int titleTextColor; //标题文字颜色
//标题文字大小,左按钮文字大小,右按钮文字颜色
private float titleTextSize, leftButtonTextSize, rightButtonTextSize;
//左按钮背景,右按钮背景
private Drawable leftButtonBackground, rightButtonBackground;
/**
* 初始化样式
* @param context 上下文
* @param attrs 样式文件
*/
private void initStyles(Context context, AttributeSet attrs) {
//将之前声明的HeaderBar的样式转换成样式数组
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.HeaderBar);
titleText = ta.getString(R.styleable.HeaderBar_titleText); //标题文字
titleTextSize = ta.getDimension(R.styleable.HeaderBar_titleTextSize, 0); //标题字体大小
titleTextColor = ta.getColor(R.styleable.HeaderBar_titleTextColor, 0); //标题字体颜色
leftButtonText = ta.getString(R.styleable.HeaderBar_leftButtonText); //左按钮文字
leftButtonTextSize = ta.getDimension(R.styleable.HeaderBar_leftButtonTextSize, 0); //左按钮字体大小
leftButtonBackground = ta.getDrawable(R.styleable.HeaderBar_leftButtonBackground); //左按钮背景
rightButtonText = ta.getString(R.styleable.HeaderBar_rightButtonText); //右按钮文字
rightButtonTextSize = ta.getDimension(R.styleable.HeaderBar_rightButtonTextSize, 0); //右按钮字体大小
rightButtonBackground = ta.getDrawable(R.styleable.HeaderBar_rightButtonBackground); //右按钮背景
ta.recycle(); //释放样式数组
}
5.其后声明控件,在initViews()方法中对控件进行赋值。
private TextView tvTitle; //标题文字
private Button leftButton, rightButton; //左按钮、右按钮
/**
* 初始化界面控件
* @param context 上下文
*/
private void initViews(Context context) {
tvTitle = new TextView(context); //标题文字控件
leftButton = new Button(context); //左按钮
rightButton = new Button(context); //右按钮
}
6.到这里,就可以对控件设置属性,这里的操作在setStylesToViews()方法中进行。
/**
* 将样式设置到对应的控件
*/
private void setStylesToViews() {
tvTitle.setText(titleText); //标题文字
tvTitle.setTextSize(titleTextSize); //标题文字大小
tvTitle.setTextColor(titleTextColor); //标题文字颜色
leftButton.setText(leftButtonText); //左按钮文字
leftButton.setTextSize(leftButtonTextSize); //左按钮文字大小
leftButton.setBackground(leftButtonBackground); //左按钮背景
rightButton.setText(rightButtonText); //右按钮文字
rightButton.setTextSize(rightButtonTextSize); //右按钮文字大小
rightButton.setBackground(rightButtonBackground); //右按钮背景
setBackgroundColor(0xFFF56535); //设置整体背景色
}
7.随后,声明控件的布局参数,在方法中对这些布局参数进行赋值,并和控件一起添加到ViewGroup中。
//标题参数,左按钮参数,右按钮参数
private LayoutParams titleParams, leftButtonParams, rightButtonParams;
/**
* 将控件添加到ViewGroup中
*/
private void addViewsToViewGroup() {
//设置布局参数
titleParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
addView(tvTitle, titleParams); //将控件和参数添加到ViewGroup中
leftButtonParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
leftButtonParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
addView(leftButton, leftButtonParams);
rightButtonParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
rightButtonParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
addView(rightButton, rightButtonParams);
}
8.至此,就完成了代码部分的设置,接下来就是在xml文件中对该自定义View进行使用。由于需要使用自定义组件需要在xml文件顶部位置加上一行xmlns:app="http://schemas.android.com/apk/res-auto"。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="linchange.com.customtemplate.MainActivity">
<linchange.com.customtemplate.HeaderBar
android:id="@+id/headerBar"
android:layout_width="match_parent"
android:layout_height="60dp"
app:titleText="中间文字"
app:titleTextSize="16sp"
app:titleTextColor="#fff"
app:leftButtonText="左按钮"
app:leftButtonTextSize="10sp"
app:leftButtonBackground="@mipmap/ic_launcher"
app:rightButtonText="右按钮"
app:rightButtonTextSize="10sp"
app:rightButtonBackground="@mipmap/ic_launcher">
</linchange.com.customtemplate.HeaderBar>
</LinearLayout>
运行后的效果如下图:
pic05.png
8.此外,如果要对自定义组件设置特定的点击事件,需要先声明一个接口,然后在HeaderBar类定义一个该接口的变量,通过重写的setOnClickListener()将该接口从外部传入,并在leftButton和rightButton各自的setOnClickListener()方法中调用对应的接口方法。
public interface HeaderBarClickListener { //监听器接口
void leftClick(); //左按钮点击事件
void rightClick(); //右按钮点击事件
}
private HeaderBarClickListener listener; //监听器
public void setOnClickListener(HeaderBarClickListener listener) {
this.listener = listener;
}
/**
* 设置按钮的点击事件
*/
private void setButtonClickEvent() {
leftButton.setOnClickListener(new OnClickListener() { //给左按钮设置点击事件
@Override
public void onClick(View v) {
listener.leftClick(); //调用接口的左按钮点击方法
}
});
rightButton.setOnClickListener(new OnClickListener() { //给右按钮设置点击事件
@Override
public void onClick(View v) {
listener.rightClick(); //调用接口的右按钮点击方法
}
});
}
9.定义好点击事件后,在MainActivity中的使用方式如下:
public class MainActivity extends AppCompatActivity {
private HeaderBar headerBar; //标题控件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
headerBar = (HeaderBar) findViewById(R.id.headerBar);
headerBar.setOnClickListener(new HeaderBar.HeaderBarClickListener(){
@Override
public void leftClick() {
Toast.makeText(MainActivity.this, "点击了左按钮", Toast.LENGTH_SHORT).show();
}
@Override
public void rightClick() {
Toast.makeText(MainActivity.this, "点击了右按钮", Toast.LENGTH_SHORT).show();
}
});
}
}
10.如果要另外写HeaderBar的左按钮可见性方法的话,在HeaderBar类中添加如下方法:
/**
* 设置右按钮的点击事件
* @param isShow 是否显示右按钮
*/
public void setRightButtonVisibility(boolean isShow) {
rightButton.setVisibility(isShow ? VISIBLE : GONE);
}
11.在MainActivity中的使用方法如下:
headerBar.setRightButtonVisibility(false); //设置右按钮不可见
至此,一个简单的Android自定义模版就开发完成了,使用自定义模版具有更高的灵活性,可以实现代码复用和降低耦合性,具有更高的通用性。
Github地址:CustomTemplate
网友评论