启动一个活动并保留TabHost

时间:2015-04-24 10:47:13

标签: android android-tabhost

我完成了一个Android应用,其中导航属于TabHost。在第一个Activity中我有一个按钮,允许我显示我的TabHost的第3个Activity。 所以在第一个Activity中我编写了以下代码:

public class HomeActivity extends Activity implements View.OnClickListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        ImageButton buttonRanking = (ImageButton)findViewById(R.id.imageButton);
        buttonRanking.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        Intent intent = new Intent(this, RankingActivity.class);
        startActivity(intent);
    }
}

当我尝试运行应用程序并按下调用方法onClick的按钮时,它会显示正确的活动,但TabHost会隐藏。按下按钮后如何保持TabHost? 我在网上发现了使用ActivityGroup的可能解决方案,但我不知道它是如何工作的,我不知道这是正确的方法。 你能救我吗?

4 个答案:

答案 0 :(得分:0)

当您点击在新实例中打开活动的按钮时,该实例现在不是tabhost的一部分。

而不是启动活动,您应该更改按钮上的选项卡,如下所示。

tabHost.setCurrentTab(的tabIndex);

答案 1 :(得分:0)

请勿使用Activity来托管您的屏幕。请改用Fragment。自API 13以来ActivityGroup已被弃用。当您致电startActivity()时,当前的Activity会暂停并停止,新的Activity会启动并进入运行状态。由于您的TabHost位于第一个View的{​​{1}}层次结构中,因此它将不再可见。

答案 2 :(得分:0)

在页面包含Navigation Drawer和TabHost的情况下,您必须在FragmentActivity下开发它,这是tabhost.xml的setContentView

公共类AppMainTabActivity扩展了FragmentActivity {     / *你的标签主持人* /

private TabHost mTabHost;
public PopupMenu popupMenu;


/* A HashMap of stacks, where we use tab identifier as keys.. */
private HashMap<String, Stack<Fragment>> mStacks;

/* Save current tabs identifier in this.. */
private String mCurrentTab;



protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.tabhost);


    mStacks = new HashMap<String, Stack<Fragment>>();
    mStacks.put("TAB1", new Stack<Fragment>());
    mStacks.put("TAB2", new Stack<Fragment>());
    mStacks.put("TAB3", new Stack<Fragment>());

    mTabHost = (TabHost) findViewById(android.R.id.tabhost);

    mTabHost.setup();
    mTabHost.setOnTabChangedListener(listener);
    initializeTabs();

}

private View createTabView(int a) {
    View view = LayoutInflater.from(this).inflate(R.layout.tab_indicator,null);
    RelativeLayout rl = (RelativeLayout) view.findViewById(R.id.rl_snehasis);
    ImageView imageView = (ImageView) view.findViewById(R.id.img_tringle);
    TextView textView = (TextView) view.findViewById(R.id.title);
    textView.setTextColor(Color.WHITE);
    if (a == 1)
        textView.setText("TAB1");
    else if (a == 2)
        textView.setText("TAB2");
    else if (a == 3)
        textView.setText("TAB3");

    return view;

}

public void initializeTabs() {
    /* Setup your tab icons and content views.. Nothing special in this.. */
    TabHost.TabSpec spec = mTabHost.newTabSpec("TAB1");
    mTabHost.setCurrentTab(-3);
    spec.setContent(new TabHost.TabContentFactory() {
        public View createTabContent(String tag) {
            return findViewById(R.id.realtabcontent);
        }
    });
    spec.setIndicator(createTabView(1));
    mTabHost.addTab(spec);

    spec = mTabHost.newTabSpec("TAB2");
    spec.setContent(new TabHost.TabContentFactory() {
        public View createTabContent(String tag) {

            return findViewById(R.id.realtabcontent);
        }
    });
    spec.setIndicator(createTabView(2));
    mTabHost.addTab(spec);

    spec = mTabHost.newTabSpec("TAB3");
    spec.setContent(new TabHost.TabContentFactory() {
        public View createTabContent(String tag) {
            return findViewById(R.id.realtabcontent);
        }
    });
    spec.setIndicator(createTabView(3));
    mTabHost.addTab(spec);

}

/* Comes here when user switch tab, or we do programmatically */
TabHost.OnTabChangeListener listener = new TabHost.OnTabChangeListener() {
    public void onTabChanged(String tabId) {
        /* Set current tab.. */
        mCurrentTab = tabId;

        for (int i = 0; i < mTabHost.getTabWidget().getChildCount(); i++) {


            View view = mTabHost.getTabWidget().getChildAt(i);
            view.setBackgroundColor(Color.parseColor("#a9a5a6")); 
        }

        View view_selected = mTabHost.getTabWidget().getChildAt(
                mTabHost.getCurrentTab());
        view_selected.setBackgroundColor(Color.parseColor("#17324f")); 
        if (mStacks.get(tabId).size() == 0) {
            /*
             * First time this tab is selected. So add first fragment of
             * that tab. Dont need animation, so that argument is false. We
             * are adding a new fragment which is not present in stack. So
             * add to stack is true.
             */
            if (tabId.equals("TAB1") {
                pushFragments(tabId, new T1_A(), false, true);
            } else if (tabId.equals("TAB2")) {
                pushFragments(tabId, new T2_A(), false, true);
            } else if (tabId.equals("TAB3")) {
                pushFragments(tabId, new T3_A(), false, true);
            }
        } else {
            /*
             * We are switching tabs, and target tab is already has atleast
             * one fragment. No need of animation, no need of stack pushing.
             * Just show the target fragment
             */
            pushFragments(tabId, mStacks.get(tabId).lastElement(), false,
                    false);
        }
    }

};

/*
 * Might be useful if we want to switch tab programmatically, from inside
 * any of the fragment.
 */
public void setCurrentTab(int val) {
    mTabHost.setCurrentTab(val);
}

/*
 * To add fragment to a tab. tag -> Tab identifier fragment -> Fragment to
 * show, in tab ident ified by tag shouldAnimate -> should animate
 * transaction. false when we switch tabs, or adding first fragment to a tab
 * true when when we are pushing more fragment into navigation stack.
 * shouldAdd -> Should add to fragment navigation stack (mStacks.get(tag)).
 * false when we are switching tabs (except for the first time) true in all
 * other cases.
 */
public void pushFragments(String tag, Fragment fragment,
        boolean shouldAnimate, boolean shouldAdd) {
    if (shouldAdd)
        mStacks.get(tag).push(fragment);
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction ft = manager.beginTransaction();
    if (shouldAnimate)
        ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left);
    ft.replace(R.id.realtabcontent, fragment);
    ft.commit();
}

public void popFragments() {
    /*
     * Select the second last fragment in current tab's stack.. which will
     * be shown after the fragment transaction given below
     */
    Fragment fragment = mStacks.get(mCurrentTab).elementAt(
            mStacks.get(mCurrentTab).size() - 2);

    /* pop current fragment from stack.. */
    mStacks.get(mCurrentTab).pop();

    /*
     * We have the target fragment in hand.. Just show it.. Show a standard
     * navigation animation
     */
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction ft = manager.beginTransaction();
    ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);

    ft.replace(R.id.realtabcontent, fragment);
    ft.commit();
}

@Override
public void onBackPressed() {
    if (((BaseFragment) mStacks.get(mCurrentTab).lastElement())
            .onBackPressed() == false) {
        /*
         * top fragment in current tab doesn't handles back press, we can do
         * our thing, which is
         * 
         * if current tab has only one fragment in stack, ie first fragment
         * is showing for this tab. finish the activity else pop to previous
         * fragment in stack for the same tab
         */
        if (mStacks.get(mCurrentTab).size() == 1) {
            super.onBackPressed();
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_HOME);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);// or call finish..
        } else {
            popFragments();
        }
    } else {
        // do nothing.. fragment already handled back button press.
    }
}

/*
 * Imagine if you wanted to get an image selected using ImagePicker intent
 * to the fragment. Ofcourse I could have created a public function in that
 * fragment, and called it from the activity. But couldn't resist myself.
 */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (mStacks.get(mCurrentTab).size() == 0) {
        return;
    }

}

tabhost.xml

<?xml version="1.0" encoding="utf-8"?>
<TabHost
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0"/>

        <FrameLayout
            android:id="@+android:id/realtabcontent"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>

        <TabWidget
            android:id="@android:id/tabs"
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="55dip"
            android:layout_weight="0"/>

    </LinearLayout>
</TabHost>

现在从Fragment扩展类BaseFragment,所有添加的类将在相同的FragmentActivity下处理

BaseFragment.java

public class BaseFragment extends Fragment {
    public static AppMainTabActivity mActivity;

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

        mActivity = (AppMainTabActivity) this.getActivity();
    }
public boolean onBackPressed() {
        return false;
    }
}

现在生成T1_A.java,T1_B.java ....所有都在TAB1下,类似T2_A.java,T2_B.java ....(对于TAB2),T3_A.java,T3_B.java .. ..(对于TAB3) T1_A.java

public class T1_A extends BaseFragment{
        @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

     View view = inflater.inflate(R.layout.test, container, false);

Button btn=(Button)view.findViewById(R.id.btn);

btn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                mActivity.pushFragments("TAB1",
                        new T1_B(), true, true);
            }
        });
     return view;
}

}

答案 3 :(得分:0)

我用这种方式解决了我的问题:

 @Override
public void onClick(View v) {
    MainActivity mainActivity = new MainActivity();
    TabHost tabHost = mainActivity.getTabHost();
    tabHost.setCurrentTab(2);
}

我在MainActivity中添加了方法getTabHost(),它为我提供了tabHost实例,所以我在我的HomeActivity中获得了tabHost实例,我只是按照Basant Kumar的建议,现在它和& #39;工作正常。