接下来给大家介绍android的自定义复合控件的方法。为什么要自定义复合控件?这个问题问的比较经典。。。。大家都知道面对组件开发的开发方式有很多的好处,其中最大的好处就是能够提高组件的复用,如果组件需要变化的时候也容易进行修改和重构。举个例子来说如下图如果每个acitivity都需要一个顶部的导航的话,如果不把其当成组件进行开发那么所有的页面我们都需要对其重新进行布局,而且对该控件每个页面都需要进入和进行实现,这样显然工作量大不说,而且维护起来也有些难度。
因此,我们在这里可以采用自定义复合组件的方式实现,思路是这样的:
1、定义自定义组件布局文件
2、实现自定义组件对应的java代码
3、在所需的自定义布局文件中引用自定义组件
接下来以上图为例我们详细说说
1、在res\layout目录下新建component_top_bar.xml导航条的布局文件
<?xml version="1.0" encoding="UTF-8"?>
<cn.firefly.component.FirstPageNaviBar
android:id="@+id/topBar"
android:background="@drawable/navi_background"
android:layout_width="fill_parent" android:layout_height="45.0dip"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<Button android:textSize="14.0sp"
android:textColor="@color/white" android:id="@+id/navi_title_left"
android:background="@drawable/title_bar_button"
android:paddingLeft="6.0dip" android:paddingRight="6.0dip"
android:clickable="true" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_marginLeft="8.0dip"
android:text="@string/left_button_text"
android:layout_alignParentLeft="true" android:layout_centerVertical="true" />
<LinearLayout android:id="@+id/main"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true" android:layout_centerVertical="true">
<TextView android:textSize="18.0sp"
android:textColor="@color/white" android:id="@+id/navi_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="@string/firstpage_title" />
</LinearLayout>
<Button android:textSize="14.0sp"
android:textColor="@color/white" android:id="@+id/navi_title_right"
android:background="@drawable/title_bar_search"
android:clickable="true" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_marginRight="6.0dip"
android:layout_alignParentRight="true" android:layout_centerVertical="true" />
</cn.firefly.component.FirstPageNaviBar>
主意:标签<cn.firefly.component.FirstPageNaviBar>指向一个实现此布局文件的类名。
2、在对应的包下建立FirstPageNaviBar.java文件
package cn.firefly.component;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
public class FirstPageNaviBar extends RelativeLayout {
public FirstPageNaviBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
这里指定了FirstPageNaviBar类继承自RelativeLayout布局类,这说明我们所定义的组件其实是一个RelativeLayout的组件。我们可以在此类中实现这个按钮的点击事件,也可以写一个超类,让所有使用这个组件的页面都继承这个类。由于代码根据业务逻辑实现不同就不提供给大家了。
3、在需要引入自定义组件的地方引入,引入方式采用<include>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<include layout="@layout/component_top_bar"/>
<LinearLayout
android:id="@+id/listLinearLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<TextView
android:id="@+id/tvTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<ListView
android:id="@id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false"
android:scrollbars="vertical"
></ListView>
</LinearLayout>
</LinearLayout>
此外自定义组件也可以嵌套,比如我们又定义了一个组件是包含刚才们定义的组件的在布局文件中我们可以这样写
<?xml version="1.0" encoding="UTF-8"?>
<cn.firefly.component.HomePage
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<include android:id="@+id/topBar" layout="@layout/component_top_bar" />
<GridView
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="90dp"
android:gravity="center"
android:horizontalSpacing="10dp"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp"
android:paddingTop="10dp" />
</LinearLayout>
</cn.firefly.component.HomePage>
同样在指定包下需要创建cn.firefly.component.HomePage类,该实现的进行实现。
最后在需要引入该页面的地方,可以使用<include>标签把刚才用到的文件进行引用。
本人水平有限,如果有不明白的可以留言,我会尽量回复。
注:本文原创,转载请注明出处。