Android简单自定义布局介绍

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" ,你可以直接将自定义属性写为:<attr name="android:text"/> 这样,你就可以在其他布局文件中使用这个属性,就像在 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>
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Android Spinner是一个下拉列表控件,用于从一组选项中选择一个选项。Spinner默认使用系统提供的下拉列表布局,但是你可以自定义Spinner的布局以适应你的应用程序的需求。 要自定义Spinner的布局,需要创建一个自定义布局文件,并在代码中指定它。以下是一个简单的示例。 首先,创建一个自定义布局文件。在res/layout目录下创建一个布局文件,例如spinner_item.xml。 ```xml <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="16sp" android:textColor="#000000" android:padding="10dp"/> ``` 这个布局文件只包含了一个TextView,它将显示Spinner中的选项。 接下来,在代码中指定这个布局文件。找到Spinner控件的实例,然后使用setDropDownViewResource()方法将自定义布局文件设置为Spinner的下拉列表布局。 ```java Spinner spinner = (Spinner) findViewById(R.id.spinner); ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.planets_array, R.layout.spinner_item); adapter.setDropDownViewResource(R.layout.spinner_item); spinner.setAdapter(adapter); ``` 在这个示例中,我们使用了预定义的数组R.array.planets_array作为Spinner的选项,并将自定义布局文件R.layout.spinner_item设置为下拉列表布局。 最后,你需要在布局文件中设置Spinner的样式和其他属性,以使它看起来是你想要的样子。你可以使用android:background设置Spinner的背景色,使用android:padding设置内边距等等。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值