Android自定义控件之联动视图 .

本文介绍了一种联动视图组件的实现方式,包括自定义的GangedPageAdapter适配器和GangedPage组件,用于创建带有底部导航的ViewPage效果。组件支持自定义样式,并详细展示了如何设置菜单栏背景、按钮间距等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果么就是ViewPage + 底部导航,效果还不错...Adapter类请在《Android自定义控件之广告视图》中查找....

  1. /** 
  2.  * 联动视图控件适配器  
  3.  * 若要更改样式 请重载响应的方法 
  4.  * @author: linxcool.hu 
  5.  */  
  6. public abstract class GangedPageAdapter extends Adapter{  
  7.     /** 
  8.      * 标题宽度 
  9.      * @return 
  10.      */  
  11.     public int getMenuWidth(Context context){  
  12.         return getFixPx(context,100);  
  13.     }  
  14.     /** 
  15.      * 标题高度 
  16.      * @return 
  17.      */  
  18.     public int getMenuHeight(Context context){  
  19.         return getFixPx(context,50);  
  20.     }  
  21.       
  22.     public View[] getMenus() {  
  23.         int count=getCount();  
  24.         View[] views=new View[count];  
  25.         for (int i = 0; i < count; i++) {  
  26.             views[i]=getMenu(i);  
  27.         }  
  28.         return views;  
  29.     }  
  30.       
  31.     public abstract View getMenu(int position);  
  32.       
  33. }  
/**
 * 联动视图控件适配器 
 * 若要更改样式 请重载响应的方法
 * @author: linxcool.hu
 */
public abstract class GangedPageAdapter extends Adapter{
	/**
	 * 标题宽度
	 * @return
	 */
	public int getMenuWidth(Context context){
		return getFixPx(context,100);
	}
	/**
	 * 标题高度
	 * @return
	 */
	public int getMenuHeight(Context context){
		return getFixPx(context,50);
	}
	
	public View[] getMenus() {
		int count=getCount();
		View[] views=new View[count];
		for (int i = 0; i < count; i++) {
			views[i]=getMenu(i);
		}
		return views;
	}
	
	public abstract View getMenu(int position);
	
}

  1. /** 
  2.  * 联动视图组件 
  3.  * @author: linxcool.hu 
  4.  */  
  5. public class GangedPage extends LinearLayout{  
  6.     public interface OnPageSelectedListener{  
  7.         public void onPageSelected(int position);  
  8.     };  
  9.     private OnPageSelectedListener listener;  
  10.       
  11.     private GangedPageAdapter adapter;  
  12.       
  13.     //标题栏   
  14.     private HorizontalScrollView topMenuScrollView;  
  15.     private RadioButton[] radioBtns;  
  16.     private View[] menuViews;  
  17.     //页面栏   
  18.     private View[] pages;  
  19.     //选中的背景   
  20.     private View checkedBg;  
  21.     //页面   
  22.     private ViewPager viewPager;  
  23.     //附加属性   
  24.     private int menuWidth;  
  25.     private int menuHeight;  
  26.     private float currentCheckedBtnToLeftSpace;  
  27.     private int lastCheckedId;  
  28.       
  29.     public void setOnPageSelectedListener(OnPageSelectedListener listener) {  
  30.         this.listener = listener;  
  31.     }  
  32.       
  33.     public View getPage(int position){  
  34.         return pages[position];  
  35.     }  
  36.       
  37.     public boolean setSelected(int position){  
  38.         if(position<0||position>radioBtns.length)  
  39.             return false;  
  40.         if(lastCheckedId!=position)  
  41.             radioBtns[position].performClick();  
  42.         else if(listener!=null)  
  43.             listener.onPageSelected(position);  
  44.         return true;  
  45.     }  
  46.       
  47.     /** 
  48.      * 设置菜单栏的背景 
  49.      * @param defaultMenuBg 
  50.      */  
  51.     public void setTitleBackground(int color){  
  52.         topMenuScrollView.setBackgroundColor(color);  
  53.     }  
  54.     /** 
  55.      * 设置菜单栏的背景 
  56.      * @param drawable 
  57.      */  
  58.     public void setTitleBackground(Drawable drawable){  
  59.         topMenuScrollView.setBackgroundDrawable(drawable);  
  60.     }  
  61.       
  62.     /** 
  63.      * 设置菜单按钮间距 
  64.      * @param size 
  65.      */  
  66.     public void setMenuItemBlankSpace(int size){  
  67.         for (int i = 0; i < radioBtns.length; i++) {  
  68.             LayoutParams btnParams=(LayoutParams) radioBtns[i].getLayoutParams();  
  69.             if(i!=radioBtns.length-1)  
  70.                 btnParams.setMargins(00,size, 0);  
  71.               
  72.             menuViews[i].setLayoutParams(btnParams);  
  73.             radioBtns[i].setLayoutParams(btnParams);  
  74.         }  
  75.     }  
  76.       
  77.     public GangedPage(Context context) {  
  78.         super(context);  
  79.         setOrientation(VERTICAL);  
  80.     }  
  81.       
  82.     public void setAdapter(GangedPageAdapter adapter){  
  83.         this.adapter=adapter;  
  84.         initResource();  
  85.         initPages();  
  86.         initMenus();  
  87.         lastCheckedId=0;  
  88.         radioBtns[lastCheckedId].setChecked(true);  
  89.     }  
  90.       
  91.     /** 
  92.      * 构造器 
  93.      * @param context 
  94.      * @param adapter 
  95.      */  
  96.     public GangedPage(Context context,GangedPageAdapter adapter) {  
  97.         this(context);  
  98.         setAdapter(adapter);  
  99.     }  
  100.   
  101.     protected void initResource(){  
  102.         menuWidth=adapter.getMenuWidth(getContext());  
  103.         menuHeight=adapter.getMenuHeight(getContext());  
  104.         menuViews=adapter.getMenus();  
  105.         checkedBg=adapter.getCheckedBg();  
  106.         pages=adapter.getPages();  
  107.     }  
  108.   
  109.     protected void initMenus(){  
  110.         //最外层滚动栏   
  111.         topMenuScrollView=new HorizontalScrollView(getContext());  
  112.         topMenuScrollView.setHorizontalScrollBarEnabled(false);  
  113.         topMenuScrollView.setBackgroundColor(Color.WHITE);  
  114.         topMenuScrollView.setFadingEdgeLength(0);  
  115.         LayoutParams svParams=new LayoutParams(  
  116.                 LayoutParams.FILL_PARENT,menuHeight);  
  117.         this.addView(topMenuScrollView,svParams);  
  118.   
  119.         RelativeLayout outLayout=new RelativeLayout(getContext());  
  120.         topMenuScrollView.addView(outLayout,  
  121.                 new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));  
  122.         //Frame可叠加层   
  123.         FrameLayout menuFrame=new FrameLayout(getContext());  
  124.         RelativeLayout.LayoutParams frameParams=new RelativeLayout.LayoutParams(  
  125.                 LayoutParams.FILL_PARENT,menuHeight);  
  126.         outLayout.addView(menuFrame,frameParams);  
  127.         //叠加层:背景特效容器   
  128.         LinearLayout menuBgLayout=new LinearLayout(getContext());  
  129.         menuBgLayout.setOrientation(RadioGroup.HORIZONTAL);  
  130.         FrameLayout.LayoutParams bParams=new FrameLayout.LayoutParams(  
  131.                 LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);  
  132.         menuFrame.addView(menuBgLayout,bParams);  
  133.         //叠加层:显示内容容器   
  134.         LinearLayout menuItemLayout=new LinearLayout(getContext());  
  135.         menuItemLayout.setOrientation(RadioGroup.HORIZONTAL);  
  136.         FrameLayout.LayoutParams cParams=new FrameLayout.LayoutParams(  
  137.                 LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);  
  138.         menuFrame.addView(menuItemLayout,cParams);  
  139.         //叠加层:单选按钮容器   
  140.         RadioGroup menuRadioGroup=new RadioGroup(getContext());  
  141.         menuRadioGroup.setOrientation(RadioGroup.HORIZONTAL);  
  142.         menuFrame.addView(menuRadioGroup,cParams);  
  143.   
  144.         radioBtns=new RadioButton[menuViews.length];  
  145.         for (int i = 0; i < menuViews.length; i++) {  
  146.             //背景内容视图   
  147.             LinearLayout.LayoutParams btnParams=new LinearLayout.LayoutParams(  
  148.                     menuWidth, menuHeight,1.0f);  
  149.             /*if(i!=menuViews.length-1) 
  150.                 btnParams.setMargins(0, 0,1, 0);*/  
  151.             menuItemLayout.addView(menuViews[i],btnParams);  
  152.             //单选按钮视图   
  153.             radioBtns[i]=new RadioButton(getContext());  
  154.             radioBtns[i].setId(i);  
  155.             radioBtns[i].setButtonDrawable(android.R.color.transparent);  
  156.             menuRadioGroup.addView(radioBtns[i],btnParams);  
  157.         }  
  158.         menuRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {  
  159.             @Override  
  160.             public void onCheckedChanged(RadioGroup group, int checkedId) {  
  161.                 //下方线条动画   
  162.                 AnimationSet aniSet = new AnimationSet(true);  
  163.                 TranslateAnimation tAni=new TranslateAnimation(  
  164.                         currentCheckedBtnToLeftSpace,checkedId*menuWidth, 0f, 0f);  
  165.                 aniSet.addAnimation(tAni);  
  166.                 //aniSet.setFillBefore(false);   
  167.                 aniSet.setFillAfter(true);  
  168.                 aniSet.setDuration(200);  
  169.                 checkedBg.startAnimation(aniSet);  
  170.                 //设置当前显示的Page   
  171.                 viewPager.setCurrentItem(checkedId);  
  172.                 //重置currentCheckedBtnToLeftSpace 并滚动标题位置   
  173.                 currentCheckedBtnToLeftSpace = getCurrentCheckedBtnToLeftSpace();  
  174.                 float x=currentCheckedBtnToLeftSpace-menuWidth;  
  175.                 topMenuScrollView.smoothScrollTo((int)x,0);  
  176.                 //修改颜色   
  177.                 lastCheckedId=checkedId;  
  178.             }  
  179.         });  
  180.   
  181.         //选中背景   
  182.         LayoutParams ivParams=new LayoutParams(  
  183.                 menuWidth,menuHeight-adapter.getFixPx(getContext(), 4));  
  184.         menuBgLayout.setGravity(Gravity.CENTER_VERTICAL);  
  185.         menuBgLayout.addView(checkedBg,ivParams);  
  186.         currentCheckedBtnToLeftSpace=getCurrentCheckedBtnToLeftSpace();  
  187.     }  
  188.   
  189.     protected void initPages(){  
  190.         viewPager=new ViewPager(getContext()){  
  191.             @Override  
  192.             public boolean onInterceptTouchEvent(MotionEvent arg0) {  
  193.                 return super.onInterceptTouchEvent(arg0);  
  194.                 //return false;   
  195.             }  
  196.         };  
  197.         LayoutParams vpParams=new LayoutParams(  
  198.                 LayoutParams.FILL_PARENT,0,1.0f);  
  199.         this.addView(viewPager,vpParams);  
  200.         viewPager.setAdapter(new PagerAdapter() {  
  201.             @Override  
  202.             public boolean isViewFromObject(View arg0, Object arg1) {  
  203.                 return arg0==arg1;  
  204.             }  
  205.             @Override  
  206.             public int getCount() {  
  207.                 return pages.length;  
  208.             }  
  209.             @Override  
  210.             public void destroyItem(View container, int position, Object object) {  
  211.                 ((ViewPager)container).removeView(pages[position]);  
  212.             }  
  213.             @Override  
  214.             public Object instantiateItem(View v, int position) {  
  215.                 ((ViewPager)v).addView(pages[position]);  
  216.                 return pages[position];  
  217.             }  
  218.         });  
  219.         viewPager.setOnPageChangeListener(new OnPageChangeListener() {  
  220.             @Override  
  221.             public void onPageSelected(int position) {  
  222.                 radioBtns[position].performClick();  
  223.                 if(listener!=null)listener.onPageSelected(position);  
  224.             }  
  225.             @Override  
  226.             public void onPageScrolled(int arg0, float arg1, int arg2) {  
  227.   
  228.             }  
  229.             @Override  
  230.             public void onPageScrollStateChanged(int arg0) {  
  231.   
  232.             }  
  233.         });  
  234.     }  
  235.   
  236.     /** 
  237.      * 顶部被选中按钮的到左边0坐标的距离 
  238.      * @return 
  239.      */  
  240.     protected float getCurrentCheckedBtnToLeftSpace(){  
  241.         for (int i = 0; i < radioBtns.length; i++) {  
  242.             if(radioBtns[i].isChecked()){  
  243.                 return menuWidth*i;  
  244.             }  
  245.         }  
  246.         return 0f;  
  247.     }  
  248. }  
/**
 * 联动视图组件
 * @author: linxcool.hu
 */
public class GangedPage extends LinearLayout{
	public interface OnPageSelectedListener{
		public void onPageSelected(int position);
	};
	private OnPageSelectedListener listener;
	
	private GangedPageAdapter adapter;
	
	//标题栏
	private HorizontalScrollView topMenuScrollView;
	private RadioButton[] radioBtns;
	private View[] menuViews;
	//页面栏
	private View[] pages;
	//选中的背景
	private View checkedBg;
	//页面
	private ViewPager viewPager;
	//附加属性
	private int menuWidth;
	private int menuHeight;
	private float currentCheckedBtnToLeftSpace;
	private int lastCheckedId;
	
	public void setOnPageSelectedListener(OnPageSelectedListener listener) {
		this.listener = listener;
	}
	
	public View getPage(int position){
		return pages[position];
	}
	
	public boolean setSelected(int position){
		if(position<0||position>radioBtns.length)
			return false;
		if(lastCheckedId!=position)
			radioBtns[position].performClick();
		else if(listener!=null)
			listener.onPageSelected(position);
		return true;
	}
	
	/**
	 * 设置菜单栏的背景
	 * @param defaultMenuBg
	 */
	public void setTitleBackground(int color){
		topMenuScrollView.setBackgroundColor(color);
	}
	/**
	 * 设置菜单栏的背景
	 * @param drawable
	 */
	public void setTitleBackground(Drawable drawable){
		topMenuScrollView.setBackgroundDrawable(drawable);
	}
	
	/**
	 * 设置菜单按钮间距
	 * @param size
	 */
	public void setMenuItemBlankSpace(int size){
		for (int i = 0; i < radioBtns.length; i++) {
			LayoutParams btnParams=(LayoutParams) radioBtns[i].getLayoutParams();
			if(i!=radioBtns.length-1)
				btnParams.setMargins(0, 0,size, 0);
			
			menuViews[i].setLayoutParams(btnParams);
			radioBtns[i].setLayoutParams(btnParams);
		}
	}
	
	public GangedPage(Context context) {
		super(context);
		setOrientation(VERTICAL);
	}
	
	public void setAdapter(GangedPageAdapter adapter){
		this.adapter=adapter;
		initResource();
		initPages();
		initMenus();
		lastCheckedId=0;
		radioBtns[lastCheckedId].setChecked(true);
	}
	
	/**
	 * 构造器
	 * @param context
	 * @param adapter
	 */
	public GangedPage(Context context,GangedPageAdapter adapter) {
		this(context);
		setAdapter(adapter);
	}

	protected void initResource(){
		menuWidth=adapter.getMenuWidth(getContext());
		menuHeight=adapter.getMenuHeight(getContext());
		menuViews=adapter.getMenus();
		checkedBg=adapter.getCheckedBg();
		pages=adapter.getPages();
	}

	protected void initMenus(){
		//最外层滚动栏
		topMenuScrollView=new HorizontalScrollView(getContext());
		topMenuScrollView.setHorizontalScrollBarEnabled(false);
		topMenuScrollView.setBackgroundColor(Color.WHITE);
		topMenuScrollView.setFadingEdgeLength(0);
		LayoutParams svParams=new LayoutParams(
				LayoutParams.FILL_PARENT,menuHeight);
		this.addView(topMenuScrollView,svParams);

		RelativeLayout outLayout=new RelativeLayout(getContext());
		topMenuScrollView.addView(outLayout,
				new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
		//Frame可叠加层
		FrameLayout menuFrame=new FrameLayout(getContext());
		RelativeLayout.LayoutParams frameParams=new RelativeLayout.LayoutParams(
				LayoutParams.FILL_PARENT,menuHeight);
		outLayout.addView(menuFrame,frameParams);
		//叠加层:背景特效容器
		LinearLayout menuBgLayout=new LinearLayout(getContext());
		menuBgLayout.setOrientation(RadioGroup.HORIZONTAL);
		FrameLayout.LayoutParams bParams=new FrameLayout.LayoutParams(
				LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);
		menuFrame.addView(menuBgLayout,bParams);
		//叠加层:显示内容容器
		LinearLayout menuItemLayout=new LinearLayout(getContext());
		menuItemLayout.setOrientation(RadioGroup.HORIZONTAL);
		FrameLayout.LayoutParams cParams=new FrameLayout.LayoutParams(
				LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);
		menuFrame.addView(menuItemLayout,cParams);
		//叠加层:单选按钮容器
		RadioGroup menuRadioGroup=new RadioGroup(getContext());
		menuRadioGroup.setOrientation(RadioGroup.HORIZONTAL);
		menuFrame.addView(menuRadioGroup,cParams);

		radioBtns=new RadioButton[menuViews.length];
		for (int i = 0; i < menuViews.length; i++) {
			//背景内容视图
			LinearLayout.LayoutParams btnParams=new LinearLayout.LayoutParams(
					menuWidth, menuHeight,1.0f);
			/*if(i!=menuViews.length-1)
				btnParams.setMargins(0, 0,1, 0);*/
			menuItemLayout.addView(menuViews[i],btnParams);
			//单选按钮视图
			radioBtns[i]=new RadioButton(getContext());
			radioBtns[i].setId(i);
			radioBtns[i].setButtonDrawable(android.R.color.transparent);
			menuRadioGroup.addView(radioBtns[i],btnParams);
		}
		menuRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
			@Override
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				//下方线条动画
				AnimationSet aniSet = new AnimationSet(true);
				TranslateAnimation tAni=new TranslateAnimation(
						currentCheckedBtnToLeftSpace,checkedId*menuWidth, 0f, 0f);
				aniSet.addAnimation(tAni);
				//aniSet.setFillBefore(false);
				aniSet.setFillAfter(true);
				aniSet.setDuration(200);
				checkedBg.startAnimation(aniSet);
				//设置当前显示的Page
				viewPager.setCurrentItem(checkedId);
				//重置currentCheckedBtnToLeftSpace 并滚动标题位置
				currentCheckedBtnToLeftSpace = getCurrentCheckedBtnToLeftSpace();
				float x=currentCheckedBtnToLeftSpace-menuWidth;
				topMenuScrollView.smoothScrollTo((int)x,0);
				//修改颜色
				lastCheckedId=checkedId;
			}
		});

		//选中背景
		LayoutParams ivParams=new LayoutParams(
				menuWidth,menuHeight-adapter.getFixPx(getContext(), 4));
		menuBgLayout.setGravity(Gravity.CENTER_VERTICAL);
		menuBgLayout.addView(checkedBg,ivParams);
		currentCheckedBtnToLeftSpace=getCurrentCheckedBtnToLeftSpace();
	}

	protected void initPages(){
		viewPager=new ViewPager(getContext()){
			@Override
			public boolean onInterceptTouchEvent(MotionEvent arg0) {
				return super.onInterceptTouchEvent(arg0);
				//return false;
			}
		};
		LayoutParams vpParams=new LayoutParams(
				LayoutParams.FILL_PARENT,0,1.0f);
		this.addView(viewPager,vpParams);
		viewPager.setAdapter(new PagerAdapter() {
			@Override
			public boolean isViewFromObject(View arg0, Object arg1) {
				return arg0==arg1;
			}
			@Override
			public int getCount() {
				return pages.length;
			}
			@Override
			public void destroyItem(View container, int position, Object object) {
				((ViewPager)container).removeView(pages[position]);
			}
			@Override
			public Object instantiateItem(View v, int position) {
				((ViewPager)v).addView(pages[position]);
				return pages[position];
			}
		});
		viewPager.setOnPageChangeListener(new OnPageChangeListener() {
			@Override
			public void onPageSelected(int position) {
				radioBtns[position].performClick();
				if(listener!=null)listener.onPageSelected(position);
			}
			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {

			}
			@Override
			public void onPageScrollStateChanged(int arg0) {

			}
		});
	}

	/**
	 * 顶部被选中按钮的到左边0坐标的距离
	 * @return
	 */
	protected float getCurrentCheckedBtnToLeftSpace(){
		for (int i = 0; i < radioBtns.length; i++) {
			if(radioBtns[i].isChecked()){
				return menuWidth*i;
			}
		}
		return 0f;
	}
}
资源: http://download.youkuaiyun.com/category

版权声明:本文为博主原创文章,未经博主允许不得转载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值