首页 > 其他分享 >一个类似Tabs的控件SegmentControl

一个类似Tabs的控件SegmentControl

时间:2023-04-07 10:03:05浏览次数:60  
标签:控件 Tabs void private SegmentControl int import android public



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

  • 一个类似Tabs的控件SegmentControl_sed

  • 大小: 9.1 KB
  • 查看图片附件

标签:控件,Tabs,void,private,SegmentControl,int,import,android,public
From: https://blog.51cto.com/u_5454003/6174602

相关文章

  • 缓存式的ViewPager&和其他手势控件冲突的解决办法
    一般来说ViewPager如果有很多页的话,会加载它的上一页,当前页和下一页,当从n页以后再想回到第一页,就会再加载一次,这样第一页很多操作后的数据就会被重置,原因是在PagerAdapter的destroyItem经常会移除View,类似下面这样的代码:@Overridepublicvoiddest......
  • 高效快捷解决一个TextView显示多种字体的控件SpannableTextView
    这个控件本人强烈推荐,它会使得布局非常的简单且高效;下面这个布局如果是你,你会用多少层?多少控件生成?告诉你吧,一个SpannableTextView控件就搞定了!它把TextView和Spannable封装在了一起,可以在一个TextView中显示不同的字体颜色,大小,背景色等;它支持如下样式:*......
  • StepsView显示步骤执行情况的控件
    显示步骤执行情况的控件,在某些情况下,还是非常有用的。<com.anton46.stepsview.StepsViewxmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/stepsView0"android:layout_width="match_parent"......
  • WPF的控件字符串内容使用StringFormat进行字符串转换
    在WPF中TextBlock的Text有时内容只需要改变个别数字,而不需要所以内容都修改,这时候就要使用StringFormat, 如:<TextBlockText="Ihavexxxfriends"/>这里面的xxx是个变量,那在Binding时应该怎样写呢<TextBlockText="{BindingFirendNumber,StringFormat='Ihave{0}firends......
  • LabVIEW调用第三方exe软件或操作操作控制第三方软件界面的控件,如操控烧录软件等
    LabVIEW调用第三方exe软件或操作操作控制第三方软件界面的控件,如操控烧录软件等除了模拟鼠标和键盘来实现之后,还可以考虑另外一种方式,使用窗口句柄来直接操作程序如下面图片实例,操作串口助手,修改串口和波特率,并写入数据和读取数据这种方式可以避免电脑的分辨率变化和位置移动等......
  • winCE 控件篇
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //页面测试伪数据privatevoidbindNumber(){#region页面数......
  • C++ MFC中嵌入web网页控件(WebBrowser、WebView2、CEF3)
    1、简介WebBrowser控件最常见的用途之一是向应用程序添加Internet浏览功能。使用IWebBrowser2接口,可以浏览到本地文件系统、网络或万维网上的任何位置。可以使用IWebBrowser2::Navigate方法告知控件要浏览到哪个位置。第一个参数是包含位置名称的字符串。要浏览到本地文件系......
  • 界面控件开发包DevExpress v22.2.5正式发布|附高速下载
    DevExpress 拥有.NET开发需要的所有平台控件,包含600多个UI控件、报表平台、DevExpressDashboardeXpressApp框架、适用于VisualStudio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpressv22.2已全新发布,该版本拥有众多新产品和数十个具有高影响力的功能,可为桌面......
  • 界面控件DevExtreme v23.1抢先体验,增强的UI/UX自定义功能!
    DevExtreme拥有高性能的HTML5/JavaScript小部件集合,使您可以利用现代Web开发堆栈(包括React,Angular,ASP.NETCore,jQuery,Knockout等)构建交互式的Web应用程序,该套件附带功能齐全的数据网格、交互式图表小部件、数据编辑器等。本文的目的就是为了让开发者预览即将发布的DevExtreme功......
  • jeesite #form中获取控件的值,以绑定的treeselect为例
    绑定部分代码:<divclass="form-group"><#form:formid="searchForm"model="${iotDevice}"action="${ctx}/iot/iotItem/listGroupData"method="post"class="form-inline"......