Android开发技术之开篇──TabActivity中子Activity的跳转问题

       在iphone开发中貌似有个UITabBarController,UITabBarController在底部,也有对应的切换效果,都封装好了。但是在android的中,这个东西它在顶部。

        当标签控制的Activity跳转到下一级Activity时,标签栏也会被覆盖,这样用户不能从下一级页面判断是从哪一个标签控制的Activity切换过来的,而在iphone中UITabBarController控制器很好地处理了这个问题,当用户push到下一级页面时,标签始终存在,并且标签选中状态不会改变,只有切换标签时才会改变标签的选中状态。由于受iphone的毒害,我做android项目时,也想实现这样的效果,经过网上查阅资料,在众多网友高手的启示下,终于实现我想要的效果,好了,废话少说,下面将我的实现方式如详细介绍,供有同样需求的网友参考!

       一、实现原理及效果图

       利用ActivityGroup + GridView + ViewFlipper 实现选项卡

首页,当点击下一页按钮时,跳转到下一级页面


    下一级页面如下所示:从图中看以清楚地看到,这一页面是从第一个标签选项卡控制的Activity跳转过来的


        

     二,实现步骤

     1)首先创建基于ActivityGroup的一个基类,在该类中,实现了切换Activity的功能,代码如下:

public class BaseGroupActivity extends ActivityGroup {


//显示日志tag

private static final String TAG = "MyTag";

//Tab栈管理

protected TabStack stack = new TabStack();

protected ViewFlipper  containerFlipper;

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

}


@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

// TODO Auto-generated method stub

if(keyCode == KeyEvent.KEYCODE_BACK){

if(!stack.isEmpty()){

back();

}else{

finish();

}

return true;

}

return super.onKeyDown(keyCode, event);

}

public void switchActivity(String id,Intent intent,int inAnimation,int outAnimation) {

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

Window window = getLocalActivityManager().startActivity(id, intent);

View v = window.getDecorView();

DisplayMetrics dm = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(dm);

LayoutParams param = new LayoutParams(LayoutParams.FILL_PARENT,

LayoutParams.FILL_PARENT);

v.setLayoutParams(param);

try {

containerFlipper.setInAnimation(AnimationUtils.loadAnimation(this,inAnimation));

containerFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,outAnimation));

} catch (NotFoundException e) {

e.printStackTrace();

}

containerFlipper.addView(v);

containerFlipper.showNext();

if(inAnimation == R.anim.push_right_in){

containerFlipper.removeViewAt(stack.size());

}

stack.push(id);

System.out.println("pust:" + id);

Log.i(TAG, "pust = " + id);

}


public void back(){

if(stack.size() > 1){

containerFlipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_in));

containerFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,R.anim.push_right_out));

containerFlipper.showPrevious();

containerFlipper.removeViewAt(stack.size() - 1);

stack.pop();

}else 

this.finish();

}

public void popSome(String id){

int sum = stack.getTheSumToPop(id);

containerFlipper.removeViews(stack.size() - sum, sum - 1);

stack.popSome(id);

containerFlipper.setDisplayedChild(containerFlipper.getChildCount() - 1);

}

}


       2)然后,创建一个基于TabActivity,核心代码如下:

public class MainActivity extends TabActivity {


private TabHost  mHost;

private GridView gvTopBar;

private TabBarItemAdapter tabBarImgAdapter;

/** 标签item图片信息 **/

int[] imgIds = { R.drawable.icon_home,R.drawable.icon_search

R.drawable.icon_shopcart,R.drawable.icon_myebuy, R.drawable.icon_info};

/** 标签item标题文字信息 **/

int[] strIds = {R.string.tab_home,R.string.tab_search,

R.string.tab_shopcart,R.string.tab_myebuy,R.string.tab_info};

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.ebuy_main);

fillViews();

setupIntent();

}


//填充标签栏item

private void fillViews(){

gvTopBar = (GridView) this.findViewById(R.tab.gridview);

gvTopBar.setNumColumns(imgIds.length);// 设置每行列数

gvTopBar.setSelector(new ColorDrawable(Color.TRANSPARENT));// 选中的时候为透明色

gvTopBar.setGravity(Gravity.CENTER);// 位置居中

gvTopBar.setVerticalSpacing(0);// 垂直间隔

int width = this.getWindowManager().getDefaultDisplay().getWidth()

/ imgIds.length;

tabBarImgAdapter = new TabBarItemAdapter(this, imgIds, width, 30, R.drawable.tab_sel_top, strIds);

gvTopBar.setAdapter(tabBarImgAdapter);

gvTopBar.setOnItemClickListener(new ItemClickEvent());// 项目点击事件

}

//设置对应标签的Activity

private void setupIntent() {

        this.mHost = getTabHost();

        TabHost localTabHost = this.mHost;

        localTabHost.addTab(buildTabSpec(TabIds.TAB_HOME, R.string.tab_home,

        new Intent(this,HomeTabGroup.class)));

        localTabHost.addTab(buildTabSpec(TabIds.TAB_SEARCH, R.string.tab_search,

        new Intent(this,SearchTabGroup.class)));

        localTabHost.addTab(buildTabSpec(TabIds.TAB_SHOPCART, R.string.tab_shopcart,

        new Intent(this,ShopcartTabGroup.class)));

        localTabHost.addTab(buildTabSpec(TabIds.TAB_MYEBUY, R.string.tab_myebuy,

        new Intent(this,MyEbuyTabGroup.class)));

        localTabHost.addTab(buildTabSpec(TabIds.TAB_INFO, R.string.tab_info,

        new Intent(this,InfoTabGroup.class)));

    }

private TabHost.TabSpec buildTabSpec(String tag, int resLabel, 

            final Intent content) {

        return this.mHost

                .newTabSpec(tag)

                .setIndicator(getString(resLabel))

                .setContent(content);

}

 

//标签item设置监听器,响应标签item点击事件

class ItemClickEvent implements OnItemClickListener {

public void onItemClick(AdapterView arg0, View arg1, int arg2,

long arg3) {

SwitchActivity(arg2);

}

}

//根据tag值,切换标签

void SwitchActivity(int id) {

tabBarImgAdapter.SetFocus(id);

switch (id) {

case 0:

this.mHost.setCurrentTabByTag(TabIds.TAB_HOME);

break;

case 1:

this.mHost.setCurrentTabByTag(TabIds.TAB_SEARCH);

break;

case 2:

this.mHost.setCurrentTabByTag(TabIds.TAB_SHOPCART);

case 3:

this.mHost.setCurrentTabByTag(TabIds.TAB_MYEBUY);

break;

case 4:

this.mHost.setCurrentTabByTag(TabIds.TAB_INFO);

break;

default:

break;

}

    }

       }


     3)在第二步时,setupIntent()方法,设置标签控制的Activity,这里我举一例子代码予以说明,其它类似。该Activity继承在第一步我们创建的基类,代码如下:

public class HomeTabGroup extends BaseGroupActivity {


@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.tab_content);

fillViews();

}


private void fillViews(){

containerFlipper = (ViewFlipper) findViewById(R.tab.content);

Intent intent = new Intent(this,HomeActivity.class);

switchActivity(EbuyConstant.TabIds.TAB_HOME_view,intent,-1,-1);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

return this.getLocalActivityManager().getCurrentActivity().onTouchEvent(event);

}

}


   该类实现,将标签显示,并利用 switchActivity(EbuyConstant.TabIds.TAB_HOME_view,intent,-1,-1)把该标签控制的Activity切换成要显示的HomeActivity,而HomeActivity是我创建的基于第一步创建的Activity的类文件。
    4)在HomeActivity中,有一个“下一步”的按钮控件,就是第一个图上面展示的效果,当点击它时,进入第二个图,这里只把它的调用方法,予以介绍,代码如下:
    

        HomeTabGroup parent = (HomeTabGroup)getParent();

Intent intent = new Intent(this, ProductListActivity.class);

intent.putExtra(IntentFlags.FLAG_PRODUCTLIST, ProductListActivity.FLAG_INTENT_PRODUCTLIST);

parent.switchActivity(TabIds.TAB_HOME, intent, R.anim.push_left_in, R.anim.push_left_out);


    通过上面的步骤,实现了我iphone样式的标签功能。到此,java代码实现部分已经完成,下面把代码中用到的配置文件也一一介绍,包括动画、页面布局,网友只需要把图片资源和文字信息作相应更改即可。


   三、xml配置文件

   1)tab.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"

    android:background="@color/bg"

    >

    <FrameLayout 

       android:id="@android:id/tabcontent" 

       android:layout_width="fill_parent" 

       android:layout_height="0.0dip" 

       android:layout_weight="1.0" />

    <TabWidget 

      android:id="@android:id/tabs" 

      android:visibility="gone" 

      android:layout_width="fill_parent" 

      android:layout_height="wrap_content" 

      android:layout_weight="0.0" />

    <LinearLayout android:layout_width="fill_parent"

    android:layout_height="49dip"

    android:gravity="center_vertical" 

    android:layout_gravity="bottom"

    android:background="@drawable/tab_bg">

    <GridView 

android:layout_width="fill_parent"

android:layout_height="wrap_content" 

android:id="@+tab/gridview"

android:fadingEdgeLength="5dip" 

android:fadingEdge="vertical"/>

    LinearLayout>

    

LinearLayout>

     2)tab_content.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"

    android:background="@color/bg"

    >

    <ViewFlipper

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:id="@+tab/content"

    >

    ViewFlipper>

LinearLayout>


    3)ebuy_main.xml文件

xml version="1.0" encoding="utf-8"?>

<TabHost xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+android:id/tabhost" 

android:layout_width="fill_parent" 

android:layout_height="fill_parent"

  >

  <include layout="@layout/tab" android:id="@+login/tab"/>

TabHost>

     

     3)home.xml文件

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:orientation="vertical">

  <LinearLayout

   android:layout_width="fill_parent"

   android:layout_height="40dip"

   android:background="@drawable/top_bg"

   android:gravity="center"

   >

   <TextView

   android:layout_width="wrap_content"

   android:layout_height="wrap_content"

   android:text="@string/tab_home"

   style="@style/TopBarText"

   />

    LinearLayout>

  

  <LinearLayout

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    >

    <Button android:id="@+id/next_button"

           android:layout_width="fill_parent"

           android:layout_height="wrap_content"

           android:text="下一页">

        Button>

   LinearLayout>

  

LinearLayout>

   

      4)动画文件,这里只以两个动画为例,其它类似

    push_left_in.xml文件如下:

    

xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">

<translate android:fromXDelta="100%p" android:toXDelta="0"

android:duration="500" />

<alpha android:fromAlpha="1.0" android:toAlpha="1.0"

android:duration="500" />

set>


    push_left_out.xml文件如下:

xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">

<translate android:fromXDelta="0" android:toXDelta="-100%p"

android:duration="500" />

<alpha android:fromAlpha="1.0" android:toAlpha="1.0"

android:duration="500" />

set>


   初次写android博客,有不到之处请高手指出。

你可能感兴趣的:(Android开发技术系列专栏)