TabActivity

最近一个项目中用到了TabActivity,遇到了不少问题,而且发现论坛中也有类似的问题,所以在这里写个TabActivity的例子,望大家多多指教。

在这里给大家介绍两种TabActivity效果,一种是用TabActivity实现,另外一种是ViewFlipper实现。
话不多说,先给个效果图,不然有人说我无图无真相了。







附近中有的都是一些小技巧很好用,
比如,图片中的菜单,是利用RadioGroup做成的,而且有选中的效果,RadioGroup做成菜单,网络上面也有不少的例子,今天我也顺便说下原理。
Radiogroup中之能有一个是选中的效果,这个刚刚好,为菜单中选中提供了方便,但是系统提供的背景和图标是很好用,所以我们要自己自定义一个,这里就用到了style和shape,详细情况大家可以看代码。
选中的效果是一个图片背景的切换,这个定义在shape的xml文件里面。
  1. <RadioGroup
  2.             android:id="@+id/rg"
  3.             android:layout_width="fill_parent"
  4.             android:layout_height="50px"
  5.             android:background="#f00"
  6.             android:orientation="horizontal" >

  7.             <RadioButton
  8.                 android:id="@+id/rb01"
  9.                 style="@style/menu_item"
  10.                 android:checked="true"
  11.                 android:drawableTop="@drawable/menu_home"
  12.                 android:text="主页" />

  13.             <RadioButton
  14.                 android:id="@+id/rb02"
  15.                 style="@style/menu_item"
  16.                 android:drawableTop="@drawable/menu_clear"
  17.                 android:text="清除" />

  18.             <RadioButton
  19.                 android:id="@+id/rb03"
  20.                 style="@style/menu_item"
  21.                 android:drawableTop="@drawable/menu_refresh"
  22.                 android:text="刷新" />

  23.             <RadioButton
  24.                 android:id="@+id/rb04"
  25.                 style="@style/menu_item"
  26.                 android:drawableTop="@drawable/menu_save"
  27.                 android:text="保存" />

  28.             <RadioButton
  29.                 android:id="@+id/rb05"
  30.                 style="@style/menu_item"
  31.                 android:drawableTop="@drawable/menu_more"
  32.                 android:text="更多" />
  33.         </RadioGroup>
复制代码
  1. <style name="menu_item">
  2.         <item name="android:layout_width">fill_parent</item>
  3.         <item name="android:layout_height">fill_parent</item>
  4.         <item name="android:button">@null</item>
  5.         <item name="android:gravity">center_horizontal</item>
  6.         <item name="android:background">@drawable/menu_item_bg</item>
  7.         <item name="android:layout_weight">1</item>
  8.     </style>
复制代码
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  3.         <item android:state_pressed="false" android:state_checked="false" android:drawable="@drawable/menu_normal" />
  4.         <item android:state_checked="true" android:drawable="@drawable/menu_press" />
  5.         <item android:state_pressed="true" android:drawable="@drawable/menu_press" />
  6. </selector>
复制代码
系统在中自带TabActivity,TabHost是在顶部的,如果要改变位置的话,比如,放在底部,就可以改变xml中的位置,那么显示的位置当然也在底部了,本实例中我们不需要系统自带的Tabhost,我就把他隐藏了, android:visibility="gone" ,使用我们自己设置的菜单栏。
另外Tabhost切换的动画,也是大家关注的问题。
  1. public class TabMainActivity extends TabActivity {

  2.         TabHost tab;
  3.         Context context;
  4.         RadioGroup rg;

  5.         public void onCreate(Bundle savedInstanceState) {
  6.                 super.onCreate(savedInstanceState);
  7.                 setContentView(R.layout.tab_main);

  8.                 tab = getTabHost();
  9.                 context = this;

  10.                 tab.addTab(tab.newTabSpec("A").setIndicator("A").setContent(new Intent(context, AActivity.class)));
  11.                 tab.addTab(tab.newTabSpec("B").setIndicator("B").setContent(new Intent(context, BActivity.class)));
  12.                 tab.addTab(tab.newTabSpec("C").setIndicator("C").setContent(new Intent(context, CActivity.class)));
  13.                 tab.addTab(tab.newTabSpec("D").setIndicator("D").setContent(new Intent(context, DActivity.class)));
  14.                 tab.addTab(tab.newTabSpec("E").setIndicator("E").setContent(new Intent(context, EActivity.class)));

  15.                 rg = (RadioGroup) findViewById(R.id.rg);
  16.                 rg.setOnCheckedChangeListener(new OnCheckedChangeListener() {
  17.                         public void onCheckedChanged(RadioGroup group, int checkedId) {
  18.                                 int idx = -1;
  19.                                 if (checkedId == R.id.rb01) {
  20.                                         idx = 0;
  21.                                 } else if (checkedId == R.id.rb02) {
  22.                                         idx = 1;
  23.                                 } else if (checkedId == R.id.rb03) {
  24.                                         idx = 2;
  25.                                 } else if (checkedId == R.id.rb04) {
  26.                                         idx = 3;
  27.                                 } else if (checkedId == R.id.rb05) {
  28.                                         idx = 4;
  29.                                 }
  30.                                 switchActivity(idx);
  31.                         }
  32.                 });
  33.         }

  34.         protected void switchActivity(int idx) {
  35.                 int n = tab.getCurrentTab();

  36.                 if (idx < n) {
  37.                         tab.getCurrentView().startAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_left_out));
  38.                 } else if (idx > n) {
  39.                         tab.getCurrentView().startAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_right_out));
  40.                 }
  41.                 tab.setCurrentTab(idx);
  42.                 if (idx < n) {
  43.                         tab.getCurrentView().startAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_left_in));
  44.                 } else if (idx > n) {
  45.                         tab.getCurrentView().startAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_right_in));
  46.                 }
  47.                 
  48.                 RadioButton rb = (RadioButton) rg.getChildAt(idx);
  49.                 rb.setChecked(true);
  50.         }

  51.         private Map<String, Object> data = new HashMap<String, Object>();

  52.         protected void put(String key, String value) {
  53.                 data.put(key, value);
  54.         }

  55.         protected Object get(String key) {
  56.                 return data.get(key);
  57.         }
  58. }
复制代码
主要的核心代码在上面的代码中,原理是先使当前的界面播放退出的动画,然后切换界面,最后播放新的界面进入的动画,请注意播放动画的代码是

tab.getCurrentView().startAnimation();

而不是

tab.getCurrentTabView().startAnimation();

我在开始写代码的时候,就发了这样的错误,找了好几天才把这个bug给找到,真郁闷。




还有TabActivity是一个Main,其他Activity相当于一个Sub,通常在一个sub中切换到另外一个sub中就比较麻烦了

可以使用如下的代码实现功能
BActivity----->CActivity
  1. public class BActivity extends Activity{

  2.         Button btn;
  3.         TabMainActivity main;
  4.         protected void onCreate(Bundle savedInstanceState) {
  5.                 super.onCreate(savedInstanceState);
  6.                 setContentView(R.layout.b);
  7.                 btn = (Button) findViewById(R.id.button1);
  8.                 main = (TabMainActivity) getParent();
  9.                 btn.setOnClickListener(new OnClickListener() {
  10.                         public void onClick(View v) {
  11.                                 main.put("test", "abc123");
  12.                                 main.switchActivity(2);
  13.                         }
  14.                 });
  15.         }
  16. }
复制代码
在BActivity中使用getParent();得带的就是MainActivity,我们可以在main写一个切换的方法,然后在B中就可以调用了,如果两个Activity之间要传递数据,那么也可以使用上面的方法,切换前先把数据放在main中,切换后在从main中取得数据。

下面说一说,ViewFlipper是一个很不错的组建,用的情况也是比较多的
ViewFlipper的子View中可以有好几个,但是显示只显示一个,利用这个原理可以做好多事情,比如,做一个类似于Window资源管理器中的视图切换,一个是网格布局,一个是列表布局, 那么就可以利用ViewFlipper来切换,
同理可以可以实现类似于TabActivity的功能,我在附件的源码中有例子。



TabActivity也有缺点,比如,在sub中不能使用startActivityForResult这样的方法,就算可以使用,那么返回的响应也不再sub中而是在main中,
  1. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  2.                 super.onActivityResult(requestCode, resultCode, data);
  3.         }
复制代码
那么就可以使用ViewFlippler来实现一个此功能

还有一个重要地方,就是ViewFlipper可以很简单的实现两个View之间的动画切换。
  1. public class VfActivity extends Activity {

  2.         ViewFlipper vf;
  3.         RadioGroup rg;
  4.         Context context;

  5.         AView a;
  6.         BView b;
  7.         CView c;
  8.         DView d;
  9.         EView e;
  10.         protected void onCreate(Bundle savedInstanceState) {
  11.                 super.onCreate(savedInstanceState);
  12.                 setContentView(R.layout.vf);

  13.                 vf = (ViewFlipper) findViewById(R.id.vf);

  14.                 rg = (RadioGroup) findViewById(R.id.rg);
  15.                 context = this;
  16.                 a = new AView(this);
  17.                 b = new BView(this);
  18.                 c = new CView(this);
  19.                 d = new DView(this);
  20.                 e = new EView(this);
  21.                 
  22.                 vf.addView(a.makeNewView());
  23.                 vf.addView(b.makeNewView());
  24.                 vf.addView(c.makeNewView());
  25.                 vf.addView(d.makeNewView());
  26.                 vf.addView(e.makeNewView());
  27.                 
  28.                 rg.setOnCheckedChangeListener(new OnCheckedChangeListener() {

  29.                         public void onCheckedChanged(RadioGroup group, int checkedId) {
  30.                                 int idx = -1;
  31.                                 if (checkedId == R.id.rb01) {
  32.                                         idx = 0;
  33.                                 } else if (checkedId == R.id.rb02) {
  34.                                         idx = 1;
  35.                                 } else if (checkedId == R.id.rb03) {
  36.                                         idx = 2;
  37.                                 } else if (checkedId == R.id.rb04) {
  38.                                         idx = 3;
  39.                                 } else if (checkedId == R.id.rb05) {
  40.                                         idx = 4;
  41.                                 }
  42.                                 changeViewByHorizontalnAnim(vf, idx);
  43.                         }
  44.                 });
  45.         }

  46.         public void changeViewByHorizontalnAnim(ViewFlipper vf, int idx) {

  47.                 int currentIdx = vf.getDisplayedChild();
  48.                 if (idx == currentIdx) {
  49.                         return;
  50.                 }
  51.                 Animation leftIn = AnimationUtils.loadAnimation(context, R.anim.left_in);
  52.                 Animation leftOut = AnimationUtils.loadAnimation(context, R.anim.left_out);
  53.                 Animation rightIn = AnimationUtils.loadAnimation(context, R.anim.right_in);
  54.                 Animation rightOut = AnimationUtils.loadAnimation(context, R.anim.right_out);
  55.                 Animation in = null;
  56.                 Animation out = null;
  57.                 if (idx > currentIdx) {
  58.                         in = leftIn;
  59.                         out = leftOut;
  60.                 } else if (idx < currentIdx) {
  61.                         in = rightIn;
  62.                         out = rightOut;
  63.                 } else {
  64.                         return;
  65.                 }
  66.                 vf.setInAnimation(in);
  67.                 vf.setOutAnimation(out);
  68.                 vf.setDisplayedChild(idx);
  69.         }
  70. }
复制代码
QQ截图20111108204413.png 

项目的结构如上图,Vf(ViewFlipper的简写,输入法来回切换太麻烦,希望大家能看懂,见谅啊,:-))
,vf在实现tab的时候,我先顶一个抽象类,
  1. public abstract class AbstractView {

  2.         protected Context context;
  3.         protected VfActivity activity;

  4.         public AbstractView(VfActivity va) {
  5.                 context = va;
  6.                 activity = va;
  7.         }

  8.         public abstract View makeNewView();
  9. }
复制代码
构造方法,把vf所在的activity穿进去,然后有个makenewview的方法,子类实现此方法,就可以得到一个界面
然后使用vf.addView(xxx.makeNewView());就行了,这里就不介绍vf的使用方法了,网上这方面的例子也很多。



终于写完了,如果有什么不同意见,可以留言,大家一起探讨探讨。写了好几个小时,累死了。

打完收工。。。。。。。

转自:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=114362

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值