自定义控件之组合控件
原博客:http://blog.csdn.net/guolin_blog/article/details/17357967
组合控件的意思就是,我们并不需要自己去绘制视图上显示的内容,而只是用系统原生的控件就好了,但我们可以将几个系统原生的控件组合到一起,这样创建出的控件就被称为组合控件。
举个例子来说,标题栏就是个很常见的组合控件,很多界面的头部都会放置一个标题栏,标题栏上会有个返回按钮和标题,点击按钮后就可以返回到上一个界面。那么下面我们就来尝试去实现这样一个标题栏控件。
新建一个title.xml布局文件,代码如下所示:
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="50dp" 5 android:background="#ffcb05" > 6 7 <Button 8 android:id="@+id/button_left" 9 android:layout_width="60dp" 10 android:layout_height="40dp" 11 android:layout_centerVertical="true" 12 android:layout_marginLeft="5dp" 13 android:background="#ffcc00" 14 android:text="Back" 15 android:textColor="#fff" /> 16 17 <TextView 18 android:id="@+id/title_text" 19 android:layout_width="wrap_content" 20 android:layout_height="wrap_content" 21 android:layout_centerInParent="true" 22 android:text="This is Title" 23 android:textColor="#fff" 24 android:textSize="20sp" /> 25 26 </RelativeLayout>
在这个布局文件中,我们首先定义了一个RelativeLayout作为背景布局,然后在这个布局里定义了一个Button和一个TextView,Button就是标题栏中的返回按钮,TextView就是标题栏中的显示的文字。
接下来创建一个TitleView继承自FrameLayout,代码如下所示:
1 package com.example.androidexpriment; 2 3 import android.app.Activity; 4 import android.content.Context; 5 import android.util.AttributeSet; 6 import android.view.LayoutInflater; 7 import android.view.View; 8 import android.widget.Button; 9 import android.widget.FrameLayout; 10 import android.widget.TextView; 11 12 public class TitleView extends FrameLayout { 13 14 private Button leftButton; 15 16 private TextView titleText; 17 18 public TitleView(Context context, AttributeSet attrs) { 19 super(context, attrs); 20 LayoutInflater.from(context).inflate(R.layout.title, this); 21 titleText = (TextView) findViewById(R.id.title_text); 22 leftButton = (Button) findViewById(R.id.button_left); 23 leftButton.setOnClickListener(new OnClickListener() { 24 @Override 25 public void onClick(View v) { 26 ((Activity) getContext()).finish(); 27 } 28 }); 29 } 30 31 public void setTitleText(String text) { 32 titleText.setText(text); 33 } 34 35 public void setLeftButtonText(String text) { 36 leftButton.setText(text); 37 } 38 39 public void setLeftButtonListener(OnClickListener l) { 40 leftButton.setOnClickListener(l); 41 } 42 43 }
得到了LayoutInflater的实例之后就可以调用它的inflate()方法来加载布局了,
20行 LayoutInflater.from(context).inflate(R.layout.title, this);加载布局必不可少,可以不返回布局实例
TitleView中的代码非常简单,在TitleView的构建方法中,我们调用了LayoutInflater的inflate()方法来加载刚刚定义的title.xml布局,这部分内容我们已经在 Android LayoutInflater原理分析,带你一步步深入了解View(一) 这篇文章中学习过了。
接下来调用findViewById()方法获取到了返回按钮的实例,然后在它的onClick事件中调用finish()方法来关闭当前的Activity,也就相当于实现返回功能了。
另外,为了让TitleView有更强地扩展性,我们还提供了setTitleText()、setLeftButtonText()、setLeftButtonListener()等方法,分别用于设置标题栏上的文字、返回按钮上的文字、以及返回按钮的点击事件。
到了这里,一个自定义的标题栏就完成了,那么下面又到了如何引用这个自定义View的部分,其实方法基本都是相同的,在布局文件中添加如下代码:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" > 5 6 <com.example.androidexpriment.TitleView 7 android:id="@+id/title_view" 8 android:layout_width="match_parent" 9 android:layout_height="wrap_content" > 10 </com.example.androidexpriment.TitleView> 11 12 </RelativeLayout>
下面的这种写法只能称作引入布局,不能响应事件。可参考
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" > 5 <include layout="@layout/title" 6 android:id="@+id/title_view" 7 /> 8 </RelativeLayout>
这样就成功将一个标题栏控件引入到布局文件中了,运行一下程序,效果如下图所示:
现在点击一下Back按钮,就可以关闭当前的Activity了。如果你想要修改标题栏上显示的内容,或者返回按钮的默认事件,只需要在Activity中通过findViewById()方法得到TitleView的实例,然后调用setTitleText()、setLeftButtonText()、setLeftButtonListener()等方法进行设置就OK了。
自定义布局:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" android:layout_width="fill_parent" 4 android:layout_height="fill_parent"> 5 6 <LinearLayout 7 android:layout_width="match_parent" 8 android:layout_height="60dp" 9 android:background="@color/dark" 10 android:orientation="horizontal"> 11 <ImageButton 12 android:id="@+id/ib_back" 13 android:layout_width="50dp" 14 android:layout_height="50dp" 15 android:scaleType="fitCenter" 16 android:background="#00000000" 17 android:padding="15dp" 18 android:layout_gravity="center" 19 android:src="@drawable/back"/>" 20 <TextView 21 android:layout_width="wrap_content" 22 android:layout_height="wrap_content" 23 android:textColor="#FFFFFF" 24 android:layout_marginLeft="80dp" 25 android:textSize="30sp" 26 android:layout_gravity="center" 27 android:text="应用列表"/> 28 29 30 </LinearLayout> 31 <LinearLayout android:id="@+id/listLinearLayout" 32 android:layout_width="fill_parent" android:layout_height="wrap_content" 33 android:orientation="vertical"> 34 <ListView android:id="@+id/list" android:layout_width="fill_parent" 35 android:layout_height="wrap_content" 36 android:background="@color/listbackground" 37 android:drawSelectorOnTop="true" 38 android:scrollbars="vertical" /> 39 </LinearLayout> 40 </LinearLayout>
同样的布局在做自定义的时候建议采用下面的,简洁:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:background="@color/dark" android:orientation="horizontal"> <ImageButton android:id="@+id/ib_back" android:layout_width="50dp" android:layout_height="50dp" android:scaleType="fitCenter" android:background="#00000000" android:padding="15dp" android:layout_gravity="center" android:src="@drawable/back"/>" <TextView android:id="@+id/title_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:layout_marginLeft="75dp" android:textSize="30sp" android:layout_gravity="center" android:text="应用列表"/> </LinearLayout> <ListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/listbackground" android:drawSelectorOnTop="true" android:scrollbars="vertical" /> </LinearLayout>
下面的相对布局不知道为啥有问题
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="50dp" 5 android:background="@color/dark" > 6 7 <ImageButton 8 android:id="@+id/ib_back" 9 android:layout_width="50dp" 10 android:layout_height="50dp" 11 android:scaleType="fitCenter" 12 android:background="#00000000" 13 android:padding="15dp" 14 android:layout_gravity="center" 15 android:src="@drawable/back"/>" 16 <TextView 17 android:id="@+id/title_text" 18 android:layout_width="wrap_content" 19 android:layout_height="wrap_content" 20 android:textColor="#FFFFFF" 21 android:layout_centerInParent="true" 22 android:textSize="30sp" 23 android:text="应用列表"/> 24 <ListView android:id="@+id/list" android:layout_width="fill_parent" 25 android:layout_height="wrap_content" 26 android:background="@color/listbackground" 27 android:layout_below="@+id/title_text" 28 android:drawSelectorOnTop="true" 29 android:scrollbars="vertical" /> 30 31 </RelativeLayout>