看了N多应用的底部菜单显示,特别是一工具类的应用所有的底部都有图片和文字并存。所以我自己想要做一个,百度谷歌几乎没有完整的。所以我做了一个使用的ActivityGroup作为分页展示窗体的底部菜单显示的测试,希望对还在查找该如何做的同学有所帮助。里面很多都是百度与谷歌的,我只是做了些改进。希望有些同学不要对号入座。
布局:
主窗体:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ff8866"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:id="@+id/Container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:layout_below="@+id/gvTopBar" >
</LinearLayout>
<GridView
android:id="@+id/gvTopBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
</GridView>
</RelativeLayout>
</LinearLayout>
子窗体:
<?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" android:background="#000000">
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="one"
></TextView>
</LinearLayout>
其他3个子窗体,以此类推。
清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ActivityGroupDemo"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".ActivityGroupDemo"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ActivityA" >
</activity>
<activity android:name=".ActivityB" >
</activity>
<activity android:name=".ActivityC" >
</activity>
<activity android:name=".ActivityD" >
</activity>
</application>
</manifest>
代码:
package com.ActivityGroupDemo;
import android.app.ActivityGroup;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.AdapterView.OnItemClickListener;
public class ActivityGroupDemo extends ActivityGroup {
private GridView gvBottomBar;//底部菜单栏
private MenuTitleAdapter btmMenuTitleAdapter;
public LinearLayout container;// 装载sub Activity的容器
/** 底部按钮图片 **/
int[] topbar_image_array = { R.drawable.ic_of_bossactivity_mysyncdisk,
R.drawable.ic_of_bossactivity_mydisk, R.drawable.ic_of_bossactivity_share,
R.drawable.ic_of_bossactivity_setting };
/** 底部菜单文字 **/
String[] titles = { "首页", "分类", "口袋", "更多" };
/*
* 作用:窗体加载初始化...
* 步骤:看注释
* 创建时间:2012-8-2 下午6:03:11
* 修改时间:2012-8-2 下午6:03:11
* @param savedInstanceState
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//对底部菜单栏进行布局设计
gvBottomBar = (GridView) this.findViewById(R.id.gvTopBar);
gvBottomBar.setNumColumns(topbar_image_array.length);// 设置每行列数
gvBottomBar.setSelector(new ColorDrawable(Color.TRANSPARENT));// 选中的时候为透明色
gvBottomBar.setGravity(Gravity.CENTER);// 位置居中
gvBottomBar.setVerticalSpacing(0);// 垂直间隔
// 设置从设备屏幕的宽除与总图片数
int width = this.getWindowManager().getDefaultDisplay().getWidth()/ titles.length;
//设置图片与文字适配器数据
btmMenuTitleAdapter=new MenuTitleAdapter(this, titles, topbar_image_array,12,width, R.drawable.btn_of_shake_press);
// 设置菜单Adapter
gvBottomBar.setAdapter(btmMenuTitleAdapter);
gvBottomBar.setOnItemClickListener(new ItemClickEvent());// 项目点击事件
//初始化设置显示的窗体
container = (LinearLayout) findViewById(R.id.Container);
SwitchActivity(0);// 默认打开第0个窗体
}
/**
* 作用:返回数组内的在包资源的图片
* 步骤:看注释
* 创建时间:2012-8-2 下午11:31:33
* 修改时间:2012-8-2 下午11:31:33
* @param context
* @param picIds
* @return 图片
*/
/**
* 作用:返回数组内的在包资源的图片
* 步骤:看注释
* 创建时间:2012-8-3 上午7:53:41
* 修改时间:2012-8-3 上午7:53:41
* @param context
* @param i 选择的第i个图片
* @param picIds
* @return 图片
*/
public Drawable getDrawable(Context context,int i,int[] picIds) {
//遍历资源文件里面的图片
Drawable draw =context.getResources().getDrawable(picIds[i]);
return draw;
}
/**
* 作用:底部菜单选项的内部处理类
* 创建时间:2012-8-2 下午6:00:51
* 修改时间:2012-8-2 下午6:00:51
* @author Hzl520
*/
class ItemClickEvent implements OnItemClickListener {
/*
* 作用:底部菜单选择处理事件
* 步骤:看注释
* 创建时间:2012-8-2 下午6:00:57
* 修改时间:2012-8-2 下午6:00:57
* @param arg0
* @param arg1
* @param arg2
* @param arg3
*/
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
SwitchActivity(arg2);
}
}
/**
* 作用:根据ID打开指定的Activity
* 步骤:看注释
* 创建时间:2012-8-2 下午6:02:34
* 修改时间:2012-8-2 下午6:02:34
* @param id GridView选中项的序号
*/
void SwitchActivity(int id) {
btmMenuTitleAdapter.SetFocus(id);// 选中项获得高亮
container.removeAllViews();// 必须先清除容器中所有的View
Intent intent = null;
if (id == 0) {
intent = new Intent(ActivityGroupDemo.this, ActivityA.class);
} else if (id == 1) {
intent = new Intent(ActivityGroupDemo.this, ActivityB.class);
} else if (id == 2) {
intent = new Intent(ActivityGroupDemo.this, ActivityC.class);
} else if (id == 3) {
intent = new Intent(ActivityGroupDemo.this, ActivityD.class);
}
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// Activity 转为 View
Window subActivity = getLocalActivityManager().startActivity("subActivity", intent);
// 容器添加View
container.addView(subActivity.getDecorView(), LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);
}
}
处理图片和文字的:
/**
*
*/
package com.ActivityGroupDemo;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.TextView;
/**
* 作用:
* 创建时间:2012-8-2 下午5:47:00
* 修改时间:2012-8-2 下午5:47:00
* @author Hzl520
*/
public class MenuTitleAdapter extends BaseAdapter {
private Context mContext;
private TextView[] title;
private int selResId;
/**
* 作用:菜单与图片的适配器
* @param context
* @param titles
* @param fontSize
*/
public MenuTitleAdapter(Context context, String[] titles,int[] picIds ,int fontSize,int width,int selResId ) {
this.mContext = context;
this.title = new TextView[titles.length];
this.selResId=selResId;
for (int i = 0; i < titles.length; i++) {
title[i] = new TextView(mContext);
Drawable drawable=new ActivityGroupDemo().getDrawable(mContext,i,picIds);
title[i].setCompoundDrawablesWithIntrinsicBounds(null, zoomDrawable(drawable,32,32),null, null);
title[i].setText(titles[i]);
title[i].setLayoutParams(new GridView.LayoutParams(width, 48));//设置TextView宽高
title[i].setTextSize(fontSize);
title[i].setTextColor(Color.WHITE);
title[i].setGravity(Gravity.CENTER);
}
}
/**
* 作用:把图片缩放后转换为Drawable
* 步骤:看注释
* 创建时间:2012-8-3 上午7:11:58
* 修改时间:2012-8-3 上午7:11:58
* @param drawable
* @param w
* @param h
* @return 图片
*/
static Drawable zoomDrawable(Drawable drawable, int w, int h){
int width = drawable.getIntrinsicWidth();
int height= drawable.getIntrinsicHeight();
Bitmap oldbmp = drawableToBitmap(drawable); // drawable转换成bitmap
Matrix matrix = new Matrix(); // 创建操作图片用的Matrix对象
float scaleWidth = ((float)w / width); // 计算缩放比例
float scaleHeight = ((float)h / height);
matrix.postScale(scaleWidth, scaleHeight); // 设置缩放比例
Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, matrix, true); // 建立新的bitmap,其内容是对原bitmap的缩放后的图
return new BitmapDrawable(newbmp); // 把bitmap转换成drawable并返回
}
/**
* 作用:drawable 转换成bitmap
* 步骤:看注释
* 创建时间:2012-8-3 上午7:07:31
* 修改时间:2012-8-3 上午7:07:31
* @param drawable
* @return
*/
static Bitmap drawableToBitmap(Drawable drawable) {
// 取drawable的长宽
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
// 取drawable的颜色格式
Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888:Bitmap.Config.RGB_565;
Bitmap bitmap = Bitmap.createBitmap(width, height, config); // 建立对应bitmap
Canvas canvas = new Canvas(bitmap); // 建立对应bitmap的画布
drawable.setBounds(0, 0, width, height);
drawable.draw(canvas); // 把drawable内容画到画布中
return bitmap;
}
/*
* 作用:获取项目总数
* 步骤:看注释
* 创建时间:2012-8-2 下午5:47:00
* 修改时间:2012-8-2 下午5:47:00
* @return
*/
@Override
public int getCount() {
return title.length;
}
/*
* 作用:获取项目位置
* 步骤:看注释
* 创建时间:2012-8-2 下午5:47:00
* 修改时间:2012-8-2 下午5:47:00
* @param arg0
* @return
*/
@Override
public Object getItem(int position) {
return position;
}
/*
* 作用:获取项目ID的位置
* 步骤:看注释
* 创建时间:2012-8-2 下午5:47:00
* 修改时间:2012-8-2 下午5:47:00
* @param position
* @return
*/
@Override
public long getItemId(int position) {
return position;
}
/**
* 作用:设置选择的图片背景
* 步骤:看注释
* 创建时间:2012-8-2 下午8:44:06
* 修改时间:2012-8-2 下午8:44:06
* @param index
*/
public void SetFocus(int index)
{
for(int i=0;i<title.length;i++)
{
if(i!=index)
{
title[i].setBackgroundResource(R.drawable.btn_of_shake_normal);//恢复未选中的样式
}
}
title[index].setBackgroundResource(selResId);//设置选中的样式
}
/*
* 作用:获取文本显示的位置
* 步骤:看注释
* 创建时间:2012-8-2 下午5:47:00
* 修改时间:2012-8-2 下午5:47:00
* @param position
* @param convertView
* @param parent
* @return
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v;
if (convertView == null) {
v = title[position];
} else {
v = convertView;
}
return v;
}
}
效果图:
好了,就这些了。