Android简单自定义布局介绍

复用嘛~写一堆同样的布局属性不仅长,还降低可读性,虽然可以定义style,但布局复杂一点就又杯水车薪,好吧style我用的不多,似乎有一些高级的用法不是很了解,但是简单的自定义布局确实会方便许多。

有错误还望指正 :-)

  1. 定义自定义类继承 View,建议在特定的package(如 com.xxx.xxx.view)下定义自定义布局类,例如:

    public class CustomTitleBar extends RelativeLayout {    public CustomTitleBar(final Context context, AttributeSet attrs) {        super(context, attrs);    }}

    给出的构造方法是必须的,这个时候其实你已经可以在其他的布局文件中引用这个叫做 CustomTitleBar 的文件了,只不过此时它和一个平常的 RelativeLayout 没什么差别。

  2. 定义layout资源文件,用于自定义view中的内容,同样用上述的 CustomTitleBar 的例子:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="@dimen/height_title_bar">    <ImageButton         android:id="XXX"         android:layout_width="match_parent"  android:layout_height="wrap_content".../>    <TextView.../>    <TextView... />RelativeLayout>

    前两步没有顺序要求,完成后这两个View对象(一个是类对象,一个是xml资源文件 – xml文件实际上仍然需要被解析为对象)还没有关系,接下来就是要让它们联系起来。

    这个时候你已经可以在自定义的 CustomTitleBar 中执行 LayoutInflater.from(context).inflate(R.layout.rl_custom_titlerbar, this); 将这个布局填充到自定义的布局对象中了,后面会说到。

  3. 在values文件夹下的attrs文件(如果没有的话可以新建一个)中新建一项declare-styleable,例如:

    <declare-styleable name="CustomTitleBar">    <attr name="xxx" format="string"/>    <attr name="xxx" format="reference"/>    <attr name="xxx" format="color"/>declare-styleable>

    这些属性是可以在布局文件中通过 app: xxx="@string/xxx" 这样的形式使用的,注意观察的朋友可能会注意到 xmlns:app="http://schemas.android.com/apk/res-auto" 这个命名空间(xml name space)的指定,实际上从 等号 后面的链接可以大概体会到这个命名空间的作用。

    指定的format则是属性对应的格式,reference 表示引用,即 drawable等资源文件,color、string即为color资源和string资源,其他还有一些如boolean之类也容易理解。

    名字name即为该属性的名称,如果不同的declare-styleable名字相同的话无法通过编译,所以还是需要区分一下的。

    如果你想使用Android已经定义过名称,如 android:text="xxx" android:src="xxx" ,你可以直接将自定义属性写为: 这样,你就可以在其他布局文件中使用这个属性,就像在 textview 中使用 android:text="xxx" 一样。

  4. 接下来就是在自定义布局中用 LayoutInflater 填充布局文件以及解析自定义的属性了,解析的时候需要用的一个叫 TypedArray 的东西,具体使用方法如下:

    public CustomTitleBar(Context context, AttributeSet attrs) {    super(context, attrs);    LayoutInflater.from(context).inflate(R.layout.rl_custom_titlerbar, this);    TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomTitleBar);    titleView = findViewById(R.id.tv_view_title_title);    titleView.setText(typedArray.getText(R.styleable.CustomTitleBar_title_title_bar));    typedArray.recycle();}
  5. 之后可以继续在自定义的类中添加自定义方法,扩充其功能。完成之后在其他布局文件中使用的时候需要先build工程,之后就可以预览出来了:

    <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"    android:orientation="vertical">    <com.zzued.campustravel.view.CustomTitleBar        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:background="@color/colorAccent"        app:title_title_bar="@string/modify_password".../>LinearLayout>

如下(也就是上述)是我在一个项目中自定义的一个标题栏的代码:

CustomTitleBar.java

package ...;import ...;public class CustomTitleBar extends RelativeLayout {    private ImageButton imgBtn;    private TextView titleView;    private TextView rightTextView;    public CustomTitleBar(final Context context, AttributeSet attrs) {        super(context, attrs);        LayoutInflater.from(context).inflate(R.layout.rl_custom_titlerbar, this);        imgBtn = findViewById(R.id.img_btn_view_title_back);        titleView = findViewById(R.id.tv_view_title_title);        rightTextView = findViewById(R.id.tv_view_title_right_text);                TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomTitleBar);        imgBtn.setImageDrawable(typedArray.getDrawable(R.styleable.CustomTitleBar_img_btn_src_title_bar));        imgBtn.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                if (context instanceof Activity)                    ((Activity)context).finish();            }        });        titleView.setText(typedArray.getText(R.styleable.CustomTitleBar_title_title_bar));        rightTextView.setText(typedArray.getText(R.styleable.CustomTitleBar_right_text_title_bar));        int textColor = typedArray.getColor(R.styleable.CustomTitleBar_text_color_title_bar, Color.BLACK);        titleView.setTextColor(textColor);        rightTextView.setTextColor(textColor);        ColorStateList stateList = typedArray.getColorStateList(R.styleable.CustomTitleBar_right_text_color_title_bar);        if (stateList != null)            rightTextView.setTextColor(stateList);        typedArray.recycle();    }    /**     * 设置返回键的监听器     *     * @param clickListener 监听器     */    public void setImgBtnClickListener(OnClickListener clickListener) {        imgBtn.setOnClickListener(clickListener);    }    /**     * 设置标题内容     *     * @param titleText 标题内容     */    public void setTitle(String titleText) {        titleView.setText(titleText);    }    /**     * 设置标题栏右侧文字内容及监听器     *     * @param text          右侧文字     * @param clickListener 监听器     */    public void setRightText(String text, OnClickListener clickListener) {        rightTextView.setText(text);        rightTextView.setOnClickListener(clickListener);    }    /**     * 设置标题栏右侧文字监听器     * @param clickListener 监听器     */    public void setRightTextListener(OnClickListener clickListener){        rightTextView.setOnClickListener(clickListener);    }}

rl_custom_titlerbar.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"    android:layout_width="match_parent"    android:layout_height="@dimen/height_title_bar">    <ImageButton        android:id="@+id/img_btn_view_title_back"        android:contentDescription="@string/app_name"        android:layout_width="@dimen/img_btn_title_bar_size"        android:layout_height="@dimen/img_btn_title_bar_size"        android:layout_marginStart="@dimen/middle_margin"        android:layout_centerVertical="true"        android:background="@null"        android:scaleType="fitCenter"        android:src="@drawable/selector_view_back_gray_white"/>    <TextView        android:id="@+id/tv_view_title_title"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:textSize="@dimen/common_text_size_large"        android:textColor="@android:color/black"        />    <TextView        android:id="@+id/tv_view_title_right_text"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentEnd="true"        android:layout_centerVertical="true"        android:clickable="true"        android:focusable="true"        android:layout_marginEnd="@dimen/middle_margin"        android:textColor="@android:color/black"        android:textSize="@dimen/common_text_size_middle"        tools:ignore="RelativeOverlap" />RelativeLayout>

attrs.xml

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="CustomTitleBar">        <attr name="title_title_bar" format="string"/>        <attr name="img_btn_src_title_bar" format="reference"/>        <attr name="right_text_title_bar" format="string"/>        <attr name="text_color_title_bar" format="color"/>        <attr name="right_text_color_title_bar" format="color"/>    declare-styleable>resources>

这是在其他布局文件中引用的例子:

<?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"    android:orientation="vertical"    tools:context=".activity.ModifyPasswordActivity">    <com.zzued.campustravel.view.CustomTitleBar        android:id="@+id/title_modify_password"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:background="@color/colorAccent"        app:right_text_color_title_bar="@drawable/selector_home_right_text_white_accent"        app:right_text_title_bar="@string/finish"        app:img_btn_src_title_bar="@drawable/selector_view_title_back_white_gray"        app:text_color_title_bar="@android:color/white"        app:title_title_bar="@string/modify_password" />LinearLayout>

更多相关文章

  1. android开发--界面的布局
  2. # Android文件存储和数据库基本知识
  3. Android仿新浪微博底部布局TabHost
  4. android 在布局文件中报错:This text field does not specify an
  5. 基于android的NFS根文件系统的制作

随机推荐

  1. 使用JDBC处理MySQL大数据
  2. MySql 优化之like语句
  3. mysql galera cluster 集群的分裂与仲裁
  4. linux CentOS 7.4下 mysql5.7.20 密码改
  5. c语言把mysql数据库语句和变量封装为一个
  6. 错误'未知表引擎'InnoDB''查询。重启mysq
  7. 添加到LEFT JOIN查询
  8. MySQL查询优化系列讲座之数据类型与效率
  9. 解析innodb status各项参数
  10. 如何使用java Web服务从mysql数据库获取