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); } }; } }