当前位置: 代码迷 >> Android >> android TAb分页菜单兑现总结
  详细解决方案

android TAb分页菜单兑现总结

热度:29   发布时间:2016-05-01 13:42:50.0
android TAb分页菜单实现总结

????? 首先说明的是,我们做APP开发,Tab分页不管是顶部还是底部,都是必不可少的,网上也有太多太多的实现方式了,我在这里总结一下:

? ? ? 第一种方式:?TabHost原始方式:(链接另一篇文章

? ? ? 这里实现的是底部菜单:

? ? ? 布局文件:(我们通过RelativeLayout 可以把TabWidget定位在底部)? ??

?

[java] view plaincopyprint?
  1. <?xml?version="1.0"?encoding="utf-8"?>??
  2. <TabHost?xmlns:android="http://schemas.android.com/apk/res/android"??
  3. ????android:id="@android:id/tabhost"??
  4. ????android:layout_width="fill_parent"??
  5. ????android:layout_height="fill_parent"?>??
  6. ??
  7. ????<RelativeLayout??
  8. ????????android:layout_width="fill_parent"??
  9. ????????android:layout_height="fill_parent"??
  10. ????????android:orientation="vertical"??
  11. ????????android:padding="3dp"?>??
  12. ??
  13. ????????<FrameLayout??
  14. ????????????android:id="@android:id/tabcontent"??
  15. ????????????android:layout_width="fill_parent"??
  16. ????????????android:layout_height="fill_parent"??
  17. ????????????android:layout_weight="1"?>??
  18. ????????</FrameLayout>??
  19. ??
  20. ????????<TabWidget??
  21. ????????????android:id="@android:id/tabs"??
  22. ????????????android:layout_width="fill_parent"??
  23. ????????????android:layout_height="wrap_content"??
  24. ????????????android:layout_alignBottom="@android:id/tabcontent"??
  25. ????????????android:background="@drawable/tabbar_bg"?/>??
  26. ????</RelativeLayout>??
  27. ??
  28. </TabHost>??
<?xml version="1.0" encoding="utf-8"?><TabHost xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@android:id/tabhost"    android:layout_width="fill_parent"    android:layout_height="fill_parent" >    <RelativeLayout        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:orientation="vertical"        android:padding="3dp" >        <FrameLayout            android:id="@android:id/tabcontent"            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:layout_weight="1" >        </FrameLayout>        <TabWidget            android:id="@android:id/tabs"            android:layout_width="fill_parent"            android:layout_height="wrap_content"            android:layout_alignBottom="@android:id/tabcontent"            android:background="@drawable/tabbar_bg" />    </RelativeLayout></TabHost>

?

在这里我们将说明一下:之前我是获取到TabWidget的view试图及内部icon和title,然后控制实现其效果,但是我们也可以用另外一种方式,也就是我们调用TabHost.TabSpec 的setIndicator(View view);这个方法,我们可以定制显示的view,

代码片段:

?

[java] view plaincopyprint?
  1. /***?
  2. ?????*?创建footerview?
  3. ?????*/??
  4. ????public?void?createFooterView()?{??
  5. ????????tabHost?=?getTabHost();?//?The?activity?TabHost ??
  6. ??
  7. ????????view?=?new?TabView(this,?R.drawable.tabbar_icon_home,??
  8. ????????????????R.drawable.tabbar_icon_home_selecotr);??
  9. ????????view.setBackgroundDrawable(this.getResources().getDrawable(??
  10. ????????????????R.drawable.footer_view_selector));??
  11. ????????intent?=?new?Intent(MainActivity.this,?HomeActivity.class);??
  12. ????????spec?=?tabHost.newTabSpec("num1").setIndicator(view).setContent(intent);??
  13. ????????tabHost.addTab(spec);??
  14. ??
  15. ????????view?=?new?TabView(this,?R.drawable.tabbar_icon_search,??
  16. ????????????????R.drawable.tabbar_icon_search_selecotr);??
  17. ????????view.setBackgroundDrawable(this.getResources().getDrawable(??
  18. ????????????????R.drawable.footer_view_selector));??
  19. ????????intent?=?new?Intent(MainActivity.this,?HomeActivity.class);??
  20. ????????spec?=?tabHost.newTabSpec("num2").setIndicator(view).setContent(intent);??
  21. ????????tabHost.addTab(spec);??
  22. ??
  23. ????????view?=?new?TabView(this,?R.drawable.tabbar_icon_cart,??
  24. ????????????????R.drawable.tabbar_icon_cart_selector);??
  25. ????????view.setBackgroundDrawable(this.getResources().getDrawable(??
  26. ????????????????R.drawable.footer_view_selector));??
  27. ????????intent?=?new?Intent(MainActivity.this,?HomeActivity.class);??
  28. ????????spec?=?tabHost.newTabSpec("num3").setIndicator(view).setContent(intent);??
  29. ????????tabHost.addTab(spec);??
  30. ??
  31. ????????view?=?new?TabView(this,?R.drawable.tabbar_icon_more,??
  32. ????????????????R.drawable.tabbar_icon_more_selecotr);??
  33. ????????view.setBackgroundDrawable(this.getResources().getDrawable(??
  34. ????????????????R.drawable.footer_view_selector));??
  35. ????????intent?=?new?Intent(MainActivity.this,?HomeActivity.class);??
  36. ????????spec?=?tabHost.newTabSpec("num4").setIndicator(view).setContent(intent);??
  37. ????????tabHost.addTab(spec);??
  38. ????}??
/***	 * 创建footerview	 */	public void createFooterView() {		tabHost = getTabHost(); // The activity TabHost		view = new TabView(this, R.drawable.tabbar_icon_home,				R.drawable.tabbar_icon_home_selecotr);		view.setBackgroundDrawable(this.getResources().getDrawable(				R.drawable.footer_view_selector));		intent = new Intent(MainActivity.this, HomeActivity.class);		spec = tabHost.newTabSpec("num1").setIndicator(view).setContent(intent);		tabHost.addTab(spec);		view = new TabView(this, R.drawable.tabbar_icon_search,				R.drawable.tabbar_icon_search_selecotr);		view.setBackgroundDrawable(this.getResources().getDrawable(				R.drawable.footer_view_selector));		intent = new Intent(MainActivity.this, HomeActivity.class);		spec = tabHost.newTabSpec("num2").setIndicator(view).setContent(intent);		tabHost.addTab(spec);		view = new TabView(this, R.drawable.tabbar_icon_cart,				R.drawable.tabbar_icon_cart_selector);		view.setBackgroundDrawable(this.getResources().getDrawable(				R.drawable.footer_view_selector));		intent = new Intent(MainActivity.this, HomeActivity.class);		spec = tabHost.newTabSpec("num3").setIndicator(view).setContent(intent);		tabHost.addTab(spec);		view = new TabView(this, R.drawable.tabbar_icon_more,				R.drawable.tabbar_icon_more_selecotr);		view.setBackgroundDrawable(this.getResources().getDrawable(				R.drawable.footer_view_selector));		intent = new Intent(MainActivity.this, HomeActivity.class);		spec = tabHost.newTabSpec("num4").setIndicator(view).setContent(intent);		tabHost.addTab(spec);	}
[java] view plaincopyprint?
  1. /***?
  2. ?????*?自定义view?
  3. ?????*??
  4. ?????*/??
  5. ????class?TabView?extends?LinearLayout?{??
  6. ????????ImageView?imageView;??
  7. ??
  8. ????????public?TabView(Context?c,?int?drawable,?int?drawableselec)?{??
  9. ????????????super(c);??
  10. ????????????imageView?=?new?ImageView(c);??
  11. ????????????//?可以定制点击后状态 ??
  12. ????????????StateListDrawable?listDrawable?=?new?StateListDrawable();??
  13. ????????????//?未选 ??
  14. ????????????listDrawable.addState(SELECTED_STATE_SET,?this.getResources()??
  15. ????????????????????.getDrawable(drawableselec));??
  16. ????????????//?选择 ??
  17. ????????????listDrawable.addState(ENABLED_STATE_SET,?this.getResources()??
  18. ????????????????????.getDrawable(drawable));??
  19. ????????????imageView.setImageDrawable(listDrawable);//?引用?StateListDrawable ??
  20. ????????????setGravity(Gravity.CENTER);??
  21. ????????????addView(imageView);??
  22. ????????}??
  23. ????}??
/***	 * 自定义view	 * 	 */	class TabView extends LinearLayout {		ImageView imageView;		public TabView(Context c, int drawable, int drawableselec) {			super(c);			imageView = new ImageView(c);			// 可以定制点击后状态			StateListDrawable listDrawable = new StateListDrawable();			// 未选			listDrawable.addState(SELECTED_STATE_SET, this.getResources()					.getDrawable(drawableselec));			// 选择			listDrawable.addState(ENABLED_STATE_SET, this.getResources()					.getDrawable(drawable));			imageView.setImageDrawable(listDrawable);// 引用 StateListDrawable			setGravity(Gravity.CENTER);			addView(imageView);		}	}

?

这样我们就实现想要的效果了.(建议使用这种方法,我的项目就是用的这个实现的.
如果我是图标和文字分开的,我们也可以用(RadioButton代替,也许大家都不陌生,一会我简单介绍下)

?

???????????

这个源码是因为项目里面用的。有时间整理下上传上去,不过我相信大家看过都会做出来的.


第二种方法:GridView+ActivityGroup (图片 ,文字)
? ? (为了省事,我把上下tab分页整理到一个demo里面了.)
? ? 这个的布局文件我就不显示了,因为比较简单,我们还是来看代码吧.

代码片段: ?

?

[java] view plaincopyprint?
  1. /***?
  2. ?*?适配器?
  3. ?*??
  4. [email protected]?
  5. ?*??
  6. ?*/??
  7. public?class?ImageAdapter?extends?BaseAdapter?{??
  8. ??
  9. ????private?Context?mContext;??
  10. ????private?ImageTextButton[]?imgItems;??
  11. ????private?int?selResId;??
  12. ??
  13. ????/***?
  14. ?????*??
  15. [email protected]?
  16. [email protected]?
  17. [email protected]?
  18. [email protected]?
  19. [email protected]?
  20. [email protected]?
  21. ?????*/??
  22. ????public?ImageAdapter(Context?c,?int[]?picIds,?String?titles[],?int?width,??
  23. ????????????int?height,?int?selResId)?{??
  24. ????????mContext?=?c;??
  25. ????????this.selResId?=?selResId;??
  26. ????????imgItems?=?new?ImageTextButton[picIds.length];??
  27. ????????for?(int?i?=?0;?i?<?picIds.length;?i++)?{??
  28. ????????????imgItems[i]?=?new?ImageTextButton(mContext);??
  29. ??
  30. ????????????imgItems[i]??
  31. ????????????????????.setLayoutParams(new?GridView.LayoutParams(width,?height));//?设置ImageView宽高 ??
  32. ????????????imgItems[i].setPadding(2,?2,?2,?2);??
  33. ????????????//?显示图片与文本 ??
  34. ????????????imgItems[i].setImageResource(picIds[i],?titles[i]);??
  35. ????????}??
  36. ????}??
  37. ??
  38. ????@Override??
  39. ????public?int?getCount()?{??
  40. ????????return?imgItems.length;??
  41. ????}??
  42. ??
  43. ????@Override??
  44. ????public?Object?getItem(int?position)?{??
  45. ????????return?position;??
  46. ????}??
  47. ??
  48. ????@Override??
  49. ????public?long?getItemId(int?position)?{??
  50. ????????return?position;??
  51. ????}??
  52. ??
  53. ????/***?
  54. ?????*?设置选中后的效果?
  55. ?????*/??
  56. ????public?void?SetFocus(int?index)?{??
  57. ??
  58. ????????for?(int?i?=?0;?i?<?imgItems.length;?i++)?{??
  59. ????????????//?先把所有设为最初状态 ??
  60. ????????????if?(i?!=?index)?{??
  61. ????????????????imgItems[i].setBackgroundResource(0);//?回到最初样式 ??
  62. ????????????}??
  63. ????????}??
  64. ????????//?选中设置 ??
  65. ????????imgItems[index].setBackgroundResource(selResId);??
  66. ????}??
  67. ??
  68. ????@Override??
  69. ????public?View?getView(int?position,?View?convertView,?ViewGroup?parent)?{??
  70. ????????ImageTextButton?imageView;??
  71. ????????if?(convertView?==?null)?{??
  72. ????????????imageView?=?imgItems[position];??
  73. ????????}?else?{??
  74. ????????????imageView?=?(ImageTextButton)?convertView;??
  75. ????????}??
  76. ????????return?imageView;??
  77. ????}??
  78. ??
  79. }??
/*** * 适配器 *  * @author Administrator *  */public class ImageAdapter extends BaseAdapter {	private Context mContext;	private ImageTextButton[] imgItems;	private int selResId;	/***	 * 	 * @param c	 * @param picIds	 * @param titles	 * @param width	 * @param height	 * @param selResId	 */	public ImageAdapter(Context c, int[] picIds, String titles[], int width,			int height, int selResId) {		mContext = c;		this.selResId = selResId;		imgItems = new ImageTextButton[picIds.length];		for (int i = 0; i < picIds.length; i++) {			imgItems[i] = new ImageTextButton(mContext);			imgItems[i]					.setLayoutParams(new GridView.LayoutParams(width, height));// 设置ImageView宽高			imgItems[i].setPadding(2, 2, 2, 2);			// 显示图片与文本			imgItems[i].setImageResource(picIds[i], titles[i]);		}	}	@Override	public int getCount() {		return imgItems.length;	}	@Override	public Object getItem(int position) {		return position;	}	@Override	public long getItemId(int position) {		return position;	}	/***	 * 设置选中后的效果	 */	public void SetFocus(int index) {		for (int i = 0; i < imgItems.length; i++) {			// 先把所有设为最初状态			if (i != index) {				imgItems[i].setBackgroundResource(0);// 回到最初样式			}		}		// 选中设置		imgItems[index].setBackgroundResource(selResId);	}	@Override	public View getView(int position, View convertView, ViewGroup parent) {		ImageTextButton imageView;		if (convertView == null) {			imageView = imgItems[position];		} else {			imageView = (ImageTextButton) convertView;		}		return imageView;	}}
在这里我们用到了自定义控件,其实就是把imageview 和textview 整到一起了,
[java] view plaincopyprint?
  1. ??
[java] view plaincopyprint?
  1. /***?
  2. ?*?自定义控件(图片文字)?
  3. ?*/??
  4. public?class?ImageTextButton?extends?LinearLayout?{??
  5. ????private?ImageView?button?=?null;??
  6. ????private?TextView?text?=?null;??
  7. ????private?Context?context;??
  8. ??
  9. ??
  10. ????public?ImageTextButton(Context?context)?{??
  11. ????????this(context,?null);??
  12. ????????this.context?=?context;??
  13. ????}??
  14. ??
  15. ??
  16. ????public?ImageTextButton(Context?context,?AttributeSet?attrs)?{??
  17. ????????super(context,?attrs);??
  18. ????????LayoutInflater.from(context).inflate(R.layout.imagetextbutton,?this,??
  19. ????????????????true);??
  20. ????????button?=?(ImageView)?this.findViewById(R.id.button);??
  21. ????????text?=?(TextView)?this.findViewById(R.id.btnText);??
  22. ????????text.setSingleLine(true);??
  23. ????}??
  24. ??
  25. ??
  26. ????public?void?setImageResource(int?image_id,?String?title)?{??
  27. ????????Bitmap?bitmap?=?BitmapFactory.decodeResource(context.getResources(),??
  28. ????????????????image_id);??
  29. ????????button.setBackgroundDrawable(new?BitmapDrawable(bitmap));??
  30. ????????text.setText(title);??
  31. ????}??
  32. ??
  33. ??
  34. ????public?void?setImageBitmap(Bitmap?bitmap)?{??
  35. ????????if?(button?!=?null)??
  36. ????????????button.setImageBitmap(bitmap);??
  37. ????}??
  38. ??
  39. ??
  40. ????public?void?setBackgroundDrawable(Drawable?drawable,?int?Width,?int?Hdight)?{??
  41. ????????if?(button?!=?null)?{??
  42. ????????????button.setBackgroundDrawable(drawable);??
  43. ????????????button.setMinimumHeight(Hdight);??
  44. ????????????button.setMinimumWidth(Width);??
  45. ????????}??
  46. ??
  47. ??
  48. ????}??
  49. ??
  50. ??
  51. ????public?void?setText(String?title)?{??
  52. ????????if?(text?!=?null)??
  53. ????????????text.setText(title);??
  54. ????}??
  55. ??
  56. ??
  57. ????public?void?setText(int?ResID)?{??
  58. ????????if?(text?!=?null)??
  59. ????????????text.setText(ResID);??
  60. ????}??
  61. ??
  62. ??
  63. ????public?void?setWidth(int?width)?{??
  64. ????????button.setMaxWidth(width);??
  65. ????}??
  66. ??
  67. ??
  68. ????public?void?setHeight(int?height)?{??
  69. ????????button.setMaxHeight(height);??
  70. ????}??
  71. ??
  72. ??
  73. }??
/*** * 自定义控件(图片文字) */public class ImageTextButton extends LinearLayout {	private ImageView button = null;	private TextView text = null;	private Context context;	public ImageTextButton(Context context) {		this(context, null);		this.context = context;	}	public ImageTextButton(Context context, AttributeSet attrs) {		super(context, attrs);		LayoutInflater.from(context).inflate(R.layout.imagetextbutton, this,				true);		button = (ImageView) this.findViewById(R.id.button);		text = (TextView) this.findViewById(R.id.btnText);		text.setSingleLine(true);	}	public void setImageResource(int image_id, String title) {		Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),				image_id);		button.setBackgroundDrawable(new BitmapDrawable(bitmap));		text.setText(title);	}	public void setImageBitmap(Bitmap bitmap) {		if (button != null)			button.setImageBitmap(bitmap);	}	public void setBackgroundDrawable(Drawable drawable, int Width, int Hdight) {		if (button != null) {			button.setBackgroundDrawable(drawable);			button.setMinimumHeight(Hdight);			button.setMinimumWidth(Width);		}	}	public void setText(String title) {		if (text != null)			text.setText(title);	}	public void setText(int ResID) {		if (text != null)			text.setText(ResID);	}	public void setWidth(int width) {		button.setMaxWidth(width);	}	public void setHeight(int height) {		button.setMaxHeight(height);	}}
我们只需要在oncreate中调用即可:
[java] view plaincopyprint?
  1. @Override??
  2. ????public?void?onCreate(Bundle?savedInstanceState)?{??
  3. ????????super.onCreate(savedInstanceState);??
  4. ????????setContentView(R.layout.main);??
  5. ????????Navigation_Top_Bar?=?(GridView)?this??
  6. ????????????????.findViewById(R.id.Navigation_Top_Bar);??
  7. ????????Navigation_Buttom_Bar?=?(GridView)?this??
  8. ????????????????.findViewById(R.id.Navigation_Buttom_Bar);??
  9. ????????//?获取显示宽度 ??
  10. ????????int?width?=?this.getWindowManager().getDefaultDisplay().getWidth()??
  11. ????????????????/?topbar_image_array.length;??
  12. ??
  13. ????????topImgAdapter1?=?new?ImageAdapter(this,?topbar_image_array,?titles,??
  14. ????????????????width,?100,?R.drawable.cover);??
  15. ??
  16. ????????Init(Navigation_Top_Bar,?topImgAdapter1);??
  17. ??
  18. ????????ButtomImgAdapter2?=?new?ImageAdapter(this,?topbar_image_array,?titles,??
  19. ????????????????width,?100,?R.drawable.cover);??
  20. ??
  21. ????????Init(Navigation_Buttom_Bar,?ButtomImgAdapter2);??
  22. ??
  23. ????}??
@Override	public void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.main);		Navigation_Top_Bar = (GridView) this				.findViewById(R.id.Navigation_Top_Bar);		Navigation_Buttom_Bar = (GridView) this				.findViewById(R.id.Navigation_Buttom_Bar);		// 获取显示宽度		int width = this.getWindowManager().getDefaultDisplay().getWidth()				/ topbar_image_array.length;		topImgAdapter1 = new ImageAdapter(this, topbar_image_array, titles,				width, 100, R.drawable.cover);		Init(Navigation_Top_Bar, topImgAdapter1);		ButtomImgAdapter2 = new ImageAdapter(this, topbar_image_array, titles,				width, 100, R.drawable.cover);		Init(Navigation_Buttom_Bar, ButtomImgAdapter2);	}
这个实现起来有点复杂,不过用习惯了会觉得别有一翻风味的.我之前就一直用这个方法.
在这里我要说明一点:
imgItems[i].setLayoutParams(new GridView.LayoutParams(width, height));// 设置ImageView宽高
其他的都是细节上的问题,我想你们看过都会ok的.
效果图:

? ??? ??

? ?

(怎么样,效果还不错吧。就是实现起来有点负责,不过习惯就好.)


? 源码下载


第三种方法:ActivityGroup+一些TextView布局.(在这里我们自定实现动态滚动效果)
? ? ? ? ? ? ? ? ? ? 详情请查看前面一片文章:android 分页Title栏滑块效果--ActionBar(模拟网易 腾讯等动态效果)
? ? ? ? ? ?分页Tab的实现方法和上面方法类是,都是运用ActivityGroup的性质,而上面是通过GridView生成,而我们这边是我们自定义View控件实现.
? ? ? ? ? 这里我主要说一下怎样实现ActionBar:
? ? ? ? ?代码片段:

?

[java] view plaincopyprint?
  1. /***?
  2. ?*?自定义控件?
  3. ?*??
  4. [email protected]?
  5. ?*??
  6. ?*?????????在这里我要说明一点?我们在创建RectF矩形的时候,?
  7. ?*??
  8. ?*?????????参照物原点是所在"父控件的左上角".?
  9. ?*??
  10. ?*/??
  11. public?class?ActionBar?extends?LinearLayout?implements?OnClickListener?{??
  12. ??
  13. ????private?ImageView?tv1;??
  14. ????private?ImageView?tv2;??
  15. ????private?ImageView?tv3;??
  16. ????private?ImageView?tv4;??
  17. ????private?Paint?paint;//?画笔 ??
  18. ????private?RectF?curRectF;//?draw当前bar ??
  19. ????private?RectF?tarRectF;//?draw被点击bar ??
  20. ??
  21. ????private?final?int?space_x?=?0;//?相当于pading. ??
  22. ????private?final?int?space_y?=?0;//?相当于pading ??
  23. ????private?final?double?step?=?32;//?速度step. ??
  24. ??
  25. ??????
  26. ????public?ActionBar(Context?context)?{??
  27. ????????super(context);??
  28. ????}??
  29. ??
  30. ????/***?
  31. ?????*?构造方法?
  32. ?????*??
  33. [email protected]?
  34. [email protected]?
  35. ?????*/??
  36. ????public?ActionBar(Context?context,?AttributeSet?attrs)?{??
  37. ????????super(context,?attrs);??
  38. ????????setWillNotDraw(false);??
  39. ????????LayoutInflater.from(context).inflate(R.layout.action_bar,?this,?true);??
  40. ????????paint?=?new?Paint();??
  41. ????????paint.setAntiAlias(true);??
  42. ????????tv1?=?(ImageView)?findViewById(R.id.tv1);??
  43. ????????tv2?=?(ImageView)?findViewById(R.id.tv2);??
  44. ????????tv3?=?(ImageView)?findViewById(R.id.tv3);??
  45. ????????tv4?=?(ImageView)?findViewById(R.id.tv4);??
  46. ????????tv1.setOnClickListener(this);??
  47. ????????tv2.setOnClickListener(this);??
  48. ????????tv3.setOnClickListener(this);??
  49. ????????tv4.setOnClickListener(this);??
  50. ????????curRectF?=?null;??
  51. ????????tarRectF?=?null;??
  52. ????}??
  53. ??
  54. ????/***?
  55. ?????*?invalidate():调用这个方法会执行onDraw()方法,但是前提是:自己把invalidate()方法执行结束在进行执行.?
  56. ?????*/??
  57. ??
  58. ????@Override??
  59. ????protected?void?onDraw(Canvas?canvas)?{??
  60. ????????super.onDraw(canvas);??
  61. ????????canvas.drawColor(Color.BLACK);??
  62. ????????paint.setColor(Color.RED);??
  63. ????????//?如果当前curRectF=null,也就是第一次访问,则默认为draw第一个bar ??
  64. ????????if?(curRectF?==?null)??
  65. ????????????curRectF?=?new?RectF(tv1.getLeft()?+?space_x,?tv1.getTop()??
  66. ????????????????????+?space_y,?tv1.getRight()?-?space_x,?tv1.getBottom()??
  67. ????????????????????-?space_y);??
  68. ??
  69. ????????//?第一次方位tarRectF=null,默认为draw ??
  70. ????????if?(tarRectF?==?null)??
  71. ????????????tarRectF?=?new?RectF(tv1.getLeft()?+?space_x,?tv1.getTop()??
  72. ????????????????????+?space_y,?tv1.getRight()?-?space_x,?tv1.getBottom()??
  73. ????????????????????-?space_y);??
  74. ????????/***?
  75. ?????????*?作用:如果在这个范围内则,以这个为最终位置,(不明的白的话,你可以把这个注释运行下你就知道why了.)?
  76. ?????????*/??
  77. ????????if?(Math.abs(curRectF.left?-?tarRectF.left)?<?step)?{??
  78. ????????????curRectF.left?=?tarRectF.left;??
  79. ????????????curRectF.right?=?tarRectF.right;??
  80. ????????}??
  81. ??
  82. ????????/***?
  83. ?????????*?说明目标在当前的左侧,需要向左移动(每次矩形移动step,则进行invalidate(),从新进行移动...)?
  84. ?????????*/??
  85. ????????if?(curRectF.left?>?tarRectF.left)?{??
  86. ????????????curRectF.left?-=?step;??
  87. ????????????curRectF.right?-=?step;??
  88. ????????????invalidate();//?继续刷新,从而实现滑动效果,每次step32. ??
  89. ????????}??
  90. ????????/***?
  91. ?????????*?说明目标在当前的右侧,需要向右移动(每次矩形移动step,则进行invalidate(),从新进行移动...)?
  92. ?????????*/??
  93. ????????else?if?(curRectF.left?<?tarRectF.left)?{??
  94. ????????????curRectF.left?+=?step;??
  95. ????????????curRectF.right?+=?step;??
  96. ????????????invalidate();??
  97. ????????}??
  98. ????????//?canvas.drawRect(curRectF,?paint); ??
  99. ????????//?参数,矩形,弧度,画笔 ??
  100. ????????canvas.drawRoundRect(curRectF,?5,?5,?paint);??
  101. ????}??
  102. ??
  103. ????/****?
  104. ?????*?这里要记录目标矩形的坐标?
  105. ?????*/??
  106. ????@Override??
  107. ????public?void?onClick(View?v)?{??
  108. ????????tarRectF.left?=?v.getLeft()?+?space_x;??
  109. ????????tarRectF.right?=?v.getRight()?-?space_x;??
  110. ????????invalidate();//?刷新 ??
  111. ??
  112. ????????System.out.println("tarRectF.top="?+?tarRectF.top?+?",v.getTop()="??
  113. ????????????????+?v.getTop()?+?",?v.getBottom()"?+?v.getBottom());??
  114. ????}??
  115. ??
  116. }??
/*** * 自定义控件 *  * @author zhangjia *  *         在这里我要说明一点 我们在创建RectF矩形的时候, *  *         参照物原点是所在"父控件的左上角". *  */public class ActionBar extends LinearLayout implements OnClickListener {	private ImageView tv1;	private ImageView tv2;	private ImageView tv3;	private ImageView tv4;	private Paint paint;// 画笔	private RectF curRectF;// draw当前bar	private RectF tarRectF;// draw被点击bar	private final int space_x = 0;// 相当于pading.	private final int space_y = 0;// 相当于pading	private final double step = 32;// 速度step.		public ActionBar(Context context) {		super(context);	}	/***	 * 构造方法	 * 	 * @param context	 * @param attrs	 */	public ActionBar(Context context, AttributeSet attrs) {		super(context, attrs);		setWillNotDraw(false);		LayoutInflater.from(context).inflate(R.layout.action_bar, this, true);		paint = new Paint();		paint.setAntiAlias(true);		tv1 = (ImageView) findViewById(R.id.tv1);		tv2 = (ImageView) findViewById(R.id.tv2);		tv3 = (ImageView) findViewById(R.id.tv3);		tv4 = (ImageView) findViewById(R.id.tv4);		tv1.setOnClickListener(this);		tv2.setOnClickListener(this);		tv3.setOnClickListener(this);		tv4.setOnClickListener(this);		curRectF = null;		tarRectF = null;	}	/***	 * invalidate():调用这个方法会执行onDraw()方法,但是前提是:自己把invalidate()方法执行结束在进行执行.	 */	@Override	protected void onDraw(Canvas canvas) {		super.onDraw(canvas);		canvas.drawColor(Color.BLACK);		paint.setColor(Color.RED);		// 如果当前curRectF=null,也就是第一次访问,则默认为draw第一个bar		if (curRectF == null)			curRectF = new RectF(tv1.getLeft() + space_x, tv1.getTop()					+ space_y, tv1.getRight() - space_x, tv1.getBottom()					- space_y);		// 第一次方位tarRectF=null,默认为draw		if (tarRectF == null)			tarRectF = new RectF(tv1.getLeft() + space_x, tv1.getTop()					+ space_y, tv1.getRight() - space_x, tv1.getBottom()					- space_y);		/***		 * 作用:如果在这个范围内则,以这个为最终位置,(不明的白的话,你可以把这个注释运行下你就知道why了.)		 */		if (Math.abs(curRectF.left - tarRectF.left) < step) {			curRectF.left = tarRectF.left;			curRectF.right = tarRectF.right;		}		/***		 * 说明目标在当前的左侧,需要向左移动(每次矩形移动step,则进行invalidate(),从新进行移动...)		 */		if (curRectF.left > tarRectF.left) {			curRectF.left -= step;			curRectF.right -= step;			invalidate();// 继续刷新,从而实现滑动效果,每次step32.		}		/***		 * 说明目标在当前的右侧,需要向右移动(每次矩形移动step,则进行invalidate(),从新进行移动...)		 */		else if (curRectF.left < tarRectF.left) {			curRectF.left += step;			curRectF.right += step;			invalidate();		}		// canvas.drawRect(curRectF, paint);		// 参数,矩形,弧度,画笔		canvas.drawRoundRect(curRectF, 5, 5, paint);	}	/****	 * 这里要记录目标矩形的坐标	 */	@Override	public void onClick(View v) {		tarRectF.left = v.getLeft() + space_x;		tarRectF.right = v.getRight() - space_x;		invalidate();// 刷新		System.out.println("tarRectF.top=" + tarRectF.top + ",v.getTop()="				+ v.getTop() + ", v.getBottom()" + v.getBottom());	}}
?上面已经讲的很详细了,就不啰嗦了.
? 效果图:
???????????

?大致就这么多了。

? ?源码下载

额外:还有一点就是有的会用到RadioButton这个控件,其实就是对其进行了一些调整,这里我简单说明一下应用:
? ?可以取消button样式,用android:drawableTop显示图片,从而达到想要的效果.

?

[java] view plaincopyprint?
  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. ????<RadioGroup??
  7. ????????android:layout_width="fill_parent"??
  8. ????????android:layout_height="wrap_content"??
  9. ????????android:layout_gravity="bottom"??
  10. ????????android:background="@drawable/maintab_toolbar_bg"??
  11. ????????android:gravity="center"??
  12. ????????android:orientation="horizontal"?>??
  13. ??
  14. ????????<RadioButton??
  15. ????????????android:id="@+id/button1"??
  16. ????????????android:layout_width="match_parent"??
  17. ????????????android:layout_height="match_parent"??
  18. ????????????android:layout_gravity="center"??
  19. ????????????android:layout_weight="1"??
  20. ????????????android:background="@drawable/home_btn_bg"??
  21. ????????????android:button="@null"??
  22. ????????????android:drawableTop="@drawable/icon_1_n"??
  23. ????????????android:gravity="center"??
  24. ????????????android:paddingTop="5dp"??
  25. ????????????android:text="首页"??
  26. ????????????android:textSize="12sp"?/>??
  27. ??
  28. ????????<RadioButton??
  29. ????????????android:id="@+id/button2"??
  30. ????????????android:layout_width="match_parent"??
  31. ????????????android:layout_height="match_parent"??
  32. ????????????android:layout_weight="1"??
  33. ????????????android:background="@drawable/home_btn_bg"??
  34. ????????????android:button="@null"??
  35. ????????????android:drawableTop="@drawable/icon_2_n"??
  36. ????????????android:gravity="center"??
  37. ????????????android:paddingTop="5dp"??
  38. ????????????android:text="短信"??
  39. ????????????android:textSize="12sp"?/>??
  40. ??
  41. ????????<RadioButton??
  42. ????????????android:id="@+id/button3"??
  43. ????????????android:layout_width="match_parent"??
  44. ????????????android:layout_height="match_parent"??
  45. ????????????android:layout_weight="1"??
  46. ????????????android:background="@drawable/home_btn_bg"??
  47. ????????????android:button="@null"??
  48. ????????????android:drawableTop="@drawable/icon_3_n"??
  49. ????????????android:gravity="center"??
  50. ????????????android:paddingTop="5dp"??
  51. ????????????android:text="联系人"??
  52. ????????????android:textSize="12sp"?/>??
  53. ??
  54. ????????<RadioButton??
  55. ????????????android:id="@+id/button4"??
  56. ????????????android:layout_width="match_parent"??
  57. ????????????android:layout_height="match_parent"??
  58. ????????????android:layout_weight="1"??
  59. ????????????android:background="@drawable/home_btn_bg"??
  60. ????????????android:button="@null"??
  61. ????????????android:drawableTop="@drawable/icon_4_n"??
  62. ????????????android:gravity="center"??
  63. ????????????android:paddingTop="5dp"??
  64. ????????????android:text="搜索"??
  65. ????????????android:textSize="12sp"?/>??
  66. ????</RadioGroup>??
  67. ??
  68. </RelativeLayout>??
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <RadioGroup        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_gravity="bottom"        android:background="@drawable/maintab_toolbar_bg"        android:gravity="center"        android:orientation="horizontal" >        <RadioButton            android:id="@+id/button1"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:layout_gravity="center"            android:layout_weight="1"            android:background="@drawable/home_btn_bg"            android:button="@null"            android:drawableTop="@drawable/icon_1_n"            android:gravity="center"            android:paddingTop="5dp"            android:text="首页"            android:textSize="12sp" />        <RadioButton            android:id="@+id/button2"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@drawable/home_btn_bg"            android:button="@null"            android:drawableTop="@drawable/icon_2_n"            android:gravity="center"            android:paddingTop="5dp"            android:text="短信"            android:textSize="12sp" />        <RadioButton            android:id="@+id/button3"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@drawable/home_btn_bg"            android:button="@null"            android:drawableTop="@drawable/icon_3_n"            android:gravity="center"            android:paddingTop="5dp"            android:text="联系人"            android:textSize="12sp" />        <RadioButton            android:id="@+id/button4"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@drawable/home_btn_bg"            android:button="@null"            android:drawableTop="@drawable/icon_4_n"            android:gravity="center"            android:paddingTop="5dp"            android:text="搜索"            android:textSize="12sp" />    </RadioGroup></RelativeLayout>
这里我们还需要selector.xml?
? 实现点击效果.

?

?

[java] view plaincopyprint?
  1. <?xml?version="1.0"?encoding="utf-8"?>??
  2. <selector?xmlns:android="http://schemas.android.com/apk/res/android">??
  3. ??
  4. ??
  5. ????<item?android:drawable="@drawable/home_btn_bg_s"?android:state_enabled="true"?android:state_focused="true"?android:state_pressed="false"/>??
  6. ????<item?android:drawable="@drawable/home_btn_bg_s"?android:state_enabled="true"?android:state_pressed="true"/>??
  7. ????<item?android:drawable="@drawable/home_btn_bg_d"?android:state_checked="true"?android:state_enabled="true"/>??
  8. ??
  9. ??
  10. </selector>??
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@drawable/home_btn_bg_s" android:state_enabled="true" android:state_focused="true" android:state_pressed="false"/>    <item android:drawable="@drawable/home_btn_bg_s" android:state_enabled="true" android:state_pressed="true"/>    <item android:drawable="@drawable/home_btn_bg_d" android:state_checked="true" android:state_enabled="true"/></selector>

?

示例图:

?????

?

源码下载

?

就说这么多了,情况因人而异.



[java] view plaincopyprint?
  1. <PRE></PRE>??
  2. <PRE></PRE>??
  3. <PRE></PRE>??
  4. <PRE></PRE>??
  5. <PRE></PRE>??
  6. <PRE></PRE>??
  7. <PRE></PRE>??
  相关解决方案