日志标签:TabHost

TabHost中在不同Tab中显示不同的Menu(菜单)

时间:2011年07月11日作者:么吉查看次数:301 views评论次数:0

  使用TabHost后,我们很多时候都有在不同的Tab中显示不同的菜单.
以下的是我足球即时比分中的一些截图(Tab为关注时显示的菜单).

以下是实现以上功能的主要代码片段(该代码是本人的应用足球即时比分的代码片段):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
public class SenseSoccerScoreActivity extends Activity{
	public static final int MENU_SETUP_ID = 1;
	public static final int MENU_ABOUT_ID = 2;
	public static final int MENU_LEAVE_ID = 3;
	public static final int MENU_CHECK_UPDATE_ID = 5;
	public static final int MENU_EMPTY_FOCUS_ID = 4;
	public static final int MENU_HISTORY_MATCH = 6;
	public static final int MENU_RETURN = 7;
	public static final int MENU_FILTER_SETTING = 8;
	public static final int MENU_FUTURE_MATCH = 9;
	public static final int MENU_BACK_ID = 10;
	public static final int MENU_REFRESH_ID = 11;
	public static final int MENU_CLEAN_CACHE = 12;
 
        // ... 其它代码.
	/**
	 * 当点击menu按钮时,添加菜单
	 * 之前一般是覆盖 onCreateOptionsMenu 方法的,现在要覆盖 onPrepareOptionsMenu
	 */
    public boolean onPrepareOptionsMenu(Menu menu) {
		// *** 这里是实现的主要代码,先要清空菜单,然后再重新添加菜单
    	menu.clear(); // 清空menu
    	super.onPrepareOptionsMenu(menu);
 
		TabHost th = (TabHost) findViewById(R.id.tabhost);
 
		// 如果是关注赛事列表,需要添加清空菜单
		if(th.getCurrentTab() == 3){
			menu.add(0, MENU_SETUP_ID, 1, R.string.settingMenu)
                                .setIcon(android.R.drawable.ic_menu_preferences);
			menu.add(0, MENU_EMPTY_FOCUS_ID, 2, R.string.clearFocusMenu)
                                .setIcon(android.R.drawable.ic_menu_delete);
			menu.add(0, MENU_CHECK_UPDATE_ID, 3, R.string.text_check_update)
                                .setIcon(android.R.drawable.ic_menu_search);
			menu.add(0, MENU_ABOUT_ID, 4, R.string.aboutMenu)
                                .setIcon(android.R.drawable.ic_menu_help);
			menu.add(0, MENU_HISTORY_MATCH, 5, R.string.fullTimeMatch)
                                .setIcon(android.R.drawable.ic_menu_recent_history);
			menu.add(0, MENU_LEAVE_ID, 6, R.string.leaveMenu)
                                .setIcon(android.R.drawable.ic_menu_close_clear_cancel);
			return true;
		} else {
			menu.add(0, MENU_SETUP_ID, 1, R.string.settingMenu)
                               .setIcon(android.R.drawable.ic_menu_preferences);
			menu.add(0, MENU_CHECK_UPDATE_ID, 3, R.string.text_check_update)
                               .setIcon(android.R.drawable.ic_menu_search);
			menu.add(0, MENU_ABOUT_ID, 4, R.string.aboutMenu)
                               .setIcon(android.R.drawable.ic_menu_help);
			menu.add(0, MENU_HISTORY_MATCH, 5, R.string.fullTimeMatch)
                               .setIcon(android.R.drawable.ic_menu_recent_history);
			menu.add(0, MENU_LEAVE_ID, 7, R.string.leaveMenu)
                               .setIcon(android.R.drawable.ic_menu_close_clear_cancel);
			return true;
		}
    }
 
	/**
	 * 当点击相应的菜单后,执行响应的事件
	 */
	public boolean onOptionsItemSelected(MenuItem item){
		Intent intent = null;
        switch (item.getItemId()){
        	// 设置
        case MENU_SETUP_ID:
        	intent = new Intent();  
        	intent.setClass(this, SettingActivity.class);
            this.startActivity(intent);  
            break;
 
            // 清空关注赛事列表
        case MENU_EMPTY_FOCUS_ID:
        	MatchManager.getInstance(this).clearFocus();
        	updateFocusMatchUI();
            break;
 
            // 检查更新
        case MENU_CHECK_UPDATE_ID:
            ProgressDialog checkUpdateDialog = buildCheckUpdateView();
            checkUpdateDialog.show();
            break;
 
            // 关于
        case MENU_ABOUT_ID:
            AlertDialog dialog = buildAboutView();
            dialog.show();
            break;
 
        // ... 实现其它的,代码就省略了...      		
 
        return super.onOptionsItemSelected(item);
	}
}

  实现以上效果的思路是:覆盖 onPrepareOptionsMenu 而不是 onCreateOptionsMenu 方法的. 因为onCreateOptionsMenu的方法只会执行一次,就是第一次点击menu键时才会执行.而onPrepareOptionsMenu每一次点击menu键都会执行.这样,我们就可以先清空menu的内容,再重新添加menu.这就是实现在不同Tab中显示不同菜单(Menu)的原理.

1
2
3
4
5
6
7
8
   public boolean onPrepareOptionsMenu(Menu menu) {
        // *** 这里是实现的主要代码,先要清空菜单,然后再重新添加菜单
    	menu.clear(); // 清空menu
    	super.onPrepareOptionsMenu(menu);
 
        // 添加所需要的菜单...
        menu.add(....);
  }

相关博文:
[ Android中TabHost切换不同的Activity ]
[ Android中TabHost的使用 ]

返回 : Android开发博文汇总

Android中TabHost切换不同的Activity

时间:2011年06月10日作者:ronald查看次数:1,834 views评论次数:0

TabHost在很多应用都会使用到,有时候在TabHost添加的Tab中设置view不能满足需求,因为在view中添加如PreferenceActivity相当困难.

之前在一个应用中需要实现使用TabHost中在多个Tab切换不同的Activity.一个是日志列表(ListActivity),一个是应用设置页面( PreferenceActivity )

先上效果图

上图是日志列表页面,是ListActivity


上图是设置页面,是一般的PreferenceActivity

开发流程 :
1, 编写不同的Activity,用于在TabHost中点击不同的Tab时进行切换(以下是两个例子,因为不是该博文的主要内容所以省略)
1-1, 编写LogActivity,该类是ListActivity,用于显示日志内容
1-2, 编写SettingActivity,该类是PreferenceActivity,应用的设置页面,编写方式与PreferenceActivity一样.

2, 编写主页面(MainActivity),该类是应用的入口类,在该类定义TabHost并添加相应的Activity.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 该类需要继承ActivityGroup
public class MainActivity extends ActivityGroup {
  private TabHost mTabHost;
 
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.main);
    // 设置TabHost
    initTabs();
  }
 
  private void initTabs() {
    mTabHost = (TabHost) findViewById(R.id.tabhost);
    mTabHost.setup(this.getLocalActivityManager());
    // 添加日志列表的tab,注意下面的setContent中的代码.是这个需求实现的关键
    mTabHost.addTab(mTabHost.newTabSpec("tab_log")
      .setIndicator("日志",getResources().getDrawable(R.drawable.ic_tab_log))
      .setContent(new Intent(this, LogActivity.class)));
 
    // 添加应用设置的tab,注意下面的setContent中的代码.是这个需求实现的关键
    mTabHost.addTab(mTabHost.newTabSpec("tab_setting")
      .setIndicator("设置",getResources().getDrawable(R.drawable.ic_tab_settings))
      .setContent(new Intent(this, SettingActivity.class)));
    mTabHost.setCurrentTab(1);
  }
}

3, 编写main.xml,MainActivity的layout的xml配置文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	>
	<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
		android:orientation="vertical" android:layout_width="fill_parent"
		xmlns:app="http://schemas.android.com/apk/res/rbase.app.nowscore"
		android:layout_height="fill_parent" 
                android:layout_above="@+id/adLayout">
		<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
			android:id="@+id/tabhost" android:layout_width="fill_parent"
			android:layout_height="wrap_content">
			<LinearLayout android:orientation="vertical"
				android:layout_width="fill_parent" 
                                android:layout_height="wrap_content">
				<TabWidget android:id="@android:id/tabs"
					android:layout_width="fill_parent" 
                                        android:layout_height="wrap_content" />
				<FrameLayout android:id="@android:id/tabcontent"
					android:layout_width="fill_parent" 
                                        android:layout_height="fill_parent" />
			</LinearLayout>
		</TabHost>
	</LinearLayout>
</RelativeLayout>

补充:
当在不同的Tab中按下menu按钮,会以当前的Activity为准,即在SettingActivity时按下menu按钮后会触发SettingActivity的事件,不是主页面的事件.

返回 : Android开发博文汇总

Android中TabHost的使用

时间:2011年05月11日作者:ronald查看次数:1,254 views评论次数:0

先上效果图, 该图片是我软件中的TabHost的使用效果:

(这个是没有选中的背景图)

(这个是选中的背景图)

点击不同的Tab后进行切换不同的Tab的效果.

要实现以上的效果要有以下几的步骤:

第一步:在xml布局页面中添加TabHost

<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/tabhost" android:layout_width="fill_parent"
	android:layout_height="wrap_content"
	>
	<LinearLayout android:orientation="vertical"
		android:layout_width="fill_parent" 
                android:layout_height="wrap_content">
		<TabWidget android:id="@android:id/tabs"
			android:layout_width="fill_parent" 
                        android:layout_height="wrap_content"
			 />
		<FrameLayout android:id="@android:id/tabcontent"
			android:layout_width="fill_parent" 
                        android:layout_height="fill_parent">
                <!-- 未开始 -->
		<ListView android:id="@+id/textview_notbegin" 
                         android:layout_width="fill_parent"
		         android:layout_height="fill_parent" 
                         android:drawSelectorOnTop="false" 
                         android:dividerHeight="-1px"/>
                <!-- 进行中 -->
		<ListView android:id="@+id/textview_playing" 
                        android:layout_width="fill_parent"
			android:layout_height="fill_parent" 
                        android:drawSelectorOnTop="false" 
                        android:dividerHeight="-1px"/>
                <!-- 已完场 -->
		<ListView android:id="@+id/textview_finish" 
                        android:layout_width="fill_parent"
			android:layout_height="fill_parent" 
                        android:drawSelectorOnTop="false" 
                        android:dividerHeight="-1px"/>
                <!-- 关注 -->
		<ListView android:id="@+id/textview_focus" 
                        android:layout_width="fill_parent"
			android:layout_height="fill_parent" 
                        android:drawSelectorOnTop="false" 
                        android:dividerHeight="-1px"/>
		</FrameLayout>
	</LinearLayout>
</TabHost>

第二步:编写Activity
在Activity的onCreate方法中添加以下代码:

        // mTabHost定义在Activity的属性
	mTabHost = (TabHost) findViewById(R.id.tabhost);
        mTabHost.setup();
 
        LayoutInflater factory = null;
        // 未开始
        factory = LayoutInflater.from(this);
        final View notStartview = factory.inflate(R.layout.tab,null);
        TextView notStartTextView = (TextView)notStartview.findViewById(R.id.tabName);
		notStartTextView.setText(getText(R.string.text_tab_notstart));
		notStartTextView
               .setBackgroundDrawable(getResources().getDrawable(R.drawable.tab));
 
        // 进行中
        factory = LayoutInflater.from(this);
        final View playingView = factory.inflate(R.layout.tab,null);
        TextView playingTextView = (TextView)playingView.findViewById(R.id.tabName);
        playingTextView.setText(getText(R.string.text_tab_playing));
        playingTextView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_act));
 
        // 已完场
        factory = LayoutInflater.from(this);
        final View finishView = factory.inflate(R.layout.tab,null);
        TextView finishTextView = (TextView)finishView.findViewById(R.id.tabName);
        finishTextView.setText(getText(R.string.text_tab_finish));
        finishTextView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab));
 
        // 关注
        factory = LayoutInflater.from(this);
        final View focusView = factory.inflate(R.layout.tab,null);
        TextView focusTextView = (TextView)focusView.findViewById(R.id.tabName);
        focusTextView.setText(getText(R.string.text_tab_focus));
        focusTextView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab));
 
        // 未开始
        mTabHost.addTab(mTabHost.newTabSpec("tab_not_begin")
          .setIndicator(notStartview)
          .setContent(R.id.textview_notbegin));
        // 进行中
        mTabHost.addTab(mTabHost.newTabSpec("tab_playing")
          .setIndicator(playingView)
          .setContent(R.id.textview_playing));  
        // 已完场
        mTabHost.addTab(mTabHost.newTabSpec("tab_finish")
          .setIndicator(finishView)
          .setContent(R.id.textview_finish));  
        // 关注
        mTabHost.addTab(mTabHost.newTabSpec("tab_focus")
          .setIndicator(focusView)
          .setContent(R.id.textview_focus));  
 
        // 修改宽度,作用两个(关注)与三个字(进行中,已完场)占有不同,三个字宽度大一些
        for (int i =0; i < mTabHost.getTabWidget().getChildCount(); i++) {
        	mTabHost.getTabWidget().getChildAt(i).getLayoutParams().height = DisplayUtil.dip2px(this, 33);
 
        	if(i == 1 || i== 2){
        		mTabHost.getTabWidget().getChildAt(i).getLayoutParams().width = 18;
        	} else{
        		mTabHost.getTabWidget().getChildAt(i).getLayoutParams().width = 10;
        	}
        }
 
        // 设置当前选中的Tab
        mTabHost.setCurrentTab(1);
        mTabHost.getTabWidget().getChildAt(mTabHost.getCurrentTab()).setBackgroundColor(Color.BLACK);
 
        // tab 选中改变时事件
        mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
		public void onTabChanged(String arg0) {
			for(int i=0;i<mTabHost.getTabWidget().getChildCount();i++){
			       mTabHost.getTabWidget().getChildAt(i).findViewById(R.id.tabName)
                                .setBackgroundDrawable(getResources().getDrawable(R.drawable.tab));
			}
			mTabHost.getTabWidget().getChildAt(mTabHost.getCurrentTab())
                        .findViewById(R.id.tabName)
                        .setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_act));
		}
	});

以上中有使用 DisplayUtil.dip2px(this, 33); 的代码,是为了支持多种分辨率的手机的.
相关内容可以查看 [Android中dip(dp)与px之间单位转换]

第三步:定义Tab的内容xml布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content"
	android:background="@drawable/tab"
	>
	<TextView android:id="@+id/tabName"
		android:background="@drawable/tab"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:gravity="bottom|center_horizontal"
		android:textColor="#FFFFFF" 
		android:textSize="14dip"
		android:paddingBottom="3dip"
		android:layout_alignParentBottom="true"
		 />
</RelativeLayout>

以上定义了显示的文字(进行中,已完场…)和背景图片.
TabHost在Android中经常都要使用,了解这种方式可以实现很多的需求了.本人一直都在使用这种方式

返回 : Android开发博文汇总