看图:
/**
*/
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