`
shuai1234
  • 浏览: 972325 次
  • 性别: Icon_minigender_1
  • 来自: 山西
社区版块
存档分类
最新评论

android TAb分页菜单实现总结

 
阅读更多

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

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

      这里实现的是底部菜单:

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

 

  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,

代码片段:

 

  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);
	}
  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里面了.)
    这个的布局文件我就不显示了,因为比较简单,我们还是来看代码吧.

代码片段:  

 

  1. /*** 
  2.  * 适配器 
  3.  *  
  4.  * @author Administrator 
  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.      * @param c 
  16.      * @param picIds 
  17.      * @param titles 
  18.      * @param width 
  19.      * @param height 
  20.      * @param selResId 
  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(2222);  
  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 整到一起了,
  1.   

  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中调用即可:
  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:
         代码片段:

 

  1. /*** 
  2.  * 自定义控件 
  3.  *  
  4.  * @author zhangjia 
  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.      * @param context 
  34.      * @param attrs 
  35.      */  
  36.     public ActionBar(Context context, AttributeSet attrs) {  
  37.         super(context, attrs);  
  38.         setWillNotDraw(false);  
  39.         LayoutInflater.from(context).inflate(R.layout.action_bar, thistrue);  
  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, 55, 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显示图片,从而达到想要的效果.

 

  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 
  实现点击效果.

 

 

  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>

 

示例图:

     

 

源码下载

 

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



  1. <PRE></PRE>  
  2. <PRE></PRE>  
  3. <PRE></PRE>  
  4. <PRE></PRE>  
  5. <PRE></PRE>  
  6. <PRE></PRE>  
  7. <PRE></PRE>  
分享到:
评论

相关推荐

    Android Tab分页式菜单Demo源码.rar

    7. **适配不同屏幕尺寸**: Android设备有各种各样的屏幕尺寸,因此,一个好的Demo会考虑如何让Tab分页菜单在不同设备上表现良好,包括平板电脑和手机。这可能涉及到使用比例值、dp单位、或者使用ConstraintLayout等...

    ndroid TAb分页菜单 带滑动切换_页签

    在Android应用开发中,创建一个用户友好的界面是至关重要的,而Tab分页菜单就是实现这一目标的有效方式。本文将详细讲解如何在Android中实现带有滑动切换功能的Tab分页菜单,包括两种常见的实现方法:TabHost和...

    Android应用源码之(Tab分页式菜单)-IT计算机-毕业设计.zip

    在Android应用开发中,Tab分页式菜单是一种常见的用户界面设计模式,用于组织大量内容或功能,让用户可以方便地在不同的视图之间切换。在这个"Android应用源码之(Tab分页式菜单)"的项目中,我们可以深入学习如何构建...

    Tab分页菜单

    总结来说,通过结合`GridView`和`ActivityGroup`,我们可以创建一个功能完善的Tab分页菜单,让用户在应用中轻松地在不同的内容页面之间切换。随着Android API的发展,现在更推荐使用Fragment和`FragmentTabHost`来...

    Android应用源码之(Tab分页式菜单).zip

    【Android应用源码之(Tab分页式菜单)】是一个典型的Android应用开发示例,它展示了如何在Android平台上实现Tab分页式菜单的功能。Tab分页通常用于在多个视图间切换,为用户提供清晰的导航结构。这个源码库可能是为了...

    Tab分页式菜单

    本篇文章将详细探讨如何在Android中实现Tab分页标签,特别是可滑动的Tab的三种实现方法。 1. **使用Android Support Library (TabLayout)** Android Support Library提供了`TabLayout`组件,它与`ViewPager`配合...

    安卓Android源码——(Tab分页式菜单).rar

    本资源“安卓Android源码——(Tab分页式菜单).rar”提供了一个关于如何在Android平台上实现Tab分页菜单的示例代码。 1. **TabHost与TabWidget**: 在早期的Android版本中,Tab分页主要通过TabHost和TabWidget组件来...

    安卓Android源码——(Tab分页式菜单).zip

    "安卓Android源码——(Tab分页式菜单).zip"这个压缩包很可能是包含了一个完整的示例项目,用于展示如何在Android应用中实现Tab分页菜单。 在Android中,实现Tab分页式菜单有多种方式,早期的版本通常使用`TabHost`...

    应用源码之(Tab分页式菜单).zip

    这份"应用源码之(Tab分页式菜单)"的压缩包资源,显然为我们提供了关于如何在Android应用中实现这种功能的实际代码示例。以下是围绕这个主题的详细知识点讲解: 1. **TabLayout**:TabLayout是Android Support ...

    ActionBar分页菜单

    本篇文章将详细探讨如何通过`ActionBar`来实现分页菜单,并结合`ActivityGroup`和`TextView`布局,实现动态滚动效果。 首先,`ActionBar`的分页功能通常借助`TabHost`或`ViewPager`来完成。`TabHost`在早期版本的...

    Android之ActivityGroup实现Tab分页标签

    在Android应用开发中,Tab分页标签是一种常见的用户界面设计,用于展示多个相互关联的页面或视图。这种设计能够帮助用户轻松地在不同的功能或数据集之间切换。本篇文章将详细探讨如何利用ActivityGroup来实现这样的...

    带侧拉菜单tab分页导航并且有信息数目提示的主页框架

    总结来说,"带侧拉菜单tab分页导航并且有信息数目提示的主页框架"是一个集成了多种核心功能的UI结构,它有效地利用了Android的系统组件,并通过自定义逻辑解决了横竖向滑动冲突。这个框架对于任何需要清晰导航和信息...

    3-9(Tab分页式菜单).zip

    标题 "3-9(Tab分页式菜单)" 暗示了这个压缩包可能包含一个教学或示例项目,展示了如何在用户界面中实现Tab分页式菜单的设计。这种设计通常用于应用程序或网站中,以帮助用户在多个相关但独立的内容区域之间轻松切换...

    Android 分页控件制成底部菜单

    完成以上步骤后,你就成功地在Android应用中创建了一个使用分页控件实现的底部菜单。在提供的`myTabTest`项目文件中,应该包含了实现这一功能的具体代码示例。通过分析和学习这个示例,你可以更好地理解和掌握这个...

    android自定义菜单

    4. 使用ViewPager和Fragment实现分页菜单。 5. 编写适配器,为ViewPager提供不同页面(菜单项)的Fragment。 6. 处理点击事件,实现菜单项的功能。 通过以上步骤,你可以创建出符合自己需求的自定义菜单,提升应用...

    tablayout+recyclerview 实现仿淘宝、京东商品详情滑动切换tab效果

    在Android应用开发中,创建一个类似淘宝或京东商品详情页的滑动切换Tab效果是常见的需求,这可以提升用户体验并使界面更具交互性。在这个项目中,我们将利用`TabLayout`和`RecyclerView`来实现这一功能。`TabLayout`...

    3-9(Tab-Tabbed-menu).zip_Tabú

    在安卓应用开发中,Tab-Tabbed Menu 是一个常见的用户界面设计模式,它允许用户通过在顶部或底部的标签之间切换...这个项目为初学者提供了一个很好的实践平台,让他们能够深入理解并掌握Android应用中的Tab式菜单实现。

Global site tag (gtag.js) - Google Analytics