zoukankan      html  css  js  c++  java
  • Android TabHost中切換、修改需要显示的Activity

    上個星期跟盛哥試了一段時間使用Fragment後還是不得其門而入(兩個人對Fragment都還不太熟悉),卡住的原因是現在有兩個Tab,當Tab1進入到第二個畫面,Tab2進到第三個畫面,但使用者切回Tab1的時候,Tab1的狀態無法被保留(第二畫面),這個影響就是如果使用者透過Tab1已經搜尋到想要的資料後,因為某些原因切到Tab2,這時候想點回Tab1時,資料卻已經消失,這對使用者體驗來說是非常差的。

    前天看到盛哥留言已經解決了上述問題,而在看到盛哥解決之前,小蛙也在
    Android: TabActivity Nested Activities @ Henrik Larsen Toft
    Android : How to have multiple activities under a single tab of TabActivity @ GammaPoint
    這兩篇文章中找到曙光,要讓Activity彼此切換,在這邊使用到了ActivityGroup去管理各個Activity切換的動作,並且額外設置了一個ArrayList<View> history當作Back Stack來使用。但小蛙照著做卻還是沒辦法使用,所以修改了一些東西。

    做法從上圖可以看得出來(也有可能畫得太爛造成大家看不太懂),首先小蛙在MainActivity中建立了3個Tab,分別是Tab1、Tab2、Tab3,而Tab1中會有兩次切換Activity的動作(既然是兩次為什麼會有3個Activity?等等後面小蛙會說明),以此類推Tab2也相同,Tab3則是很單純的直接顯示一個Activity7。

    會使用到同一頁籤中切換Activity的所有Activity都必須透過ActivityGroup來做管理,也就是圖中的Activity1、Activity2、Activity3都是可以透過ActivityGroup1來管理,同理可說明ActivityGroup2,每個ActivityGroup又另外設置了個別的Back Stack來管理當使用者按下Back鍵時的行為(例如:該退出程式還是回到上一個Activity、切換Tab時該Tab原本停留的狀態),至於Activity7因為只有單一頁面所以不需要這麼麻煩。介紹完架構家族之後,進到程式碼的部份。

    承上篇文章Android TabHost Without TabActivity,在MainActivity中的TabHost加入頁籤。


    mHost.addTab(mHost.newTabSpec(getString(R.string.tab_two_name))
                    .setIndicator(getString(R.string.tab_two_name))
                    .setContent(new Intent(this, ActivityGroup1.class)));

    小蛙在測試了上面兩篇文章的方法後發現,必須要在ActivityGroup1中直接先載入Activity1(也就是ActivityGroup僅用來”操作”這些Activity,並沒有實質的內容呈現,如果讓ActivityGroup在這邊有自己的內容呈現,會造成Back Stack運作錯誤,也有可能是小蛙實作上出了問題,如果照著上面兩篇文章試不出來的網友,不妨參照小蛙的做法),以下是ActivityGroup1的程式碼:

    public class ActivityGroup1 extends ActivityGroup{
        /** 設定成 static 讓其他的子 Activity 可以存取 */
        public static ActivityGroup1 group;
        /** Back Stack */
        private ArrayList<View> history;
     
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            this.history = new ArrayList<View>();
            group = this;
     
            // ActivityGroup1 只是一個外框,在這個外框中載入其他要用的 Activity
            // 如果沒有這個外框會發生錯誤
            View view = getLocalActivityManager()
                      .startActivity("Activity1",
                                      new Intent(ActivityGroup1.this, Activity1.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
                      .getDecorView();
            // 馬上載入真正要執行的 Activity
            replaceView(view);
        }
     
        /**
         * 在 ActivityGroup 中切換 Activity
         * @param v
         */
        public void replaceView(View v) {
            // 可在這插入換頁動畫
            history.add(v);
            setContentView(v);
        }
     
        /**
         * 當使用者按下 back 的時候,把之前存起來的 stack 撈回來顯示
         */
        public void back() {
            // 原本的範例是寫 > 0,但會發生錯誤
            if(history.size() > 1) {
                history.remove(history.size()-1);
                View v = history.get(history.size()-1);
                // 可在這插入換頁動畫
                setContentView(v);
            }else {
                // back stack 沒有其他頁面可顯示,直接結束
                finish();
            }
        }
        /**
         * 複寫聆聽按下 back 事件,呼叫 back()
         */
        // 由於我的股票精算師是使用1.6+,因此採用onKeyDown來監聽
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            switch (keyCode) {
                case KeyEvent.KEYCODE_BACK:
                    back();
                    break;
            }
            return true;
        }
    }

    至於在Activity1中的設定如下:

    public class Activity1 extends Activity{
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity1);
            Button button = (Button) findViewById(R.id.button1);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 如果沒有這個外框會發生錯誤
                    View view = ActivityGroup1.group.getLocalActivityManager().startActivity("Activity2", new Intent(Activity1.this, Activity2.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();
                    // 載入真正要執行的 Activity
                    ActivityGroup1.group.replaceView(view);
                }
            });
    }

    基本上到這邊就已經可以正常運作囉!有什麼問題可以留言在這邊,小蛙會盡可能的協助解決。

    2013-01-30 有網友反應 MediaFire 的檔案無法下載,更新下載路徑。範例檔下載

    2012-10-22 範例檔下載

    转载自:http://wazai.net/2114


  • 相关阅读:
    Interview with BOA
    Java Main Differences between HashMap HashTable and ConcurrentHashMap
    Java Main Differences between Java and C++
    LeetCode 33. Search in Rotated Sorted Array
    LeetCode 154. Find Minimum in Rotated Sorted Array II
    LeetCode 153. Find Minimum in Rotated Sorted Array
    LeetCode 75. Sort Colors
    LeetCode 31. Next Permutation
    LeetCode 60. Permutation Sequence
    LeetCode 216. Combination Sum III
  • 原文地址:https://www.cnblogs.com/xieyuan/p/3787397.html
Copyright © 2011-2022 走看看