一个类似Tabs的控件SegmentControl

155 篇文章 0 订阅
79 篇文章 0 订阅


package com.ql.view;

import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;

public class SegmentControl extends LinearLayout {

	private Map<Integer,IButton> indexButtonMap = new HashMap<Integer, IButton>();
	private Map<IButton,Integer> buttonIndexMap = new HashMap<IButton, Integer>();
	
	private int selectedIndex;
	
	public static final int TAB = 1;
	public static final int SEGMENT = 2;
	
	private int currentStyle = SEGMENT;
	
	private int maxButtonSize;
	private int marginsLeft = 1;
	
	private LayoutParams  layoutMarginsParams;
	
	private boolean onlyIsPressed;
	private OnSegmentChangedListener onSegmentChangedListener;
	
	public SegmentControl(Context context, AttributeSet attrs) {
		super(context,attrs);
		
		this.setOrientation(HORIZONTAL);
		layoutMarginsParams = new LayoutParams(
				LinearLayout.LayoutParams.WRAP_CONTENT,
				LinearLayout.LayoutParams.WRAP_CONTENT);
		layoutMarginsParams.setMargins(marginsLeft, 0, 0, 0);
	}
	
	public SegmentControl(Context context,int style) {
		super(context,null);
		this.setOrientation(HORIZONTAL);
		currentStyle = style;
		layoutMarginsParams = new LayoutParams(
				LinearLayout.LayoutParams.WRAP_CONTENT,
				LinearLayout.LayoutParams.WRAP_CONTENT);
		layoutMarginsParams.setMargins(marginsLeft, 0, 0, 0);
	}
	
	public void setStyle(int style) {
		
		currentStyle = style;
	}
	
	public void setWidth(int width, int height, int num) {
		
		int itemWidth = width/num;
		
		layoutMarginsParams.width = itemWidth;
		layoutMarginsParams.height = height;
	}
	
	
	public int getButtonCount(){
		return maxButtonSize;
	}
	
	public IButton getButton(int index){
		return indexButtonMap.get(index);
	}
	
	public void setSelectedIndex(int index){
		if(index <= maxButtonSize){
			selectedIndex = index;
			selectButton(index);
		}
	}
	
	public int getSelectedIndex(){
		return selectedIndex;
	}
	
	/**
	 * 废弃
	 * 请使用setOnSegmentChangedListener代替
	 * @param index
	 * @param l
	 */
	@Deprecated
	public void bindOnChooseListener(int index, IButton.OnChooseListener l){
		indexButtonMap.get(index).setOnChooseListener(l);
	}
	
	public void clearButton() {
		this.removeAllViews();
		maxButtonSize = 0;
	}
	
	public IButton newButton(int drawableId, int id){
		IButton button = new IButton(getContext(), id, IButton.PICTURE);
		button.setLayoutParams(layoutMarginsParams);

		button.setBackgroundResource(drawableId);
		
		postNewButton(button);
		return button;
	}
	
	
	private void postNewButton(IButton button){
		this.addView(button);
		addButtonToMap(button, maxButtonSize);
		maxButtonSize++;
		button.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					selectedIndex = buttonIndexMap.get(v);
					selectButton(selectedIndex);
				}
				return false;
			}
		});
	}
	public IButton newButton(String text, int id){
		IButton button = null;
		if(currentStyle == TAB){
			button = new IButton(getContext(), id, IButton.TAB);
		}else if(currentStyle == SEGMENT){
			if(maxButtonSize == 0){
				button = new IButton(getContext(), id);
			}else{
				button = new IButton(getContext(), id, IButton.SEGMENT_CENTER);
			}
			//只有2个按�?
			if(maxButtonSize == 1){
				getButton(0).changeButtonStyle(IButton.SEGMENT_LEFT);
				button.changeButtonStyle(IButton.SEGMENT_RIGHT);
			}
			
			//超过2�?
			if(maxButtonSize > 1){
					getButton(0).changeButtonStyle(IButton.SEGMENT_LEFT);
					getButton(maxButtonSize - 1).changeButtonStyle(IButton.SEGMENT_CENTER);
					button.changeButtonStyle(IButton.SEGMENT_RIGHT);
			}
			
		}
		//layoutMarginsParams = new LayoutParams(45, 35);
		button.setLayoutParams(layoutMarginsParams);
		
		//button背景色可以在这里设置
		button.setPressedColor(Color.rgb(16, 38, 55), Color.rgb(16, 38, 55));

		button.setTextSize(16);
		button.setText(text);
		postNewButton(button);
		return button;
	}
	
	private void addButtonToMap(IButton button, int index){
		this.indexButtonMap.put(maxButtonSize, button);
		this.buttonIndexMap.put(button, maxButtonSize);
	}
	
	private void selectButton(int index){
		//1
		if(maxButtonSize == 1){
			IButton button = indexButtonMap.get(0);
			button.onDefaultUp();
				if(!onlyIsPressed){
					button.onDown();
					if(button.hasPressedDrawable()){
						button.setPressedDrawable();
					}
					if(onSegmentChangedListener != null){
						onSegmentChangedListener.onSegmentChanged(button.getCmdId());
					}
					onlyIsPressed = true;
				}else{
					if(button.hasDefaultDrawable()){
						button.setDefaultDrawable();
					}
					button.onUp();
					onlyIsPressed = false;
				}
		//more
		}else{
			for (int i = 0; i < maxButtonSize; i++) {
				IButton button = indexButtonMap.get(i);
				if(i == index){
					if(button.isNormal()){
						button.onDown();
						if(button.hasPressedDrawable()){
							button.setPressedDrawable();
						}
						if(onSegmentChangedListener != null){
							onSegmentChangedListener.onSegmentChanged(button.getCmdId());
						}
					}
				}else{
					if(button.hasDefaultDrawable()){
						button.setDefaultDrawable();
					}
					button.onDefaultUp();
				}
			}
		}

	}
	
	public interface OnSegmentChangedListener{
		public void onSegmentChanged(int index);
	}
	
	public void setOnSegmentChangedListener(OnSegmentChangedListener l){
		this.onSegmentChangedListener = l;
	}
	
}


package com.ql.view;


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Button;

/**
 */
public class IButton extends Button implements OnTouchListener {
	
	private int	buttonID;
	
	private ShapeDrawable mDrawable;
	
	private boolean isPressed = false;
	private int radian;
	
    float[] DEFAULT_OUTRADII;
    float[] TAB_OUTRADII;
    float[] LEFT_OUTRADII;
    float[] RIGHT_OUTRADII;
    float[] CENTER_OUTRADII;
    private static int DEFAULT_RADIAN = 8;
    
    //#B7B7B7
    private  int DEFAULT_START_COLOR =  -4737097;
    //8F8F8F
    private int DEFAULT_END_COLOR = -7368817;

    //#9F9F9F
    private int PRESSED_START_COLOR = -6316129;
    //#767676
    private int PRESSED_END_COLOR = -9013642;
    
    public static int TAB = 1;
    public static int SEGMENT_LEFT = 2;
    public static int SEGMENT_CENTER = 3;
    public static int SEGMENT_RIGHT = 4;
    public static int DEFAULT = 0;
    public static int PICTURE = 5;
    
    private int style;
    
    private OnChooseListener mOnChooseListener;
    
    /**
     * 默认图片
     */
    private int defaultDrawableId;
    
    /**
     * 按下图片
     */
    private int pressedDrawableId;
    
    public boolean hasDefaultDrawable(){
    	if(defaultDrawableId != 0){
    		return true;
    	}else{
    		return false;
    	}
    }
    
    public boolean hasPressedDrawable(){
    	if(pressedDrawableId != 0){
    		return true;
    	}else{
    		return false;
    	}
    }
    
    public void setDefaultDrawableId(int defaultDrawableId){
    	this.defaultDrawableId = defaultDrawableId;
    }
    
    public void setDefaultDrawable(int defaultDrawableId){
    	setDefaultDrawableId(defaultDrawableId);
    	setDefaultDrawable();
    }
    
    public void setDefaultDrawable(){
    	setBackgroundResource(defaultDrawableId);
    }
    
    public void setPressedDrawable(int pressedDrawableId){
    	setPressedDrawableId(pressedDrawableId);
    	setPressedDrawable();
    }
    
    public void setPressedDrawable(){
    	setBackgroundResource(pressedDrawableId);
    }
    
    public void setPressedDrawableId(int pressedDrawableId){
    	this.pressedDrawableId = pressedDrawableId;
    }
    public void setOnChooseListener(IButton.OnChooseListener l){
    	this.mOnChooseListener = l;
    }
	public boolean isNormal(){
		return !isPressed;
	}
	
	public boolean isPressed(){
		return isPressed;
	}
	
	
	public void setRadian(int radian){
		this.radian = radian;
		initRadian();
		changeButtonStyle(style);
	}
	
	
	private void initRadian(){
	    DEFAULT_OUTRADII = new float[] { radian, radian, radian, radian, radian, radian, radian, radian };
	    TAB_OUTRADII = new float[] { radian, radian, radian, radian, 0, 0, 0, 0 };
	    LEFT_OUTRADII = new float[] { radian, radian, 0, 0, 0, 0, radian, radian };
	    RIGHT_OUTRADII = new float[] { 0, 0, radian, radian, radian, radian, 0, 0 };
	    CENTER_OUTRADII = new float[] { 0, 0, 0, 0, 0, 0, 0, 0 };
	}
	/**
	 * 
	 * @param startColor
	 * @param endColor
	 */
	public IButton setNormalColor(int startColor, int endColor){
		this.DEFAULT_START_COLOR = startColor;
		this.DEFAULT_END_COLOR = endColor;
		invalidate();
		return this;
	}
	
	/**
	 * 
	 * @param startColor
	 * @param endColor
	 */
	public IButton setPressedColor(int startColor, int endColor){
		this.PRESSED_START_COLOR = startColor;
		this.PRESSED_END_COLOR = endColor;
		invalidate();
		return this;
	}
	
	private Shader getNormalColor(int width, int height){
		return new LinearGradient(width/2,0,width/2,height,DEFAULT_START_COLOR,DEFAULT_END_COLOR,Shader.TileMode.MIRROR);  
	}
	
	private Shader getPressedColor(int width, int height){
		return new LinearGradient(width/2,0,width/2,height,PRESSED_START_COLOR,  PRESSED_END_COLOR,Shader.TileMode.MIRROR);  
	}
	
	
	public IButton(Context context, int id, int style) {
		super(context,null);
		
		this.buttonID = id;
		init(style);
	}
	
	public IButton(Context context, int id){
		super(context,null);
		
		this.buttonID = id;
		init(DEFAULT);
	}
	
	private void init(int style){
		radian = DEFAULT_RADIAN;
		initRadian();
		if(PICTURE != style){
			if(mDrawable == null){
				mDrawable = getShapeDrawable(style);
			}
			this.getBackground().setAlpha(0);
			this.setTextColor(Color.WHITE);
		}
		this.setOnTouchListener(this);
	}
	
	public IButton(Context context, int id, AttributeSet attrs) {
		super(context,attrs);
		
		this.buttonID = id;
		init(DEFAULT);
	}
	
	public IButton(Context context, int id, ShapeDrawable mDrawable){
		super(context);
		
		this.buttonID = id;
		this.mDrawable = mDrawable;
	}
	
	public int getCmdId() {
		return buttonID;
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
		if(mDrawable != null){
			mDrawable.setBounds(0, 0, this.getWidth(), this.getHeight());
			if(!isPressed){
				mDrawable.getPaint().setShader(getNormalColor(this.getWidth(), this.getHeight()));
			}else{
				mDrawable.getPaint().setShader(getPressedColor(this.getWidth(), this.getHeight()));
			}
			
			//mDrawable.getPaint().setColor(Color.BLUE);
			//mDrawable.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);
			mDrawable.draw(canvas);
		}

		Paint paint = new Paint();
		paint.setAntiAlias(true);
		paint.setStyle(Paint.Style.STROKE);
		paint.setTextAlign(Align.CENTER);
		paint.setTextSize(getTextSize());
		paint.setColor(Color.WHITE);
		FontMetrics fm = paint.getFontMetrics();
		int y = getTop() + (int)(getHeight() - fm.ascent)/2;
    	canvas.drawText((String)getText(), getWidth()/2, y, paint);
		
	}
	
	public void onDown() {
		onDefaultDown();
		if(mOnChooseListener != null){
			mOnChooseListener.onDown();
		}
	}

	public void onUp() {
		onDefaultUp();
		if(mOnChooseListener != null){
			mOnChooseListener.onUp();
		}
	}
	
	public void onDefaultUp(){
		isPressed = false;
		invalidate();
	}
	
	public void onDefaultDown(){
		isPressed = true;
		invalidate();
	}

	public void changeButtonStyle(int style){
		getShapeDrawable(style);
		invalidate();
	}
	
	private ShapeDrawable getShapeDrawable(int style){
		this.style = style;
		if(style == TAB){
			mDrawable = new ShapeDrawable(new RoundRectShape(TAB_OUTRADII, null,
					null));
		}else if(style == SEGMENT_LEFT){
			mDrawable = new ShapeDrawable(new RoundRectShape(LEFT_OUTRADII, null,
					null));
		}else if(style == SEGMENT_CENTER){
			mDrawable = new ShapeDrawable(new RoundRectShape(CENTER_OUTRADII, null,
					null));
		}else if(style == SEGMENT_RIGHT){
			mDrawable = new ShapeDrawable(new RoundRectShape(RIGHT_OUTRADII, null,
					null));
		}else{
			mDrawable = new ShapeDrawable(new RoundRectShape(DEFAULT_OUTRADII, null,
					null));
		}
		return mDrawable;
	}
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			if (!isPressed) {
				if(hasPressedDrawable()){
					setBackgroundResource(pressedDrawableId);
				}
				// 更改为按下时的背景图
				onDown();
			}
		} else if (event.getAction() == MotionEvent.ACTION_UP) {
			if (isPressed) {
				if(hasDefaultDrawable()){
					setBackgroundResource(defaultDrawableId);
				}
				// 改为抬起时的图片
				onUp();
			}
		}
		// TODO Auto-generated method stub
		return false;
	}
	
	public interface OnChooseListener{
		public void onDown();
		public void onUp();
	}
}

用法:

package com.ql.activity;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;

import com.ql.view.SegmentControl;
import com.ql.view.SegmentControl.OnSegmentChangedListener;

public class Test_5_Activity  extends Activity{
	SegmentControl segControl;
	private ViewFlipper	mFlipper;
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.test6);
        
        mFlipper = (ViewFlipper)findViewById(R.id.flipper);
        //测试界面,实际开发中是从layout中读取的,下同。
        TextView tv=new TextView(this);
        tv.setText("index=0");
        mFlipper.addView(tv);
//      tv.requestFocus();
        
        segControl = (SegmentControl)findViewById(R.id.segcontrol);
        segControl.setStyle(SegmentControl.TAB);//试试SEGMENT
        segControl.newButton("标题1", 0);
        segControl.newButton("标题2", 1);
        segControl.newButton("标题3", 2);
        segControl.newButton("标题4", 3);
        //还可试试segControl.newButton(int drawableId, int id);
        segControl.setSelectedIndex(0);
        int width = this.px2dip(this, 80*segControl.getButtonCount());
        int height = this.px2dip(this, 38);
        segControl.setWidth(width, height, segControl.getButtonCount());
        
        segControl.setOnSegmentChangedListener(new OnSegmentChangedListener() {
			
			@Override
			public void onSegmentChanged(int index) {
				//
				onChangeView(index);
			}
		});
        
    }
    private int mIndex=0;
    private void changeViewAnimation(int index, View view) {
		if(index == mIndex)
			return;
		
		mFlipper.addView(view);
		
		Animation inAnim = null;
		Animation outAnim = null;

		if(index > mIndex) {
			inAnim = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
			outAnim = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
		} else {
			inAnim = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
			outAnim = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
		}
		inAnim.setDuration(1000);
		outAnim.setDuration(1000);
		
        mFlipper.setInAnimation(inAnim);
        mFlipper.setOutAnimation(outAnim);
        mFlipper.showNext();
        //mFlipper.startFlipping();
        mFlipper.removeViewAt(0);
        
        mIndex = index;
	}
    private void onChangeView(int index) 
	{
        //测试界面,实际开发中是从layout中读取的,下同。 
    	TextView tv=new TextView(this);
    	tv.setText("index="+index);
		switch(index){
		case 0:
			Toast.makeText(this, "VIEW_TLINE", Toast.LENGTH_SHORT).show();
			changeViewAnimation(index, tv);
			break;
		case 1:
			Toast.makeText(this, "VIEW_KLINE", Toast.LENGTH_SHORT).show();
			changeViewAnimation(index, tv);
			break;
		case 2:
			Toast.makeText(this, "VIEW_DETAIL", Toast.LENGTH_SHORT).show();
			changeViewAnimation(index, tv);
			break;
		case 3:
			Toast.makeText(this, "VIEW_F10", Toast.LENGTH_SHORT).show();
			changeViewAnimation(index, tv);
			break;
		case 4:
			Toast.makeText(this, "VIEW_RADAR", Toast.LENGTH_SHORT).show();
			changeViewAnimation(index, tv);
			break;
		}
	}
    
  //dip/px像素单位转换
	public static int dip2px(Context context, float dipValue){   
        final float scale = context.getResources().getDisplayMetrics().density;   
        return (int)(dipValue / scale + 0.5f);   
    }   
	public static int px2dip(Context context, float pxValue){   
		final float scale = context.getResources().getDisplayMetrics().density;   
	    return (int)(pxValue * scale + 0.5f);   
	}  
}

text6.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
  	android:orientation="vertical"
  	android:layout_width="fill_parent"
  	android:layout_height="fill_parent">

	<com.ql.view.SegmentControl
 		android:id="@+id/segcontrol"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:layout_gravity="bottom"
 		/>
  		<!-- android:gravity="right" -->
  		
  	<ViewFlipper android:id="@+id/flipper" 
		android:layout_width="fill_parent" 
		android:layout_height="fill_parent" 
		android:gravity="center"
		/>
</LinearLayout>


妙用TabHost
http://www.cnblogs.com/over140/archive/2011/03/02/1968042.html
  • 大小: 9.1 KB
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值