zoukankan      html  css  js  c++  java
  • Android -- TabHost、Fragment、状态保存、通信

    工程结构                                                                                      

    image

    TabAFm到TabEFm都是Fragment,并且每个Fragment对应一个布局文件。

    TabAFm.java                                                                            

    package com.yydcdut.tabhoststudy;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    
    public class TabAFm extends Fragment {
    
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            System.out.println("AAAAAAAAAA____onAttach");
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            System.out.println("AAAAAAAAAA____onCreate");
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            System.out.println("AAAAAAAAAA____onCreateView");
            return inflater.inflate(R.layout.tab_a, container, false);
        }
    
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            System.out.println("AAAAAAAAAA____onActivityCreated");
        }
    
        @Override
        public void onStart() {
            super.onStart();
            System.out.println("AAAAAAAAAA____onStart");
        }
    
        @Override
        public void onResume() {
            super.onResume();
            System.out.println("AAAAAAAAAA____onResume");
        }
    
        @Override
        public void onPause() {
            super.onPause();
            System.out.println("AAAAAAAAAA____onPause");
        }
    
        @Override
        public void onStop() {
            super.onStop();
            System.out.println("AAAAAAAAAA____onStop");
        }
    
        @Override
        public void onDestroyView() {
            super.onDestroyView();
            System.out.println("AAAAAAAAAA____onDestroyView");
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            System.out.println("AAAAAAAAAA____onDestroy");
        }
    
        @Override
        public void onDetach() {
            super.onDetach();
            System.out.println("AAAAAAAAAA____onDetach");
        }
        
    }

    如上述代码所示,TabAFm是一个Fragment,对应的布局文件是tab_a.xml,并实现了他的所有的生命周期回调函数并打印,便于调试。tab_a.xml布局中有个EditText,其他的Fragment大同小异,这里就不贴出代码了

    MainActivity                                                                             

    package com.yydcdut.tabhoststudy;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.view.ViewPager;
    import android.widget.RadioGroup;
    
    public class MainActivity extends FragmentActivity {
    
        private RadioGroup rgs;
        public List<Fragment> fragments = new ArrayList<Fragment>();
    
        public String hello = "hello ";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            fragments.add(new TabAFm());
            fragments.add(new TabBFm());
            fragments.add(new TabCFm());
            fragments.add(new TabDFm());
            fragments.add(new TabEFm());
    
            rgs = (RadioGroup) findViewById(R.id.tabs_rg);
    
            FragmentTabAdapter2 tabAdapter = new FragmentTabAdapter2(this, fragments, R.id.tab_content, rgs);
            tabAdapter.setOnRgsExtraCheckedChangedListener(new FragmentTabAdapter2.OnRgsExtraCheckedChangedListener(){
                @Override
                public void OnRgsExtraCheckedChanged(RadioGroup radioGroup, int checkedId, int index) {
                    System.out.println("Extra---- " + index + " checked!!! ");
                }
            });
        }
    }

    MainActivity上述代码所示

    MainActivity是包含Fragment的Activity(也就是这里的5个Fragment)

    他继承了FragmentActivity(因为我这里用的是android-support-v4.jar)

    用一个List<Fragment>去维护5个Fragment,也就是5个tab

    main布局                                                                                    

    有一个id为tab_content的FrameLayout,用来存放要显示的Fragment。底部有一个RadioGroup,用于tab的切换

    <?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:background="@android:color/white"
        android:orientation="vertical" >
    
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical" >
    
            <FrameLayout
                android:id="@+id/tab_content"
                android:layout_width="fill_parent"
                android:layout_height="0dp"
                android:layout_weight="1.0"
                android:background="#77557799" />
    
            <RadioGroup
                android:id="@+id/tabs_rg"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:orientation="horizontal"
                android:paddingBottom="7dp"
                android:paddingTop="7dp" >
    
                <RadioButton
                    android:id="@+id/tab_rb_a"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1.0"
                    android:background="@drawable/selector_tab"
                    android:button="@null"
                    android:checked="true"
                    android:drawableTop="@drawable/tablatestalert"
                    android:gravity="center"
                    android:singleLine="true"
                    android:text="Tab1"
                    android:textColor="#000000"
                    android:textSize="13sp" />
    
                <RadioButton
                    android:id="@+id/tab_rb_b"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1.0"
                    android:background="@drawable/selector_tab"
                    android:button="@null"
                    android:drawableTop="@drawable/tabsearch"
                    android:gravity="center"
                    android:singleLine="true"
                    android:text="Tab2"
                    android:textColor="#000000"
                    android:textSize="13sp" />
    
                <RadioButton
                    android:id="@+id/tab_rb_c"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1.0"
                    android:background="@drawable/selector_tab"
                    android:button="@null"
                    android:drawableTop="@drawable/tabrecommd"
                    android:gravity="center"
                    android:singleLine="true"
                    android:text="Tab3"
                    android:textColor="#000000"
                    android:textSize="13sp" />
    
                <RadioButton
                    android:id="@+id/tab_rb_d"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1.0"
                    android:background="@drawable/selector_tab"
                    android:button="@null"
                    android:drawableTop="@drawable/tabconfigicon"
                    android:gravity="center"
                    android:singleLine="true"
                    android:text="Tab4"
                    android:textColor="#000000"
                    android:textSize="13sp" />
    
                <RadioButton
                    android:id="@+id/tab_rb_e"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1.0"
                    android:background="@drawable/selector_tab"
                    android:button="@null"
                    android:drawableTop="@drawable/tababoutus"
                    android:gravity="center"
                    android:singleLine="true"
                    android:text="Tab5"
                    android:textColor="#000000"
                    android:textSize="13sp" />
            </RadioGroup>
        </LinearLayout>
    
    </LinearLayout>

    现在回到MainActivity中,下面这个FragmentTabAdapter类是关键,是我自己编写的用于绑定和处理fragments和RadioGroup之间的逻辑关系

    FragmentTabAdapter2 tabAdapter = new FragmentTabAdapter2(this, fragments, R.id.tab_content, rgs);

    FragmentTabAdapter2                                                            

    package com.yydcdut.tabhoststudy;
    
    import java.util.List;
    
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.app.FragmentTransaction;
    import android.widget.RadioGroup;
    import android.widget.RadioGroup.OnCheckedChangeListener;
    
    public class FragmentTabAdapter2 {
        private List<Fragment> fragments; // 一个tab页面对应一个Fragment
        private RadioGroup rgs; // 用于切换tab
        private FragmentActivity fragmentActivity; // Fragment所属的Activity
        private int fragmentContentId; // Activity中所要被替换的区域的id
    
        private int currentTab; // 当前Tab页面索引
    
        private OnRgsExtraCheckedChangedListener onRgsExtraCheckedChangedListener; // 用于让调用者在切换tab时候增加新的功能
    
        /**
         * 构造函数
         * 
         * @param fragmentActivity
         * @param fragments
         * @param fragmentContentId
         * @param rgs
         */
        public FragmentTabAdapter2(FragmentActivity fragmentActivity,
                List<Fragment> fragments, int fragmentContentId, RadioGroup rgs) {
            this.fragments = fragments;
            this.rgs = rgs;
            this.fragmentActivity = fragmentActivity;
            this.fragmentContentId = fragmentContentId;
    
            // 默认显示第一页
            FragmentTransaction ft = fragmentActivity.getSupportFragmentManager()
                    .beginTransaction();
            ft.add(fragmentContentId, fragments.get(0));
            ft.commit();
            // 设置监听事件
            MyCheckedChangeListener myCheckedChangeListener = new MyCheckedChangeListener();
            rgs.setOnCheckedChangeListener(myCheckedChangeListener);
    
        }
    
        /**
         * 监听器内部类
         * 
         * @author sansung
         * 
         */
        class MyCheckedChangeListener implements OnCheckedChangeListener {
    
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                for (int i = 0; i < rgs.getChildCount(); i++) {
                    if (rgs.getChildAt(i).getId() == checkedId) {
                        Fragment fragment = fragments.get(i);
                        FragmentTransaction ft = obtainFragmentTransaction(i);
    
                        getCurrentFragment().onPause(); // 暂停当前tab
                        // getCurrentFragment().onStop(); // 暂停当前tab
    
                        if (fragment.isAdded()) {
                            // fragment.onStart(); // 启动目标tab的onStart()
                            fragment.onResume(); // 启动目标tab的onResume()
                        } else {
                            ft.add(fragmentContentId, fragment);
                        }
                        showTab(i); // 显示目标tab
                        ft.commit();
    
                        // 如果设置了切换tab额外功能功能接口
                        if (null != onRgsExtraCheckedChangedListener) {
                            onRgsExtraCheckedChangedListener
                                    .OnRgsExtraCheckedChanged(group, checkedId, i);
                        }
                    }
                }
            }
        }
    
        /**
         * 切换tab
         * 
         * @param idx
         */
        private void showTab(int idx) {
            for (int i = 0; i < fragments.size(); i++) {
                Fragment fragment = fragments.get(i);
                FragmentTransaction ft = obtainFragmentTransaction(idx);
    
                if (idx == i) {
                    ft.show(fragment);
                } else {
                    ft.hide(fragment);
                }
                ft.commit();
            }
            currentTab = idx; // 更新目标tab为当前tab
        }
    
        /**
         * 获取一个带动画的FragmentTransaction
         * 
         * @param index
         * @return
         */
        private FragmentTransaction obtainFragmentTransaction(int index) {
            FragmentTransaction ft = fragmentActivity.getSupportFragmentManager()
                    .beginTransaction();
            // 设置切换动画
            if (index > currentTab) {
                ft.setCustomAnimations(R.anim.slide_left_in, R.anim.slide_left_out);
            } else {
                ft.setCustomAnimations(R.anim.slide_right_in,
                        R.anim.slide_right_out);
            }
            return ft;
        }
    
        public int getCurrentTab() {
            return currentTab;
        }
    
        public Fragment getCurrentFragment() {
            return fragments.get(currentTab);
        }
    
        public OnRgsExtraCheckedChangedListener getOnRgsExtraCheckedChangedListener() {
            return onRgsExtraCheckedChangedListener;
        }
    
        public void setOnRgsExtraCheckedChangedListener(
                OnRgsExtraCheckedChangedListener onRgsExtraCheckedChangedListener) {
            this.onRgsExtraCheckedChangedListener = onRgsExtraCheckedChangedListener;
        }
    
        /**
         * 切换tab额外功能功能接口
         */
        static class OnRgsExtraCheckedChangedListener {
            public void OnRgsExtraCheckedChanged(RadioGroup radioGroup,
                    int checkedId, int index) {
            }
        }
    }

    这里解决Fragment切换重新加载布局的办法,用的是把几个Fragment全部Add,然后根据要显示的哪个Fragment设置show或者hide

    10-10 11:55:41.168: INFO/System.out(18368): AAAAAAAAAA____onAttach      // 第一次进入,显示TabA
    10-10 11:55:41.168: INFO/System.out(18368): AAAAAAAAAA____onCreate
    10-10 11:55:41.168: INFO/System.out(18368): AAAAAAAAAA____onCreateView
    10-10 11:55:41.175: INFO/System.out(18368): AAAAAAAAAA____onActivityCreated
    10-10 11:55:41.179: INFO/System.out(18368): AAAAAAAAAA____onStart
    10-10 11:55:41.179: INFO/System.out(18368): AAAAAAAAAA____onResume
    10-10 11:55:44.980: INFO/System.out(18368): AAAAAAAAAA____onPause      // 从TabA切换到TabB(TabA调用onPause)
    10-10 11:55:44.980: INFO/System.out(18368): Extra---- 1 checked!!!
    10-10 11:55:44.996: INFO/System.out(18368): BBBBBBBBBBB____onAttach
    10-10 11:55:44.996: INFO/System.out(18368): BBBBBBBBBBB____onCreate
    10-10 11:55:44.996: INFO/System.out(18368): BBBBBBBBBBB____onCreateView
    10-10 11:55:45.004: INFO/System.out(18368): BBBBBBBBBBB____onActivityCreated
    10-10 11:55:45.004: INFO/System.out(18368): BBBBBBBBBBB____onStart
    10-10 11:55:45.004: INFO/System.out(18368): BBBBBBBBBBB____onResume
    10-10 11:55:52.062: INFO/System.out(18368): BBBBBBBBBBB____onPause      // 从TabB切换到TabC(TabB调用onPause)
    10-10 11:55:52.062: INFO/System.out(18368): Extra---- 2 checked!!!
    10-10 11:55:52.082: INFO/System.out(18368): CCCCCCCCCC____onAttach
    10-10 11:55:52.082: INFO/System.out(18368): CCCCCCCCCC____onCreate
    10-10 11:55:52.086: INFO/System.out(18368): CCCCCCCCCC____onCreateView
    10-10 11:55:52.090: INFO/System.out(18368): CCCCCCCCCC____onActivityCreated
    10-10 11:55:52.090: INFO/System.out(18368): CCCCCCCCCC____onStart
    10-10 11:55:52.090: INFO/System.out(18368): CCCCCCCCCC____onResume
    10-10 11:56:06.535: INFO/System.out(18368): CCCCCCCCCC____onPause      // 从TabC切换到TabB(TabC调用onPause)
    10-10 11:56:06.535: INFO/System.out(18368): BBBBBBBBBBB____onResume    // 从TabC切换到TabB(TabB调用onResume)
    10-10 11:56:06.535: INFO/System.out(18368): Extra---- 1 checked!!!

    好了,到此为止,我们已经用Fragment实现了类似TabHost的功能了,下面来看下各个Fragment之间的通信

    现在的情况是TabAFm中有个EditText,TabBFm中有个Button,MainActivity中有个变量“hello”

    要做的是,切换到TabA,输入“I'm TabA”,切换到B,点击Button后,Toast显示“hello I'm TabA”

    MainActivity中没什么好说的,就一个hello变量:

    public String hello = "hello ";

    TabAFm在布局文件tab_a.xml中加个EditText,设置个id就可以了

    TabBFm中:

    @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            System.out.println("BBBBBBBBBBB____onActivityCreated");
            this.getView().findViewById(R.id.clickme).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // 获得绑定的FragmentActivity
                    MainActivity activity = ((MainActivity)getActivity());
                    // 获得TabAFm的控件
                    EditText editText = (EditText) activity.fragments.get(0).getView().findViewById(R.id.edit);
    
                    Toast.makeText(activity, activity.hello + editText.getText(), Toast.LENGTH_SHORT).show();
                }
            });
        }
    // 获得绑定的FragmentActivity
    MainActivity activity = ((MainActivity)getActivity());

    通过getActivity()即可得到Fragment所在的FragmentActivity

    我是天王盖地虎的分割线                                                                 

    1

    源代码:http://pan.baidu.com/s/1dD1Qx01

    tabhost学习.zip

    参考:http://www.cnblogs.com/tiantianbyconan/p/3360938.html

  • 相关阅读:
    kafka学习3——单机伪集群(window版)
    (转)在阿里云 CentOS 服务器(ECS)上搭建 nginx + mysql + php-fpm 环境
    渗透测试工具sqlmap基础教程
    编译安装nginx后service nginx start 启动不了
    centos6.5上tomcat的安装
    centos6.5上安装淘宝tfs系统
    解决nagios登录不了的问题
    centos6.5上网络不通解决方法
    redis远程密码连接
    centos7上定时将mysql数据导出并且发送到指定的邮箱
  • 原文地址:https://www.cnblogs.com/yydcdut/p/3889902.html
Copyright © 2011-2022 走看看