Android简单自定义布局介绍
Android简单自定义布局介绍
复用嘛~写一堆同样的布局属性不仅长,还降低可读性,虽然可以定义style,但布局复杂一点就又杯水车薪,好吧style我用的不多,似乎有一些高级的用法不是很了解,但是简单的自定义布局确实会方便许多。
有错误还望指正 :-)
-
定义自定义类继承 View,建议在特定的package(如 com.xxx.xxx.view)下定义自定义布局类,例如:
public class CustomTitleBar extends RelativeLayout { public CustomTitleBar(final Context context, AttributeSet attrs) { super(context, attrs); }}
给出的构造方法是必须的,这个时候其实你已经可以在其他的布局文件中引用这个叫做
CustomTitleBar
的文件了,只不过此时它和一个平常的RelativeLayout
没什么差别。 -
定义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);
将这个布局填充到自定义的布局对象中了,后面会说到。 -
在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"
一样。 -
接下来就是在自定义布局中用
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();}
-
之后可以继续在自定义的类中添加自定义方法,扩充其功能。完成之后在其他布局文件中使用的时候需要先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>
更多相关文章
- NPM 和webpack 的基础使用
- 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
- 读取android手机流量信息
- android 使用html5作布局文件: webview跟javascript交互
- Android(安卓)多媒体扫描过程(Android(安卓)Media Scanner Proces
- android“设置”里的版本号
- Android开发环境搭建
- Android(安卓)Resource介绍和使用
- 2014.01.21 ——— android 关联android-support源码