论坛首页 移动开发技术论坛

android底部菜单应用

浏览 33599 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (2) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-10-08  

在android中实现菜单功能有多种方法。

Options Menu:用户按下menu Button时显示的菜单。

Context Menu:用户长时间按下屏幕,所显示出来的菜单也称为上下文菜单。

Submenu:子菜单。

但是有时候这些内置的菜单并不能满足我们功能,这就需要自己自定义一种菜单。接下来我说的这种就是通过TabHost与RadioGroup结合完成的菜单。这也是很常用的一种底部菜单做法。先上图:

 



 

首先看布局文件:

 

 

 

 

<?xml version="1.0" encoding="UTF-8"?>
<TabHost android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <LinearLayout 
    	android:orientation="vertical" 
    	android:layout_width="fill_parent" 
    	android:layout_height="fill_parent">
        <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" />
        <RadioGroup 
        	android:gravity="center_vertical" 
        	android:layout_gravity="bottom" 
        	android:orientation="horizontal" 
        	android:id="@+id/main_radio" 
        	android:background="@drawable/maintab_toolbar_bg" 
        	android:layout_width="fill_parent" 
        	android:layout_height="wrap_content">
            <RadioButton 
            	android:id="@+id/radio_button0" 
            	android:tag="radio_button0" 
            	android:layout_marginTop="2.0dip" 
            	android:text="@string/alarm" 
            	android:drawableTop="@drawable/icon_1" 
            	style="@style/main_tab_bottom" />
            <RadioButton 
            	android:id="@+id/radio_button1" 
            	android:tag="radio_button1" 
            	android:layout_marginTop="2.0dip" 
            	android:text="@string/message" 
            	android:drawableTop="@drawable/icon_2" 
            	style="@style/main_tab_bottom" />
            <RadioButton 
            	android:id="@+id/radio_button2" 
            	android:tag="radio_button2" 
            	android:layout_marginTop="2.0dip" 
            	android:text="@string/photo" 
            	android:drawableTop="@drawable/icon_3" 
            	style="@style/main_tab_bottom" />
            <RadioButton 
            	android:id="@+id/radio_button3" 
            	android:tag="radio_button3" 
            	android:layout_marginTop="2.0dip" 
            	android:text="@string/music" 
            	android:drawableTop="@drawable/icon_4" 
            	style="@style/main_tab_bottom" />
            <RadioButton 
            	android:id="@+id/radio_button4" 
            	android:tag="radio_button4" 
            	android:layout_marginTop="2.0dip" 
            	android:text="@string/setting" 
            	android:drawableTop="@drawable/icon_5" 
            	style="@style/main_tab_bottom" />
        </RadioGroup>
    </LinearLayout>
</TabHost>

 

需要注意的是,如果用TabHost这个控件,其中有几个ID是必须这么写的,android:id="@android:id/tabhost   ;android:id="@android:id/tabcontent" ;android:id="@android:id/tabs" ;之所以要这么写是因为在TabHost这个类中。需要实例化上述这个ID的控件。看源码:

 

在TabActivity中有么个方法:

 @Override
    public void onContentChanged() {
        super.onContentChanged();
        mTabHost = (TabHost) findViewById(com.android.internal.R.id.tabhost);

        if (mTabHost == null) {
            throw new RuntimeException(
                    "Your content must have a TabHost whose id attribute is " +
                    "'android.R.id.tabhost'");
        }
        mTabHost.setup(getLocalActivityManager());
    }

    private void ensureTabHost() {
        if (mTabHost == null) {
            this.setContentView(com.android.internal.R.layout.tab_content);
        }
    }

 当内容发生改变时它会调用这个方法,来更新列表或者其他视图,而这个方法中需要实例化TabHost,所以必须通过ID为tabhost实例化。

 

再看看TabHost这个类中,

 

  public void setup() {
        mTabWidget = (TabWidget) findViewById(com.android.internal.R.id.tabs);
        if (mTabWidget == null) {
            throw new RuntimeException(
                    "Your TabHost must have a TabWidget whose id attribute is 'android.R.id.tabs'");
        }

        // KeyListener to attach to all tabs. Detects non-navigation keys
        // and relays them to the tab content.
        mTabKeyListener = new OnKeyListener() {
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                switch (keyCode) {
                    case KeyEvent.KEYCODE_DPAD_CENTER:
                    case KeyEvent.KEYCODE_DPAD_LEFT:
                    case KeyEvent.KEYCODE_DPAD_RIGHT:
                    case KeyEvent.KEYCODE_DPAD_UP:
                    case KeyEvent.KEYCODE_DPAD_DOWN:
                    case KeyEvent.KEYCODE_ENTER:
                        return false;

                }
                mTabContent.requestFocus(View.FOCUS_FORWARD);
                return mTabContent.dispatchKeyEvent(event);
            }

        };

        mTabWidget.setTabSelectionListener(new TabWidget.OnTabSelectionChanged() {
            public void onTabSelectionChanged(int tabIndex, boolean clicked) {
                setCurrentTab(tabIndex);
                if (clicked) {
                    mTabContent.requestFocus(View.FOCUS_FORWARD);
                }
            }
        });

        mTabContent = (FrameLayout) findViewById(com.android.internal.R.id.tabcontent);
        if (mTabContent == null) {
            throw new RuntimeException(
                    "Your TabHost must have a FrameLayout whose id attribute is "
                            + "'android.R.id.tabcontent'");
        }
    }

 这个方法,是在增加选项卡之前由系统调用。在这个方法中需要通过tabs 这个ID实例化一个TabWidget,通过tabcontent这个ID实例化一个FrameLayout,用来放置选项卡内容。所以这两个ID也是固定的。

 

在上述布局文件中隐藏了系统默认的Widget,取而代之的是带有图片的Button。

 

看一下主要代码:

package com.iteye.androidtoast;

import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.TabHost;

public class MainActivity extends TabActivity implements OnCheckedChangeListener{
    /** Called when the activity is first created. */
	private TabHost mHost;
	private RadioGroup radioderGroup;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.maintabs);
        //实例化TabHost
        mHost=this.getTabHost();
        
        //添加选项卡
        mHost.addTab(mHost.newTabSpec("ONE").setIndicator("ONE")
        			.setContent(new Intent(this,OneActivity.class)));
        mHost.addTab(mHost.newTabSpec("TWO").setIndicator("TWO")
        		.setContent(new Intent(this,TwoActivity.class)));
        mHost.addTab(mHost.newTabSpec("THREE").setIndicator("THREE")
        		.setContent(new Intent(this,ThreeActivity.class)));
        mHost.addTab(mHost.newTabSpec("FOUR").setIndicator("FOUR")
        		.setContent(new Intent(this,FourActivity.class)));
        mHost.addTab(mHost.newTabSpec("FIVE").setIndicator("FIVE")
        		.setContent(new Intent(this,FiveActivity.class)));
        
        radioderGroup = (RadioGroup) findViewById(R.id.main_radio);
		radioderGroup.setOnCheckedChangeListener(this);
    }
	@Override
	public void onCheckedChanged(RadioGroup group, int checkedId) {
		switch(checkedId){
		case R.id.radio_button0:
			mHost.setCurrentTabByTag("ONE");
			break;
		case R.id.radio_button1:
			mHost.setCurrentTabByTag("TWO");
			break;
		case R.id.radio_button2:
			mHost.setCurrentTabByTag("THREE");
			break;
		case R.id.radio_button3:
			mHost.setCurrentTabByTag("FOUR");
			break;
		case R.id.radio_button4:
			mHost.setCurrentTabByTag("FIVE");
			break;
		}		
	}
}

 这个应该没有什么好难理解的。OK该睡了。有什么问题留言!

 

  • 大小: 247 KB
   发表时间:2011-10-09  
有用。多谢分享!
0 请登录后投票
   发表时间:2011-10-10  
有用,值得借鉴
0 请登录后投票
   发表时间:2011-10-10  
收藏ing....谢谢
0 请登录后投票
   发表时间:2011-10-10  
不错,但是目前有没有人收集整理过常用的一些andrid开发的代码片段啊 ?
0 请登录后投票
   发表时间:2011-10-10  
bluky999 写道
不错,但是目前有没有人收集整理过常用的一些andrid开发的代码片段啊 ?

Professional Android2 Application Development这本书就有很多
1 请登录后投票
   发表时间:2011-10-11  
讲解 为什么一定要顶 id 为 @android:id/tabhost 或者 tabs 。。是亮点!多谢楼主!
0 请登录后投票
   发表时间:2011-10-12  
楼主 如何保存的gif动画效果。。。。
0 请登录后投票
   发表时间:2011-10-12  
工程中怎么没找到TabActivity
0 请登录后投票
   发表时间:2011-10-12   最后修改:2011-10-12
为什么要把tabwdiget gone掉,然后用RadioGroup代替,且并没有加入什么它不能完成的功能呢?
我觉得不应该这么复杂,仅TabActivity就足够用了吧。
0 请登录后投票
论坛首页 移动开发技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics