原文链接:http://www.orlion.ga/441/
一、引入布局
iphone应用顶部会有一个标题栏,我们可以模仿着做一个,但是如果我们的程序中很多个活动都需要这样的标题栏,如果 每一个活动中都写一个标题栏就会导致代码重复,我们可以使用引入布局的方式来解决这个问题,新建一个布局title.xml。代码:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:id="@+id/title_back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="5dip" android:text="Back" android:textColor="#fff"/> <TextView android:id="@+id/title_text" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="1" android:gravity="center" android:text="Title Text" android:textColor="#fff" android:textSize="24sp"/> <Button android:id="@+id/title_edit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="5dip" android:text="Edit" android:textColor="#fff"/> </LinearLayout>
android:layout_margin这个属性可以指定控件在上下左右方向上偏移的距离,当然也可以使用android:layout_marginLeft或 android:layout_marginTop等属性来单独指定控件在某个方向上偏移的距离。现在标题栏布局已经编写完成了,剩下的就是如何在程序中使用这个标题栏了,修改activity_main.xml中的代码,如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <include layout="@layout/title"/> </LinearLayout>
二、创建自定义控件
上边我们创建的标题栏有一个返回按钮,需要绑定事件。如果在每一个活动中都需要注册一遍返回按钮的点击事件会增加很多重复代码。这种情况最好使用自定义控件的方式解决
新建TitleLayout继承自LinearLayout,让它成为我们自定义的标题栏控件,代码如下:
package com.example.uicustomviews; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.widget.LinearLayout; public class TitleLayout extends LinearLayout { public TitleLayout(Context context, AttributeSet attrs) { super(context, attrs); LayoutInflater.from(context).inflate(R.layout.title , this); } }
首先我们重写了LinearLayout中的带有两个参数的构造函数,在布局中引入了TitleLayout控件就会调用这个构造函数。然后在构造函数中对标题栏进行动态加载,这就要借助LayoutInflate来实现。通过LayoutInflate的from()方法就可以构建出一个LayoutInflater对象,然后调用inflate()方法就可以动态加载一个布局文件,inflate()方法接收两个参数,第一个参数是要加载的布局文件的id,这里我们传入R.layout.title,第二个参数是给加载好的布局再添加一个父布局,这里我们想要指定为TitleLayout,于是直接传入this。
现在自定义控件已经创建好了,然后我们需要在布局文件中添加这个自定义控件,修改activity_main.xml中的代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <ga.orlion.uicustomviews.TitleLayout android:layout_width="match_parent" android:layout_height="wrap_content"> </ga.orlion.uicustomviews.TitleLayout> </LinearLayout>
添加自定义控件和普通添加控件的方式基本上是一样的,只不过在添加自定义控件的时候我们需要指明控件的完整类名,包名在这里是不可以忽略的。
重新运行程序,可以看到效果与之前一样。
然后为标题栏中的按钮注册点击事件:
package com.example.uicustomviews; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; import android.widget.Toast; public class TitleLayout extends LinearLayout { public TitleLayout(Context context, AttributeSet attrs) { super(context, attrs); LayoutInflater.from(context).inflate(R.layout.title , this); Button titleBack = (Button) findViewById(R.id.title_back); Button titleEdit = (Button) findViewById(R.id.title_edit); titleBack.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ((android.app.Activity) getContext()).finish(); } }); titleEdit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getContext() , "You clicked Edit button" , Toast.LENGTH_SHORT).show(); } }); } }