Reprint please indicate this article from Jflex blog http://blog.csdn.net/jflex/article/details/46492501, please respect others ' hard work results, thank you!
Android UI Customization-similar to iOS Tabbar
Tabbar最早出现在iOS,iOS中的TabBarController实现了这个功能,开发起来相当简单。现在的APP,大多数都会使用Tabbar来作为应用的功能导航,界面简单清晰。那么Android常见的实现是通过RadioGroup来实现,今天将带来自定义实现,补充RadioGroup实现的不足。
First look at the use of common software:
This is the high-speed train Butler app, everyone should be very familiar with. At the bottom of the app's homepage is an iOS-like Tabbar. Here is not a lot of examples, then go straight to the point.
Radiogroup realize Tabbar1, why use radiogroup realization?
熟悉RadioGroup的都知道,一个RadioGroup中只能选中一个RadioButton。而Tabbar刚好就是这么一个效果,所以用RadioGroup再好不过了。
2. Implementation code
<radiogroup android:id="@+id/rghomemenu"Android:layout_width="Match_parent"android:layout_height="60DP"android:orientation="Horizontal"> <radiobutton android:layout_width="0DP"android:layout_height="Match_parent"android:layout_weight="1"android:button="@null"Android:checked="true"android:drawabletop="@drawable/icon_project_selector"android:gravity="Center"Android:paddingbottom="5DP"android:paddingtop="8DP"android:text="@string/project"Android:textcolor="@color/menu_txt_selector"Android:textsize="12SP"/> <radiobutton android:layout_width="0DP"android:layout_height="Match_parent"android:layout_weight="1"android:button="@null"android:drawabletop="@drawable/icon_msg_selector"android:gravity="Center"Android:paddingbottom="5DP"android:paddingtop="8DP"android:text="@string/msg"Android:textcolor="@color/menu_txt_selector"Android:textsize="12SP"/> <radiobutton android:layout_width="0DP"android:layout_height="Match_parent"android:layout_weight="1"android:button="@null"android:drawabletop="@drawable/icon_mine_selector"android:gravity="Center"Android:paddingbottom="5DP"android:paddingtop="8DP"android:text="@string/mine"Android:textcolor="@color/menu_txt_selector"Android:textsize="12SP"/> </RadioGroup>
-Radiogroup must use RadioButton as child control
-Since Tabbar is a piece, the following text, all need to set Android:button empty, remove the default diagram of RadioButton. Settings Android:drawabletop properties, text Settings Android:text properties, other properties according to the actual needs to adjust.
-It's easy to implement, and the code page is simple.
3. Advantages and Disadvantages
- Advantages: Simple code, easy to implement
- Disadvantage: Insufficient extensibility. Because each item is radiobutton, you can only use the relevant features of this space, and if you need to expand it, you can't.
Custom TABBAR1, requirements: For example, you now need to add an iOS-like Badgeview message prompt on the message.
2. Implementation code
TabGroup
This class needs to implement something like Radiogroup, which is implemented by the code for reference Radiogroup.
PackageCom.snicesoft.tabbar;ImportAndroid.annotation.SuppressLint;ImportAndroid.content.Context;ImportAndroid.util.AttributeSet;ImportAndroid.view.View;ImportAndroid.view.ViewGroup;ImportAndroid.widget.LinearLayout;@SuppressLint("Newapi") Public class tabgroup extends linearlayout { Public TabGroup(context context, AttributeSet attrs,intDefstyleattr,intDefstyleres) {Super(Context, Attrs, defstyleattr, defstyleres); Init (); } Public TabGroup(context context, AttributeSet attrs,intDEFSTYLEATTR) {Super(Context, attrs, defstyleattr); Init (); } Public TabGroup(context context, AttributeSet attrs) {Super(context, attrs); Init (); } Public TabGroup(Context context) {Super(context); Init (); }Private void Init() {setorientation (horizontal); }intMcheckedid =-1; Ontabgroupcheckedlistener Ontabgroupcheckedlistener; Public void Setontabgroupcheckedlistener(Ontabgroupcheckedlistener Ontabgroupcheckedlistener) { This. Ontabgroupcheckedlistener = Ontabgroupcheckedlistener; }@Override Public void AddView(View Child,intIndex, viewgroup.layoutparams params) {if(ChildinstanceofTabItem) {FinalTabItem tab = (TabItem) child;if(Tab.ischecked ()) {Check (Tab.getid ()); } }Super. AddView (Child, index, params); } Public void Check(intCheckid) {if(Mcheckedid = = Checkid) {return; } Setcheckedstateforview (Mcheckedid,false); Setcheckedid (Checkid); Mcheckedid = Checkid;if(Ontabgroupcheckedlistener! =NULL) ontabgroupcheckedlistener.onchecked (Checkid); }Private void Setcheckedid(intID) {View Checkedview = Findviewbyid (ID);if(Checkedview! =NULL&& CheckedviewinstanceofTabItem) {((TabItem) checkedview). setchecked (true); } }Private void Setcheckedstateforview(intViewId,BooleanChecked) {View Checkedview = Findviewbyid (viewId);if(Checkedview! =NULL&& CheckedviewinstanceofTabItem) {((TabItem) checkedview). setchecked (checked); } } Public interface ontabgroupcheckedlistener { Public void onchecked(intCheckedid); }}
TabItem
TabItem need to integrate RadioButton capabilities, and also need to be more scalable. Therefore, it is necessary to implement checkable to select the integrated relativelayout, which requires check state operation.
PackageCom.snicesoft.tabbar;ImportJava.util.ArrayList;ImportJava.util.HashMap;ImportAndroid.annotation.SuppressLint;ImportAndroid.content.Context;Importandroid.graphics.drawable.Drawable;Importandroid.graphics.drawable.StateListDrawable;ImportAndroid.util.AttributeSet;ImportAndroid.view.View;ImportAndroid.view.ViewGroup;Importandroid.widget.Checkable;ImportAndroid.widget.RelativeLayout;@SuppressLint("Newapi") Public class TabItem extends relativelayout implements checkable { PrivateArraylist<checkable> chechablelist =NewArraylist<checkable> ();PrivateHashmap<view, statelistdrawable> statelistdrawablemap =NewHashmap<view, statelistdrawable> ();Private Static Final int[] Checked_state_set = {Android. R.attr.state_checked}; Public TabItem(context context, AttributeSet attrs,intDefstyleattr,intDefstyleres) {Super(Context, Attrs, defstyleattr, defstyleres); Init (); } Public TabItem(context context, AttributeSet attrs,intDEFSTYLEATTR) {Super(Context, attrs, defstyleattr); Init (); } Public TabItem(context context, AttributeSet attrs) {Super(context, attrs); Init (); } Public TabItem(Context context) {Super(context); Init (); }Private void Init() {Super. Setonclicklistener (NewOnclicklistener () {@Override Public void OnClick(View v) {onchecked ();if(Onclicklistener! =NULL) Onclicklistener.onclick (v); } }); }@Override Public void AddView(View Child,intIndex, android.view.ViewGroup.LayoutParams params) {Super. AddView (Child, index, params); Setstates (child); }Private void setstates(View Child) {drawable drawable = Child.getbackground ();if(Drawable! =NULL&& drawableinstanceofstatelistdrawable) {Statelistdrawablemap.put (Child, (statelistdrawable) drawable); } child.setclickable (false);if(Childinstanceofcheckable) {Chechablelist.add (checkable) child); }if(ChildinstanceofViewGroup) {FinalViewGroup Group = (viewgroup) child;if(Group.getchildcount () >0) { for(inti =0; I < Group.getchildcount (); i++) {setstates (Group.getchildat (i)); }}}} Onclicklistener Onclicklistener;@Override Public void Setonclicklistener(Onclicklistener L) {onclicklistener = l; }BooleanisChecked =false;@Override Public void setchecked(BooleanChecked) {if(isChecked = = checked)return; for(checkable ca:chechablelist) {ca.setchecked (checked); }if(checked) { for(View V:statelistdrawablemap.keyset ()) {Statelistdrawable drawable = Statelistdrawablemap.get (v); Drawable.setstate (Checked_state_set); V.setbackground (Drawable.getcurrent ()); } }Else{ for(View V:statelistdrawablemap.keyset ()) {V.setbackground (Statelistdrawablemap.get (v)); }} isChecked = checked; }Private void onchecked() {if(GetParent ()instanceofTabGroup) {FinalTabGroup group = (tabgroup) getParent (); Group.check (GetId ()); } }@Override Public Boolean isChecked() {returnisChecked; }@Override Public void setpressed(BooleanPressed) {Super. setpressed (pressed);if(!pressed) {setchecked (true); } }@Override Public void Toggle() {setchecked (!ischecked); }}
The default component in Relativelayout with the pressed attribute is not as good as the button, which intercepts the onclick event, so all components in the TabItem are not clickable in the back settings.
- In order for TabItem compatibility to reach RadioButton, it is mandatory to invoke the Checkable method in the Setchecked method for all the integrated setchecked view contained in TabItem. Ability to achieve synchronization effect (when clicking TabItem, you can pass the check's state to the child control)
- In order for components in TabItem to be able to use selector, statelistdrawable is used to control the background display in different states.
3. Advantages and Disadvantages
- Advantages: Consistent use and radiogroup, strong extensibility
- Cons: More layout code than Radiogroup, no default checked property set
Summarize
这种自定义控件,只是在原生控件的基础上改进,是比较初级的,只需要掌握改进原理,修改的方法很多种的。本人的修改只是一个简单的演示,希望大家有好的改进方法,不吝赐教。
This example source code download
Android UI Customization-ios-like Tabbar