美文网首页
Android自定义模版View

Android自定义模版View

作者: lkmc2 | 来源:发表于2017-12-09 02:43 被阅读26次

Android自定义模版View

Android开发中有许多需要复用的组件,那么要如何才能自定义一个自定义的模版呢?接下来请看下面的例子。

1.新建完一个新的项目后,在res目录下的vulues目录单击右键,选择New->Vaules resource file,文件名填入attrs,点击确定。

pic01.png pic02.png

2.在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

相关文章

网友评论

      本文标题:Android自定义模版View

      本文链接:https://www.haomeiwen.com/subject/xyfuixtx.html