前面学习的是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>
执行结果例如以下:
单击button会有对应的事件响应。
注意,加入自己定义控件的时候须要指明完整的包名和类名
转载请注明:http://blog.csdn.net/j903829182/article/details/40682583