首页 > 代码库 > Android 自定义组合控件

Android 自定义组合控件

一:需要的效果如下图所示:可以动态设置提醒数,如果提醒数小于1则不显示红色提醒图标。

在点击每一个Button时,同时改变字体颜色与背景颜色以及将红色提醒去掉,如下图所示:

二:实现原理:通过继承LinearLayout进行扩展,自定义复合控件。

在创建复合控件时,必须对他包含的视图布局、外观以及交互进行定义。一般来说,复合控件是通过扩展一个ViewGroup来创建。

(1)定义一个类如WzhAlertLlBtn.java使其继承LinearLayout,代码如下:

public class WzhAlertLlBtn extends LinearLayout{    TextView alertTitle;    //设置标题    TextView alertCount;    //设置是否有提醒消息        /**     * 重写父类的构造函数,使自定义控件可以在xml布局文件中直接使用     * @param context     * @param attrs     */    public WzhAlertLlBtn(Context context, AttributeSet attrs){        super(context,attrs);                //使用自定义布局资源填充视图        LayoutInflater li = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);        li.inflate(R.layout.view_wzh_alert_ll_btn, this, true);                //获取对自控件的引用        alertTitle = (TextView)findViewById(R.id.alertTitle);        alertCount = (TextView)findViewById(R.id.alertCount);    }        /**     * @MethodName setAlertTitle      * @Description 设置标题     * @Param @param title     * @Return void     * @Throws     */    public void setAlertTitle(String title){        alertTitle.setText(title);    }        /**     * @MethodName setAlertCount      * @Description 设置是否存在提醒     * @Param @param count     * @Return void     * @Throws     */    public void setAlertCount(int count){        alertCount.setText(String.valueOf(count));        if(count>0){            alertCount.setVisibility(View.VISIBLE);        }else{            alertCount.setVisibility(View.GONE);        }    }}

(2)填充布局文件view_wzh_alert_ll_btn.xml 每一项的布局。

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"                android:paddingLeft="8dp"                android:paddingRight="8dp"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:orientation="horizontal">                  <TextView                       android:id="@+id/alertTitle"                      android:layout_width="0dp"                      android:layout_height="45dp"                      android:layout_weight="4"                      android:textSize="18sp"                      android:gravity="center_vertical"                      android:textColor="@drawable/btn_text_color"/>                  <RelativeLayout                      android:layout_width="0dp"                      android:layout_height="45dp"                      android:layout_weight="1">                      <TextView                          android:id="@+id/alertCount"                          android:layout_centerInParent="true"                          android:layout_alignParentLeft="true"                          android:layout_width="wrap_content"                          android:layout_height="wrap_content"                          android:textSize="16sp"                          android:background="@drawable/ic_alert_info"                          android:textColor="@color/white"                          android:gravity="center"/>                      <ImageView                          android:layout_centerInParent="true"                          android:layout_alignParentRight="true"                          android:layout_width="wrap_content"                          android:layout_height="wrap_content"                          android:background="@drawable/btn_go_right_bg"/>                  </RelativeLayout></LinearLayout>            

三:样式布局文件:

(1)android:textColor="@drawable/btn_text_color"  当点击控件时改变标题颜色,代码如下:

<?xml version="1.0" encoding="UTF-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:state_focused="false" android:state_enabled="true" android:state_pressed="false"          android:color="@drawable/txtBlack" />      <item android:state_enabled="false" android:color="@drawable/txtGray" />      <item android:state_pressed="true" android:color="@drawable/txtWhite" />      <item android:state_focused="true"  android:color="@drawable/txtBlack" /> </selector>

其中android:color的值在colors.xml文件中,内容如下:

<!-- Btn text color -->    <drawable name="txtBlack">#000000</drawable>      <drawable name="txtWhite">#FFFFFF</drawable>    <drawable name="txtGray">#ccc</drawable>  

(2)android:background="@drawable/ic_alert_info"  是一个九妹格式的红色图片。

(3)android:background="@drawable/btn_go_right_bg"  控件右侧的箭头,默认是灰色点击后变成白色,内容如下:

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android" >    <item android:state_pressed="true" android:drawable="@drawable/ic_go_right_click"/>    <item android:state_focused="true" android:drawable="@drawable/ic_go_right_click"/>    <item android:drawable="@drawable/ic_go_right"/></selector>

 

四:使用自定义复合控件。

(1)fragment_alert_and_emails.xml

<!-- 1项-->          <LinearLayout              android:layout_marginTop="16dp"               android:padding="1dp"             android:background="@drawable/set_ll_bg"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:orientation="vertical">                <com.wzh.view.WzhAlertLlBtn                  android:id="@+id/wzhTest1"                  android:layout_width="match_parent"                  android:layout_height="wrap_content"                  android:background="@drawable/alter_ll_one_bg"/>          </LinearLayout>                    <!-- 2项-->          <LinearLayout              android:layout_marginTop="16dp"               android:padding="1dp"             android:background="@drawable/set_ll_bg"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:orientation="vertical">                <com.wzh.view.WzhAlertLlBtn                  android:id="@+id/wzhTest2"                  android:layout_width="match_parent"                  android:layout_height="wrap_content"                  android:background="@drawable/alter_ll_top_bg"/>              <TextView style="@style/sscxTxtLine"/>                <com.wzh.view.WzhAlertLlBtn                  android:id="@+id/wzhTest3"                  android:layout_width="match_parent"                  android:layout_height="wrap_content"                  android:background="@drawable/alter_ll_bottom_bg"/>          </LinearLayout>                              <!-- 3项-->          <LinearLayout              android:layout_marginTop="16dp"               android:padding="1dp"             android:background="@drawable/set_ll_bg"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:orientation="vertical">                <com.wzh.view.WzhAlertLlBtn                  android:id="@+id/wzhTest4"                  android:layout_width="match_parent"                  android:layout_height="wrap_content"                  android:background="@drawable/alter_ll_top_bg"/>              <TextView style="@style/sscxTxtLine"/>                <com.wzh.view.WzhAlertLlBtn                  android:id="@+id/wzhTest5"                  android:layout_width="match_parent"                  android:layout_height="wrap_content"                  android:background="@drawable/alter_ll_middle_bg"/>              <TextView style="@style/sscxTxtLine"/>                <com.wzh.view.WzhAlertLlBtn                  android:id="@+id/wzhTest6"                  android:layout_width="match_parent"                  android:layout_height="wrap_content"                  android:background="@drawable/alter_ll_bottom_bg"/>          </LinearLayout>

    在使用自定义复合控件时,一定要对控件设置layout_width与layout_height属性。每一种组合都是包含在LinearLayout中,

并设置其 android:background="@drawable/set_ll_bg",set_ll_bg.xml内容如下:背景色设置为白色,边框为灰色,圆角为8dp。

<?xml version="1.0" encoding="utf-8"?><shape    xmlns:android="http://schemas.android.com/apk/res/android"     android:shape="rectangle" >    <solid android:color="#FFFFFF"/>        <stroke android:width="1dp"        android:color="#aaaaaa"/>        <corners         android:radius="8dp"/></shape>

 

对于 com.wzh.view.WzhAlertLlBtn 的 android:background 样式一共四种:

alter_ll_top_bg:表示头部第一个,当一组大于一个时才使用到;
alter_ll_middle_bg:标示介于top与bottom之间的内容样式,当一组大于两个时才使用到;
alter_ll_bottom_bg:表示底部最后一个,当一组大于一个时才使用到;
alter_ll_one_bg:表示只一组有且只有一个时使用;

(2)alter_ll_top_bg.xml
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android" >    <item android:state_pressed="true"  android:drawable="@drawable/alter_ll_top_bg_click"/>    <item android:drawable="@drawable/alter_ll_top_bg_normal"/></selector>
alter_ll_top_bg_click.xml(点击时的样式)
<?xml version="1.0" encoding="utf-8"?><shape    xmlns:android="http://schemas.android.com/apk/res/android"     android:shape="rectangle" >    <solid android:color="@color/commColor"/>        <corners         android:topLeftRadius="8dp"        android:topRightRadius="8dp"        android:bottomLeftRadius="0dp"        android:bottomRightRadius="0dp"/></shape>
alter_ll_top_bg_normal.xml (默认样式)
<?xml version="1.0" encoding="utf-8"?><shape    xmlns:android="http://schemas.android.com/apk/res/android"     android:shape="rectangle" >    <solid android:color="@color/white"/>        <corners         android:topLeftRadius="8dp"        android:topRightRadius="8dp"        android:bottomLeftRadius="0dp"        android:bottomRightRadius="0dp"/></shape>

其他三种布局文件依次类推,不再一一赘述。

(3)在AlertAndEmailsActivity.java中操作。

public class AlertAndEmailsActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_alert_and_emails);        if (savedInstanceState == null) {            getFragmentManager().beginTransaction()                    .add(R.id.container, new PlaceholderFragment()).commit();        }            }        /**     * A placeholder fragment containing a simple view.     */    public static class PlaceholderFragment extends Fragment {        WzhAlertLlBtn wzhTest1;        WzhAlertLlBtn wzhTest2,wzhTest3;        WzhAlertLlBtn wzhTest4,wzhTest5,wzhTest6;                public PlaceholderFragment() {}                @Override        public View onCreateView(LayoutInflater inflater, ViewGroup container,                Bundle savedInstanceState) {            View rootView = inflater.inflate(R.layout.fragment_alert_and_emails, container, false);                                                //wzhTest1            wzhTest1 = (WzhAlertLlBtn)rootView.findViewById(R.id.wzhTest1);            wzhTest1.setAlertTitle("自定义测试1");            wzhTest1.setAlertCount(1);            wzhTest1.setOnClickListener(btnOnClickListener);                        //wzhTest2            wzhTest2 = (WzhAlertLlBtn)rootView.findViewById(R.id.wzhTest2);            wzhTest2.setAlertTitle("自定义测试2");            wzhTest2.setAlertCount(2);            wzhTest2.setOnClickListener(btnOnClickListener);            //wzhTest3            wzhTest3 = (WzhAlertLlBtn)rootView.findViewById(R.id.wzhTest3);            wzhTest3.setAlertTitle("自定义测试3");            wzhTest3.setAlertCount(3);            wzhTest3.setOnClickListener(btnOnClickListener);                        //wzhTest4            wzhTest4 = (WzhAlertLlBtn)rootView.findViewById(R.id.wzhTest4);            wzhTest4.setAlertTitle("自定义测试4");            wzhTest4.setAlertCount(4);            wzhTest4.setOnClickListener(btnOnClickListener);            //wzhTest5            wzhTest5 = (WzhAlertLlBtn)rootView.findViewById(R.id.wzhTest5);            wzhTest5.setAlertTitle("自定义测试5");            wzhTest5.setAlertCount(5);            wzhTest5.setOnClickListener(btnOnClickListener);            //wzhTest6            wzhTest6 = (WzhAlertLlBtn)rootView.findViewById(R.id.wzhTest6);            wzhTest6.setAlertTitle("自定义测试6");            wzhTest6.setAlertCount(6);            wzhTest6.setOnClickListener(btnOnClickListener);                                                            return rootView;        }                OnClickListener btnOnClickListener = new OnClickListener(){            @Override            public void onClick(View arg0) {                wzhTest1.setAlertCount(0);            }        };    }}