前面学习的是android的基本控件和布局的使用,但是基本的控件和布局有时候并不能实现复杂的布局。我们来看下各种控件和布局的关系。
可见所有的控件都是直接或者间接的继承自View的,所有的布局都是直接或者间接基础自ViewGroup的。View是Android中一种最基本的UI组件,它可以在屏幕的上绘制一块矩形区域,并能响应这块区域的各种事件,因此,我们使用的各种控件其实就是在View的基础上又添加了各种各自特有的功能。而ViewGroup则是一种特殊的View,它可以包含很多的View和子ViewGroup,是一个用于放置控件和布局的容器。创建自定义控件的两种简单的方法,一种是引入布局,另一种是自定义控件。
首先创建一个项目,项目的名字为UICustomViews。
下面我们就自己定义一个标题栏。
新建一个布局,代码如下:
<?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" android:orientation="horizontal" android:background="@drawable/title_bg" > <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:background="@drawable/back_bg" 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:background="@drawable/edit_bg" android:text="Edit" android:textColor="#fff" /> </LinearLayout>
修改主布局,代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <include layout="@layout/title"/> </LinearLayout>
修改MainActivity里面的onCreate方法
代码如下:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); }
<include layout="@layout/title"/>是引入一个布局文件
requestWindowFeature(Window.FEATURE_NO_TITLE);是将系统自带的标题栏隐藏掉
程序运行结果如下:
使用上面的这种引入布局的方式,不管有多少布局需要添加标题栏,只需一行include语句就可以了。
引入布局的技巧确实解决了重复编写代码的问题,但是如果布局中有一些控件要求能响应事件,我们还是需要在每个活动中为这些控件单独的编写一次事件注册的代码。但是注册的代码都一样,所以这会带来很多重复的代码,那么下面就进行自定义控件。
自定义控件
新建TitleLayout继承LinearLayout,代码和说明如下:
package com.wj.uicustomviews; import android.app.Activity; 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); // TODO Auto-generated constructor stub /* * 重写LinearLayout中的带有2个参数的构造函数,在布局中引入TitleLayout控件就会调用这个构造函数 * 然后在构造函数中需要对标题栏布局进行动态加载,这就是要借助LayoutInflater来实现了。通过LayoutInflater的 * from()方法可以构建出一个LayoutInflater对象,然后调用inflate()方法就可以动态加载一个布局文件,inflate方法 * 接收2个参数数,第一个参数是要加载的布局的id,这里我们传入R.layout.title,第二个参数是给加载好的布局在添加一个父布局, * 这里我们想要指定为TitleLayout,于是就传入this * * */ 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 OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub ((Activity)getContext()).finish(); } }); titleEdit.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub Toast.makeText(getContext(), "you clicked edit button", Toast.LENGTH_SHORT).show(); } }); } }
在布局文件中引用自定义控件修改主布局文件,代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- <include layout="@layout/title"/> --> <com.wj.uicustomviews.TitleLayout android:layout_width="match_parent" android:layout_height="wrap_content" > </com.wj.uicustomviews.TitleLayout> </LinearLayout>
运行结果如下:
单击按钮会有相应的事件响应。
注意,添加自定义控件的时候需要指明完整的包名和类名
转载请注明:http://blog.csdn.net/j903829182/article/details/40682583