大家都知道导航栏的实现可采用tab与tab host方式,或采用GridView与ActivityGroup方式。如果某应用的顶部或底部导航栏除了本身的导航块以外还有其他功能按键,他们与导航按键不是互斥关系,却影响着子activity的展示,那么我们该选择什么方式实现呢。
我采用的是比较灵活的GridView+ImageButton+ActivityGroup组合,GridView切换不同的subActivity, ImageButton切换subActivity的展示样式。
下面是一个最简单的样式xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:background="@drawable/switch_style"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/imgButton"
></ImageButton>
<GridView
android:id="@+id/gridView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/imgButton"
android:layout_toLeftOf="@id/imgButton"
></GridView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/container"
android:layout_below="@+id/imgButton"
android:background="@color/black"
></LinearLayout>
</RelativeLayout>
</LinearLayout>
该视图包括一个LinearLayout容器装载子activity, gridview用于导航控件,imageButton做样式切换等操作。由于gridview是可变的,所以这里先固定imageButton让GridView可以动态排版。
然后是实现代码:
public class RockVideoPlayerActivityGroup extends ActivityGroup {
//顶部导航栏
private GridView gridView;
//导航栏适配器
private ImageAdapter imgAdapter;
//视图容器,加载子activity
public LinearLayout container;
//控制按钮
private ImageButton imgBtn;
//子页面样式的控制开关
public boolean switchStyle = false;
//横竖屏flag
public boolean direct = false;
private int selectId = 0;
//gridView的图片包括横竖屏,为简单化只列了两项
int[] img_array = {R.drawable.pic1_nor,R.drawable.pic2_nor};
int[] img_array_port = {R.drawable.pic1_nor_port,R.drawable.pic2_nor_port};
int[] img_sel_array = {R.drawable.pic1_sel,R.drawable.pic2_sel};
int[] img_sel_array_port = {R.drawable.pic1_sel_port,R.drawable.pic2_sel_port};
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//无标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
//设置主显示视图
setContentView(R.layout.main);
imgBtn = (ImageButton) this.findViewById(R.id.imgButton);
imgBtn.setOnClickListener(new ImageButton.OnClickListener(){
boolean flag = false;//用于切换imagebutton显示
@Override
public void onClick(View v) {
if(!flag){
imgBtn.setBackgroundResource(R.drawable.switch_style1);
switchStyle = true;
}else{
imgBtn.setBackgroundResource(R.drawable.switch_style2);
switchStyle = false;
}
SwitchActivity(selectId);
flag = !flag;
}
} );
gridView = (GridView) this.findViewById(R.id.gridView);
//设置每行列数
gridView.setNumColumns(img_array.length);
//设置选中时为透明色,重要,不设置的话gridview会有选中色,而我们需要的只是图片聚焦
gridView.setSelector(new ColorDrawable(Color.TRANSPARENT));
//初始化adapter,区分横竖屏
//因为切换屏幕时需要重新初始化,所以manifeste中不能加android:configChanges="orientation|keyboardHidden"
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
direct = false;
imgAdapter = new ImageAdapter(this, img_array,img_sel_array);
}else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
direct = true;
imgAdapter = new ImageAdapter(this, img_array_port,img_sel_array_port);
}
//设置菜单Adapter
gridView.setAdapter(imgAdapter);
//九宫格点击事件
gridView.setOnItemClickListener(mOnItemClickListener);
container = (LinearLayout) findViewById(R.id.container);
SwitchActivity(selectId);
}
private OnItemClickListener mOnItemClickListener = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
if(selectId == arg2)//点选聚焦状态按钮无效返回
return;
selectId = arg2;
SwitchActivity(selectId);
}
};
/**
* 根据ID打开指定的Activity
* @param id GridView选中项的序号
*/
void SwitchActivity(int id)
{
//默认聚焦在第一项;选中项获得高亮
imgAdapter.SetFocus(selectId);
//必须先清除容器中所有的View
container.removeAllViews();
Intent intent =null;
if (id == 0) {
intent = new Intent(MyActivityGroup.this, MySubActivity.class);
if(!switchStyle){
intent.setAction("act1");//样式1
}else{
intent.setAction("act2");//样式2
}
} else if (id == 1) {
intent = new Intent(MyActivityGroup.this, MySubActivity.class);
if(!switchStyle){
intent.setAction("act3");//样式3
}else{
intent.setAction("act4");//样式4
}
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//Activity 转为 View
Window subActivity = getLocalActivityManager().startActivity(
"subActivity", intent);
//容器添加View
container.addView(subActivity.getDecorView(),
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}
}
这里有点偷懒,只加载了同一个子activity以切换不同样式,如果加载不同子activity需要使用handler机制,以免阻塞,具体就不写了。
最后子activity根据activityGroup传过来的值进行动态加载。按照这种思路,我们可以实现更灵活更复杂的页面,不知到3.0的新特性是否更方便简单,还没用过。