天天看点

Android自定义控件之联动视图

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

/**
 * 联动视图控件适配器 
 * 若要更改样式 请重载响应的方法
 * @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);
	
}
           
/**
 * 联动视图组件
 * @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;
	}
}