漫谈android开发之菜单(二)

接上篇:漫谈android开发之菜单(一)

版本二:          

    版本一的原料是LinearLayout+Buttons+LayoutInflater.我们可以想到,“互斥”这一属性明显就是由RadioButton代言。所以这个版本咱们将RadioButton加入。布局文件大致上不变,修改下RadioButton和加入RadioGroup就OK。逻辑方面,需要实现OnCheckedChangeListener接口。同时,背景图片的改变咱们这里用selector代替。布局代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    <LinearLayout 
        android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:orientation="vertical">
           <FrameLayout 
               android:id="@android:id/tabcontent"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:layout_weight="1"/>
            <RadioGroup
                android:id="@+id/rb_group"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
                <RadioButton
                    android:id="@+id/rb_0"
                    android:checked="true"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:button="@null"
                    android:layout_weight="1"
                    android:background="@drawable/tab_index_selector"/>
                <RadioButton
                    android:id="@+id/rb_1"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:button="@null"
                    android:layout_weight="1"
                    android:background="@drawable/tab_home_selector"/>
                <RadioButton
                    android:id="@+id/rb_2"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:button="@null"
                    android:layout_weight="1"
                    android:background="@drawable/tab_wt_selector"/>
                <RadioButton
                    android:id="@+id/rb_3"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:button="@null"
                    android:layout_weight="1"
                    android:background="@drawable/tab_yh_selector"/>
            </RadioGroup>
    </LinearLayout>
</TabHost>

selector需要在drawable下实现一个xml文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<selector
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="false" android:drawable="@drawable/bst_tab_home_0" />
    <item android:state_checked="true" android:drawable="@drawable/bst_tab_home_1" />
</selector>

在onCheckedChanged中,需要注意一点的是,不要忘记判断当前RadioButton是否被点击。因为onCheckedChanged记录的是点击状态改变的RadioButton,因此每次点击事件会有两个RadioButton的状态发生改变,分别是由选中到未选中、由未选中到选中。所以如果只需要获取被点击的那个RadioButton的话,建议在代码最外层加一个if判断。代码如下:

package com.example.menutest;

import android.app.Activity;
import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TabHost;
import android.widget.TabHost.TabContentFactory;

public class MenuRbActivity extends Activity implements OnCheckedChangeListener{
    private RadioGroup radioGroup;
    private RadioButton rbHd,rbHome,rbWt,rbYh;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rb);
        initViews();
    }

    private void initViews() {
        // TODO Auto-generated method stub
        //Initialize  RadioGroup and RadioButtons
        radioGroup = (RadioGroup) findViewById(R.id.rb_group);
        rbHd = (RadioButton) findViewById(R.id.rb_0);
        rbHd.setOnCheckedChangeListener(this);
        rbHome = (RadioButton) findViewById(R.id.rb_1);
        rbHome.setOnCheckedChangeListener(this);
        rbWt = (RadioButton) findViewById(R.id.rb_2);
        rbWt.setOnCheckedChangeListener(this);
        rbYh = (RadioButton) findViewById(R.id.rb_3);
        rbYh.setOnCheckedChangeListener(this);
    }

    @Override
    public void onCheckedChanged(CompoundButton bv, boolean isChecked) {
        // TODO Auto-generated method stub
        if(isChecked)
        switch(bv.getId()){
        case R.id.rb_0:
            rbHd.setChecked(true);
            //设置第一个选项的内容break;
        case R.id.rb_1:
            rbHd.setChecked(true);
            //设置第二个选项的内容break;
        case R.id.rb_2:
            rbHd.setChecked(true);break;
        case R.id.rb_3:
            rbHd.setChecked(true);break;
        }
    }
}

版本二的选项区做了改变。然后内容区依旧选择使用LayoutInflater.

 

版本三:            

    以上两个版本我们完成了选项区的改变,使用RadioButton已经比较接近现在大部分程序员的开发习惯。

    那么内容区,虽然LayoutInflater可以比较简单的实现View的贴入,但是就代码来说,比较冗余和繁杂。这时,一个我们熟悉的老朋友闪亮登场,TabHost.。

    TabHost的实现和前两个版本的LayoutInflater差不多。区别点在于,TabHost的每一个内容View要么是布局都写在同一个文件中——这样就不需要LayoutInflater,我估计底层使用的是类似findViewById()方法。(有知道的朋友请说一下。)要么就是把每个内容View的布局写在不同的布局文件中,那么,这个就是使用的LayoutInflater。

    另外,TabHost的好处是,google将这些封装了起来(你看不见LayoutInflater)。所以代码上结构性强,可观赏性有所提升。

    下面是RadioButton+TabHost的代码:

    

<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    <LinearLayout 
        android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:orientation="vertical">
           <FrameLayout 
               android:id="@android:id/tabcontent"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:layout_weight="1"/>
           <TabWidget 
               android:id="@android:id/tabs"
               android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom">
            <RadioGroup
                android:id="@+id/rb_group"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
                <RadioButton
                    android:id="@+id/rb_0"
                    android:checked="true"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:button="@null"
                    android:layout_weight="1"
                    android:background="@drawable/tab_index_selector"/>
                <RadioButton
                    android:id="@+id/rb_1"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:button="@null"
                    android:layout_weight="1"
                    android:background="@drawable/tab_home_selector"/>
                <RadioButton
                    android:id="@+id/rb_2"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:button="@null"
                    android:layout_weight="1"
                    android:background="@drawable/tab_wt_selector"/>
                <RadioButton
                    android:id="@+id/rb_3"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:button="@null"
                    android:layout_weight="1"
                    android:background="@drawable/tab_yh_selector"/>
            </RadioGroup>
        </TabWidget>
    </LinearLayout>
</TabHost>

 

     布局文件就是加入了TabHost,需要注意的是,如果你继承TabActivity,然后使用了默认的setContentView(),就必须要有tabhost、tabcontent、tabs等存在,分别有对应的组件。设置Id时是@android:id/tabcontent,这是因为这几个id都是android本身拥有的,不需要+id.

package com.example.menutest;

import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RadioButton;
import android.widget.TabHost;

public class MenuRbActivity extends TabActivity implements OnCheckedChangeListener{
    private RadioButton rbHd,rbHome,rbWt,rbYh;
    private TabHost mTabHost;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rb);
        initViews();
    }

    private void initViews() {
        // TODO Auto-generated method stub
        //Initialize  RadioGroup and RadioButtons
        rbHd = (RadioButton) findViewById(R.id.rb_0);
        rbHd.setOnCheckedChangeListener(this);
        rbHome = (RadioButton) findViewById(R.id.rb_1);
        rbHome.setOnCheckedChangeListener(this);
        rbWt = (RadioButton) findViewById(R.id.rb_2);
        rbWt.setOnCheckedChangeListener(this);
        rbYh = (RadioButton) findViewById(R.id.rb_3);
        rbYh.setOnCheckedChangeListener(this);
        
        //Initialize TabHost
        mTabHost = getTabHost();
        mTabHost.addTab(mTabHost.newTabSpec("0").setIndicator("").setContent(new Intent(MenuRbActivity.this,Tab0Activity.class)));
        mTabHost.addTab(mTabHost.newTabSpec("1").setIndicator("").setContent(new Intent(MenuRbActivity.this,Tab1Activity.class)));
        mTabHost.addTab(mTabHost.newTabSpec("2").setIndicator("").setContent(new Intent(MenuRbActivity.this,Tab2Activity.class)));
        mTabHost.addTab(mTabHost.newTabSpec("3").setIndicator("").setContent(new Intent(MenuRbActivity.this,Tab3Activity.class)));
        //let view tab0 be showed at first
        mTabHost.setCurrentTab(0);
    }

    @Override
    public void onCheckedChanged(CompoundButton bv, boolean isChecked) {
        // TODO Auto-generated method stub
        if(isChecked)
        switch(bv.getId()){
        case R.id.rb_0:
            rbHd.setChecked(true);
            mTabHost.setCurrentTab(0);
            break;
        case R.id.rb_1:
            rbHd.setChecked(true);
            mTabHost.setCurrentTab(1);
            break;
        case R.id.rb_2:
            rbHd.setChecked(true);
            mTabHost.setCurrentTab(2);
            break;
        case R.id.rb_3:
            rbHd.setChecked(true);
            mTabHost.setCurrentTab(3);
            break;
        }
    }
}

   逻辑上基本就是版本二的内容。

   版本三基本就完成了一般的tab架构。RadioButton+TabHost也是一个比较普遍使用的菜单。那么我们可不可以给这个菜单加上滑动切换View呢?这个得等到下一个版本再说了。

posted @ 2013-07-31 19:33  光源  阅读(1092)  评论(0编辑  收藏  举报