Scrollable可拖动的TabActivity

看图:

/**
 */
package com.ql.activity;

import java.util.ArrayList;
import java.util.List;

import com.ql.view.RadioStateDrawable;
import com.ql.view.TabBarButton;

import android.app.ActivityGroup;
import android.app.LocalActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.RadioGroup;

public class ScrollableTabActivity extends ActivityGroup  implements RadioGroup.OnCheckedChangeListener{
	
	private LocalActivityManager activityManager;
	public 	LinearLayout contentViewLayout;
	private LinearLayout.LayoutParams contentViewLayoutParams;
	//private HorizontalScrollView bottomBar;
	private RadioGroup.LayoutParams buttonLayoutParams;
	private RadioGroup bottomRadioGroup;
	//private Context context;
	public	List<Intent> intentList;
	private List<String> titleList;
	private List states;
	private SliderBarActivityDelegate delegate;
	private int defaultOffShade;
	private int defaultOnShade;
	
	private IntentFilter changeTabIntentFilter;
	private ChangeTabBroadcastReceiver changeTabBroadcastReceiver;
	public static String CURRENT_TAB_INDEX;
	public static String ACTION_CHANGE_TAB = ".changeTab";
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //context = this;
        
        activityManager = getLocalActivityManager();
        
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.customslidingtabhost);
        //getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);
        
        contentViewLayout = (LinearLayout)findViewById(R.id.contentViewLayout);
        //bottomBar = (HorizontalScrollView)findViewById(R.id.bottomBar);
        bottomRadioGroup = (RadioGroup)findViewById(R.id.bottomMenu);
        contentViewLayoutParams = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); 
        
        defaultOffShade = RadioStateDrawable.SHADE_GRAY;
        defaultOnShade = RadioStateDrawable.SHADE_YELLOW;
        
        /*
         *  alternative method to using XML for layout, not used
         */
        /*
        if (inflateXMLForContentView())
        {
        	contentViewLayoutParams = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); 
        }
        else
        {
        	RelativeLayout mainLayout = new RelativeLayout(this);
            RelativeLayout.LayoutParams mainLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
            mainLayout.setLayoutParams(mainLayoutParams);
            contentViewLayout = new LinearLayout(this);
            contentViewLayout.setOrientation(LinearLayout.VERTICAL);
            contentViewLayout.setBackgroundColor(Color.WHITE);
            contentViewLayoutParams = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
            contentViewLayoutParams.bottomMargin = 55;
            mainLayout.addView(contentViewLayout, contentViewLayoutParams);
            bottomBar = new HorizontalScrollView(this);
            //bottomBar.setHorizontalFadingEdgeEnabled(false);
            RelativeLayout.LayoutParams bottomBarLayout = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, 55);
            bottomBarLayout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            mainLayout.addView(bottomBar, bottomBarLayout);
            bottomRadioGroup = new RadioGroup(this);
            bottomRadioGroup.setOrientation(RadioGroup.HORIZONTAL);
            LayoutParams bottomRadioGroupLayoutParam = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
            bottomRadioGroup.setLayoutParams(bottomRadioGroupLayoutParam);
            bottomBar.addView(bottomRadioGroup);
            if (bottomBar()!=-1) bottomBar.setBackgroundResource(bottomBar());
            //bottomBar.setBackgroundResource(R.drawable.bottom_bar);
            setContentView(mainLayout);
        }*/
         
        bottomRadioGroup.setOnCheckedChangeListener(this);
        intentList  = new ArrayList();
        titleList	= new ArrayList();
        states 		= new ArrayList();
        
        buttonLayoutParams = new RadioGroup.LayoutParams(320/5, 55);
    }
    
    public void onResume()
    {
    	changeTabIntentFilter = new IntentFilter(ACTION_CHANGE_TAB);
    	changeTabBroadcastReceiver = new ChangeTabBroadcastReceiver();
    	registerReceiver(changeTabBroadcastReceiver, changeTabIntentFilter);
    	super.onResume();
    }
    
    public void onPause()
    {
    	unregisterReceiver(changeTabBroadcastReceiver);
    	super.onPause();
    }

    public void commit()
    {
    	bottomRadioGroup.removeAllViews();
    	
    	int optimum_visible_items_in_portrait_mode = 5;
//    	try
//    	{
//    		WindowManager window = getWindowManager();
//        	Display display = window.getDefaultDisplay();
//        	int window_width = display.getWidth();
//        	
//        	optimum_visible_items_in_portrait_mode = (int) (window_width/64.0);
//    	}
//    	catch (Exception e)
//    	{
//    		optimum_visible_items_in_portrait_mode = 5;
//    	}
//    	
    	int screen_width = getWindowManager().getDefaultDisplay().getWidth();
    	int width;
    	if (intentList.size()<=optimum_visible_items_in_portrait_mode)
    	{
    		width = screen_width/intentList.size();
    	}
    	else
    	{
    		width = screen_width/5;
    	}
    	RadioStateDrawable.width = width;
		RadioStateDrawable.screen_width = screen_width;
//		int height = ViewTools.px2dip(this, 50);
		int height = this.px2dip(this, 50);
    	RadioStateDrawable.height = height;
		buttonLayoutParams = new RadioGroup.LayoutParams(width, height);
    	
    	for (int i=0; i<intentList.size(); i++)
    	{
    		TabBarButton tabButton = new TabBarButton(this);
    		int[] iconStates = (int[]) states.get(i);
    		if (iconStates.length==1) tabButton.setState( titleList.get(i).toString(),iconStates[0]);
    		else if (iconStates.length==2) tabButton.setState(titleList.get(i).toString(), iconStates[0], iconStates[1]);
    		else if (iconStates.length==3) tabButton.setState(titleList.get(i).toString(), iconStates[0], iconStates[1], iconStates[2]);
        	tabButton.setId(i);
        	tabButton.setGravity(Gravity.CENTER);
        	bottomRadioGroup.addView(tabButton, i, buttonLayoutParams);
    	}
    	
    	setCurrentTab(0);
    }
    
    /**
     * <b><i>protected void addTab(String title, int offIconStateId, int onIconStateId, Intent intent)</i></b> <p><p>
     * Add a tab to the navigation bar by specifying the title, 1 image for button on-state, and 1 image for button off-state<p>
     * @param title				a String that specifies that title of the tab button
     * @param onIconStateId		id of the on-state image
     * @param offIconStateId	id of the off-state image
     * @param intent			intent to start when button is tapped
     */
    protected void addTab(String title, int offIconStateId, int onIconStateId, Intent intent)
    {
    	int[] iconStates = {onIconStateId, offIconStateId};
    	states.add(iconStates);
    	intentList.add(intent);
    	titleList.add(title);
    	//commit();
    }
    
    /**
     * <b><i>protected void addTab(String title, int iconStateId, Intent intent)</i></b> <p><p>
     * Add a tab to the navigation bar by specifying the title, and 1 image for the button. Default yellow/gray shade is used for button on/off state<p>
     * @param title				a String that specifies that title of the tab button
     * @param iconStateId		id of the image used for both on/off state
     * @param intent			intent to start when button is tapped
     */
    protected void addTab(String title, int iconStateId, Intent intent)
    {
    	//int[] iconStates = {iconStateId};
    	int[] iconStates = {iconStateId, defaultOffShade, defaultOnShade};
    	states.add(iconStates);
    	intentList.add(intent);
    	titleList.add(title);
    	//commit();
    }
    
    /**
     * <b><i>protected void addTab(String title, int iconStateId, int offShade, int onShade, Intent intent)</i></b> <p><p>
     * Add a tab to the navigation bar by specifying the title, and 1 image for the button. Default yellow/gray shade is used for button on/off state<p>
     * @param title				a String that specifies that title of the tab button
     * @param iconStateId		id of the image used for both on/off state
     * @param offShade  		id for off-state color shades (e.g. RadioStateDrawable.SHADE_GRAY, RadioStateDrawable.SHADE_GREEN etc)
     * @param onShade			id for on-state color shades (e.g. RadioStateDrawable.SHADE_GRAY, RadioStateDrawable.SHADE_GREEN etc)
     * @param intent			intent to start when button is tapped
     */
    protected void addTab(String title, int iconStateId, int offShade, int onShade, Intent intent)
    {
    	int[] iconStates = {iconStateId, offShade, onShade};
    	states.add(iconStates);
    	intentList.add(intent);
    	titleList.add(title);
    	//commit();
    }

    /**
     * <b><i>protected void setDefaultShde(int offShade, int onShade)</i></b><p><p>
     * Sets the default on and off color shades of the bottom bar buttons<p>
     * If not specified, the default off shade is gray, and the default on shade is yellow
     * @param offShade			id for off-state color shades (e.g. RadioStateDrawable.SHADE_GRAY, RadioStateDrawable.SHADE_GREEN etc)
     * @param onShade			id for on-state color shades (e.g. RadioStateDrawable.SHADE_GRAY, RadioStateDrawable.SHADE_GREEN etc)
     */
    protected void setDefaultShade(int offShade, int onShade)
    {
    	defaultOffShade = offShade;
    	defaultOnShade = onShade;
    }
    
    public void onCheckedChanged(RadioGroup group, int checkedId) {
    	try
    	{
    		if (delegate!=null) delegate.onTabChanged(checkedId);
    	}
    	catch (Exception e){}
    	
    	Intent intent = intentList.get(checkedId);
    	startGroupActivity( titleList.get(checkedId).toString(), intent );
    	
    	onTabChanged(checkedId, intent);
    }
    
    //
    public void onTabChanged(int checkedId, Intent intent) {
    	
    }
    
    public void startGroupActivity(String id, Intent intent)
    {
    	contentViewLayout.removeAllViews();
    	
    	View view = activityManager.startActivity(id, intent).getDecorView();
        contentViewLayout.addView(view, contentViewLayoutParams);
    }
    
    public void setCurrentTab(int index)
    {
    	bottomRadioGroup.check(index);
		startGroupActivity(titleList.get(index).toString(), (Intent)intentList.get(index));
    }
    
    public int getCurrentTab()
    {
    	return bottomRadioGroup.getCheckedRadioButtonId();
    }
    
    /*
     * gets required R, not used
     */
    public boolean inflateXMLForContentView()
    {
    	/*
    	setContentView(R.layout.customslidingtabhost);
        contentViewLayout = (LinearLayout)findViewById(R.id.contentViewLayout);
        bottomBar = (HorizontalScrollView)findViewById(R.id.bottomBar);
        bottomRadioGroup = (RadioGroup)findViewById(R.id.bottomMenu);
    	*/
    	return false;
    }
    
    public int bottomBar()
    {
    	return -1;
    }
    
    /*
     * delegates
     */
    
    public void setDelegate(SliderBarActivityDelegate delegate_)
    {
    	delegate = delegate_;
    }
    
    public static abstract class SliderBarActivityDelegate {

        /*
         * Called when tab changed
         */
        protected void onTabChanged(int tabIndex) {}
    }
    
    /*
     * Broadcast receiver to set current tab
     */
    
    public class ChangeTabBroadcastReceiver extends BroadcastReceiver
    {
    	@Override
    	public void onReceive(Context context, Intent intent)
    	{
    		int index = intent.getExtras().getInt(CURRENT_TAB_INDEX);
    		setCurrentTab(index);
    	}
    }
  //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);   
	}  
}


package com.ql.view;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.util.AttributeSet;
import android.widget.RadioButton;

public class TabBarButton extends RadioButton{
	
	Context context;
	public TabBarButton(Context context) {
		super(context);
		this.context = context;
	}
	
	public TabBarButton(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.context = context;
	}
	
	public void setState(String label, int imageId)
	{
		RadioStateDrawable offDrawable = new RadioStateDrawable(context, imageId, label, false, RadioStateDrawable.SHADE_GRAY);
		RadioStateDrawable onDrawable = new RadioStateDrawable(context, imageId, label, true, RadioStateDrawable.SHADE_YELLOW);
		setStateImageDrawables(onDrawable,offDrawable);
	}
	
	public void setState(String label, int imageId, int offState, int onState)
	{
		RadioStateDrawable offDrawable = new RadioStateDrawable(context, imageId, label, false, offState);
		RadioStateDrawable onDrawable = new RadioStateDrawable(context, imageId, label, true, onState);
		setStateImageDrawables(onDrawable,offDrawable);
	}

	public void setState(String label, int onId, int offId)
	{
		Resources resource = this.getResources();
		Drawable offDrawable = resource.getDrawable(offId);
		Drawable onDrawable = resource.getDrawable(onId);
		setStateImageDrawables(onDrawable,offDrawable);
	}
	
	private void setStateImageDrawables(Drawable onDrawable, Drawable offDrawable)
	{
		StateListDrawable drawables = new StateListDrawable();
		
		int stateChecked = android.R.attr.state_checked;
		int stateFocused = android.R.attr.state_focused;
		int statePressed = android.R.attr.state_pressed;
		int stateWindowFocused = android.R.attr.state_window_focused;
		
		//Resources resource = this.getResources();
		//Drawable xDrawable = resource.getDrawable(R.drawable.bottom_bar_highlight);
		
		drawables.addState(new int[]{ stateChecked, -stateWindowFocused}, offDrawable);
		drawables.addState(new int[]{-stateChecked, -stateWindowFocused}, offDrawable);
		drawables.addState(new int[]{ stateChecked,  statePressed      }, onDrawable);
		drawables.addState(new int[]{-stateChecked,  statePressed      }, onDrawable);
		drawables.addState(new int[]{ stateChecked,  stateFocused      }, onDrawable);
		drawables.addState(new int[]{-stateChecked,  stateFocused      }, offDrawable);
		drawables.addState(new int[]{ stateChecked                     }, onDrawable);
		drawables.addState(new int[]{-stateChecked                     }, offDrawable);
		drawables.addState(new int[]{                  				   }, onDrawable);
		this.setButtonDrawable(drawables);
	}
}

/**
  * 
 */
package com.ql.view;

import java.io.InputStream;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.graphics.drawable.Drawable;

public class RadioStateDrawable extends Drawable{

	private int	textSize = 14;
	private Bitmap bitmap;
	//private Bitmap highlightBitmap;
    private Shader shader;
    private Shader textShader;
	Context context;
	public static int width;
	public static int height;
	public static int screen_width;
	private boolean highlight;
	private String label;
	
	public static final int SHADE_GRAY = 0;
	public static final int SHADE_BLUE = 1;
	public static final int SHADE_MAGENTA = 2;
	public static final int SHADE_YELLOW = 3;
	public static final int SHADE_WHITE = 4;
	public static final int SHADE_RED = 5;
	public static final int SHADE_ORANGE = 6;
	
	public RadioStateDrawable(Context context, int imageID, String label, boolean highlight, int shade)
	{
		super();
		this.highlight = highlight;
		this.context = context;
		this.label = label;
		InputStream is = context.getResources().openRawResource(imageID);
		bitmap = BitmapFactory.decodeStream(is).extractAlpha();
		setShade(shade);
		
		//highlightBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.bottom_bar_highlight);
	}
	
	public RadioStateDrawable(Context context, int imageID, String label, boolean highlight, int startGradientColor, int endGradientColor)
	{
		super();
		this.highlight = highlight;
		this.context = context;
		this.label = label;
		InputStream is = context.getResources().openRawResource(imageID);
		bitmap = BitmapFactory.decodeStream(is).extractAlpha();
		int[] shades = new int[] { startGradientColor, endGradientColor};
		shader = new LinearGradient(0, 0, 0, bitmap.getHeight(), shades, null, Shader.TileMode.MIRROR);
	}
	
	public void setShade(int shade)
	{
		int[] shades = new int[2];
		switch (shade)
		{
			case SHADE_GRAY:
			{
				shades = new int[]{Color.LTGRAY, Color.DKGRAY };
				break;
			}
			case SHADE_BLUE:
			{
				shades = new int[]{Color.CYAN, Color.BLUE };
				break;
			}
			case SHADE_RED:	
			{
				shades = new int[]{Color.MAGENTA, Color.RED };
				break;
			}
			case SHADE_MAGENTA:
			{
				shades = new int[]{ Color.MAGENTA, Color.rgb(292, 52, 100) };
				break;
			}
			case SHADE_YELLOW:
			{
				shades = new int[]{Color.YELLOW, Color.rgb(255, 126, 0) };
				break;
			}
			case SHADE_ORANGE:
			{
				shades = new int[]{Color.rgb(255, 126, 0), Color.rgb(255,90,0) };
				break;
			}
			case SHADE_WHITE:
			{
				shades = new int[]{Color.WHITE, Color.LTGRAY };
				break;
			}
		}
		
		shader = new LinearGradient(0, 0, 0, bitmap.getHeight(), shades, null, Shader.TileMode.MIRROR);
		
		if (highlight) textShader = new LinearGradient(0, 0, 0, 10, new int[]{Color.WHITE, Color.LTGRAY}, null, Shader.TileMode.MIRROR);
		else textShader = new LinearGradient(0, 0, 0, 10, new int[]{Color.LTGRAY, Color.DKGRAY}, null, Shader.TileMode.MIRROR);
	}
	
	@Override
	public void draw(Canvas canvas) {
		
		int bwidth = bitmap.getWidth();
		int bheight = bitmap.getHeight();
		/*
		if (width==0)
		{
			if (screen_width==0) screen_width = 320;
			width=screen_width/5;
		}*/
		int x = (width-bwidth)/2;
		int top = 2+(32-bheight)/2;

//		if (highlight)
//			canvas.drawColor(Color.LTGRAY);
//		else
		canvas.drawColor(Color.TRANSPARENT);
		Paint p = new Paint();
		
//		p.setColor(Color.RED);
//      p.setStyle(Paint.Style.FILL);
		p.setTextSize(textSize);
//		p.setTypeface(Typeface.DEFAULT_BOLD);
//		p.setFakeBoldText(true);
		p.setTextAlign(Align.CENTER);
		p.setShader(textShader);
		p.setAntiAlias(true);
		
		FontMetrics fm = p.getFontMetrics();
		int y = top+bheight + (int)(height-top-bheight - fm.ascent)/2;
		canvas.drawText(label, width/2 ,y, p);
		
		p.setShader(shader);
//		Rect rect = new Rect();
//		rect.set(x, top, x+32, top+32);
//		Rect src = new Rect();
//		src.set(0, 0, bwidth, bheight);
		canvas.drawBitmap(bitmap, x, top, p);
	}

	@Override
	public int getOpacity() {
		return 0;
	}

	@Override
	public void setAlpha(int alpha) {}

	@Override
	public void setColorFilter(ColorFilter cf) {}

}

用法:
package com.ql.activity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends ScrollableTabActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.main);
        
        setDelegate(new SliderBarActivityDelegateImpl());
        Intent intent = new Intent(this, Test_1_Activity.class);
        this.addTab("首页", R.drawable.home, intent);
        intent = new Intent(this, Test_2_Activity.class);
        this.addTab("自选", R.drawable.mystock, intent);
        intent = new Intent(this, Test_3_Activity.class);
        this.addTab("排行", R.drawable.rank, intent);
        intent = new Intent(this, Test_4_Activity.class);
        this.addTab("主力", R.drawable.zhuli, intent);
        intent = new Intent(this, Test_6_Activity.class);
        this.addTab("Loading", R.drawable.zhuli, intent);
        
        commit();//别忘了执行
        setCurrentTab(0);
    }
    
    private class SliderBarActivityDelegateImpl extends SliderBarActivityDelegate
    {
    	/*
    	 * Optional callback method
    	 * called when users tap on the tab bar button
    	 */
    	protected void onTabChanged(int tabIndex) 
    	{
    		Log.d("onTabChanged",""+tabIndex);
    		if(tabIndex == 1)
    		{
    			//title.setText("啊啊啊啊");
    		}
    	}
    }
}

妙用TabHost
http://www.cnblogs.com/over140/archive/2011/03/02/1968042.html

Android入门第十五篇之ActivityGroup + GridView 实现Tab分页标签
http://blog.csdn.net/hellogv/archive/2010/12/06/6057174.aspx

你可能感兴趣的:(android,OS)