android中的TabGroup Activity问题

时间:2011-06-13 09:38:55

标签: android

我有TabAvtivity,其中特定的Tab我有一个Tab GroupActivity,在这个组下我有3个活动。这是以下格式。

TabActivity - > Tab1 Tab2 Tab3

在Tab2下 - > TabGroupActivity。

TabGroupActivity下的

- > Activiy1 - >活动2 - >活动3。

如果我从活动1中选择活动2 ,则问题出在TabGroupActivity下。当我从活动2回来时。活动1正在重新启动。我不希望这件事发生。与活动2和3相同

这是我的TabGroupActivity

public class TabGroupActivity extends ActivityGroup {

        private ArrayList<String> mIdList;

        static boolean restartFlag=false;

        @Override
        public void onCreate(Bundle savedInstanceState) 
        {
            super.onCreate(savedInstanceState);

            if (mIdList == null) mIdList = new ArrayList<String>();
        }

        /**
        * This is called when a child activity of this one calls its finish method.
        * This implementation calls {@link LocalActivityManager#destroyActivity} on the child activity
        * and starts the previous activity.
        * If the last child activity just called finish(),this activity (the parent),
        * calls finish to finish the entire group.
        */
        @Override
        public void finishFromChild(Activity child) 
        {
            restartFlag=true;

            Log.e("finishFromChild","finishFromChild");
            LocalActivityManager manager = getLocalActivityManager();

            int index = mIdList.size()-1;

            if (index < 1) {

                finish();

                return;
            }

            //manager.destroyActivity(mIdList.get(index), true);

            mIdList.remove(index);

            index--;

            String lastId = mIdList.get(index);

            Intent lastIntent = manager.getActivity(lastId).getIntent();

            Window newWindow = manager.startActivity(lastId, lastIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));

            setContentView(newWindow.getDecorView());

        }

        /**
        * Starts an Activity as a child Activity to this.
        * @param Id Unique identifier of the activity to be started.
        * @param intent The Intent describing the activity to be started.
        * @throws android.content.ActivityNotFoundException.
        *///Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP

        public void startChildActivity(String Id, Intent intent) {

            Window window;
            Log.e("startChildActivity","startChildActivity");

                window = getLocalActivityManager().startActivity(Id,intent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP ));

                if (window != null) 
                {
                    mIdList.add(Id);

                    setContentView(window.getDecorView());
                }


        }

        /**
        * The primary purpose is to prevent systems before android.os.Build.VERSION_CODES.ECLAIR
        * from calling their default KeyEvent.KEYCODE_BACK during onKeyDown.
        */
        /*@Override
        public boolean onKeyDown(int keyCode, KeyEvent event) 
        {
        if (keyCode == KeyEvent.KEYCODE_BACK) 
        {

            //preventing default implementation previous to android.os.Build.VERSION_CODES.ECLAIR
            return true;
        }
        return super.onKeyDown(keyCode, event);
        }

        *//**
        * Overrides the default implementation for KeyEvent.KEYCODE_BACK
        * so that all systems call onBackPressed().
        *//*
        @Override
        public boolean onKeyUp(int keyCode, KeyEvent event) 
        {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
            onBackPressed();
            return true;
        }
        return super.onKeyUp(keyCode, event);
        }*/

        /**
        * If a Child Activity handles KeyEvent.KEYCODE_BACK.
        * Simply override and add this method.
        */
        @Override
        public void onBackPressed () 
        {

            Log.e("onBackPressed","Back Came Here");

            int length = mIdList.size();

            Log.d("onBackPressed",String.valueOf(length));

            if ( length >= 1) 
            {
                Activity current = getLocalActivityManager().getActivity(mIdList.get(length-1));
                current.finish();
            }

         }
}   

2 个答案:

答案 0 :(得分:0)

你做了这个复杂的事情。为了简单起见,我更喜欢这样的东西。

TabActivity - &gt; Tab1活动,Tab2活动和Tab3活动

对于Tab2活动,如果要求显示不同的屏幕,则可以使用ViewAnimator。

对于上述问题,您需要查看onBackPressed事件被传播和处理的位置。您完成此操作的方式可以是任何活动或TabGroupActivity或父TabActivity。

答案 1 :(得分:0)

@ E-Madd

在这里,我将发布答案。实际问题是ActivityGroup的destroy()方法(这是一个bug),所以使用这个自定义destroy方法来解决问题。

           public boolean destroy(String id , LocalActivityManager manager) {

    if(manager != null){
        manager.destroyActivity(id, false);
        try {
            final Field mActivitiesField = LocalActivityManager.class.getDeclaredField("mActivities");
            if(mActivitiesField != null){
                mActivitiesField.setAccessible(true);
                @SuppressWarnings("unchecked")
                final Map<String, Object> mActivities = (Map<String, Object>)mActivitiesField.get(manager);
                if(mActivities != null){
                    mActivities.remove(id);
                }
                final Field mActivityArrayField = LocalActivityManager.class.getDeclaredField("mActivityArray");
                if(mActivityArrayField != null){
                    mActivityArrayField.setAccessible(true);
                    @SuppressWarnings("unchecked")
                    final ArrayList<Object> mActivityArray = (ArrayList<Object>)mActivityArrayField.get(manager);
                    if(mActivityArray != null){
                        for(Object record : mActivityArray){
                            final Field idField = record.getClass().getDeclaredField("id");
                            if(idField != null){
                                idField.setAccessible(true);
                                final String _id = (String)idField.get(record);
                                if(id.equals(_id)){
                                    mActivityArray.remove(record);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return true;
    }

    return false;
} 

并将其粘贴到以下行

          Window newWindow = manager.startActivity(lastId, lastIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));

并且在开始活动时不添加任何标记。并且您也可以参考此链接以获取更多信息destroyActivity() Bug in LocalActivityManager class in Android issue

这对我来说很好。