【问题标题】:Android how to interact with Fragment tabsAndroid 如何与 Fragment 选项卡进行交互
【发布时间】:2011-11-09 01:32:14
【问题描述】:

您好,我在更改片段活动的视觉视图时遇到了困难。我创建了所有选项卡,但 onClick 我不知道如何将活动传递到该空白区域。

所以它的结构是一个名为Main 的简单活动,它只是将内容视图设置为maintabholder.xml 文档,该文档包含片段视图,该片段视图连接到名为MainNav 的类,其内容视图包含位于底部。

maintabholder.xml:

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>

<include layout="@layout/header" android:layout_alignParentTop="true"           android:id="@+id/headerArea"></include>
<fragment
    class="my.package.name.MainNav"
    android:id="@+id/fragment_tabs"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />
</LinearLayout>

MainNav.java code snippet:

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) 
{
    mRoot = inflater.inflate(R.layout.fragment_tabs, null);
    mTabHost = (TabHost) mRoot.findViewById(android.R.id.tabhost);
    setupTabs();
    return mRoot;
}

和 R.layout.fragment_tabs:

<?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"
android:background="#EFEFEF">

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

    <TabWidget
        android:id="@android:id/tabs"
        android:layout_alignParentBottom="true"
        android:layout_width="fill_parent"
        android:background="@drawable/tab_background"
        android:gravity="center_horizontal"
        android:layout_height="wrap_content" >
    </TabWidget>

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            
            android:layout_height="wrap_content">

            <FrameLayout
                android:id="@+id/tab_1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <FrameLayout
                android:id="@+id/tab_2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
             <FrameLayout
                android:id="@+id/tab_3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
              <FrameLayout
                android:id="@+id/tab_4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
               <FrameLayout
                android:id="@+id/tab_5"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

        </FrameLayout>
</RelativeLayout>

最后是我想要加载到 Fragment 的 Activity 的内容(按下 tab1 按钮后)

 public class HomeFragment extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.home);
    
    }
 }

那是为了帮助你了解事情的要点,但问题出现在 MainNav.java 中:

  @Override
   public void onTabChanged(String tabId) {
        Log.d(TAG, "onTabChanged(): tabId=" + tabId);
        if (TAB_HOME.equals(tabId)) {
            updateTab(tabId, R.id.tab_1);
            mCurrentTab = 0;
            return;
        }
   }

当一个标签被点击时,它被注册到onTabChanged活动中,并调用updateTab函数:

   private void updateTab(String tabId, int placeholder) {
        FragmentManager fm = getFragmentManager();
        if (fm.findFragmentByTag(tabId) == null) {
            //fm.beginTransaction()
             //      .replace(placeholder, /*need fragment object here*/ , tabId)
             //       .commit();
            //
        }
}

注释掉的replace 方法正在寻找(int, fragment, string),我想它应该会为我更改空白。

但我不明白我从哪里得到片段对象!这个幻像对象需要以某种方式包含我的 HomeFragment 的 xml 布局,并允许我与我为 HomeFragment 活动编写的所有其他内容进行交互。

我的第一个预感是我的HomeFragment 活动需要extend FragmentActivity 只是活动。但这就是我碰壁的地方。

关于兼容性包方法的文档很少,但是 TabActivity 的文档说不再使用 TabActivity,所以我在这里。为 Android 2.2+ 开发

感谢您的洞察力。

【问题讨论】:

    标签: android tabs android-fragments tabactivity


    【解决方案1】:

    您不能将活动放入片段中,就这么简单。您必须将提供选项卡内容的活动转换为片段。考虑到您不在这些活动中使用片段,这应该不是问题。

    所以这里有两条规则要遵循:

    1. 您不能将活动放入片段中。
    2. 您不能将 Fragments 放入 Fragments。

    我建议您将底部片段保留在布局中,以处理选项卡小部件中的选项卡开关。如果发生选项卡切换,则将其报告给父 Activity,父 Activity 会将相应的 Fragment 加载到选项卡片段上方的区域中。为此,您必须修改布局,使其在选项卡片段上方和标题下方有一个 ViewGroup。您可以将带有选项卡内容的片段动态加载到该 ViewGroup 中。

    这是布局(maintabholder.xml):

    <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    
    <include layout="@layout/header" android:layout_alignParentTop="true"           android:id="@+id/headerArea"></include>
    
    <FrameLayout android:id="@+id/TabContent"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1"/>
    
    <fragment
        class="my.package.name.MainNav"
        android:id="@+id/fragment_tabs"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    </LinearLayout>
    

    当您的底部片段中发生选项卡切换时,您将其告知父 Activity:

    ...
    (YourActivity)getActivity().switchToTab(tabId);
    ...
    

    在 YourActivity 中:

    ...
    public void switchToTab(int tabId){
        switch(tabId){
        ...
        case 2:
            getSupportFragmentManager().beginTransaction().replace(R.id.TabContent, TabContentFragment2.newInstance(), "someTag").commit().
        break;
        ...
        }
    }
    

    类似的东西。

    【讨论】:

    • 这很有帮助!我拥有的一件事是我的一项活动包含谷歌地图。所以它必须扩展 MapActivity 。如果我将该活动更改为 FragmentActivity 那么它会崩溃并出现明显的错误 "mapview can only be called from MapActivity" ,这对我和这个片段结构来说都是一个问题,除非我创建了某种混合 MapFragmentActivity .....
    • 考虑使用这个库 github.com/petedoyle/android-support-v4-googlemaps 。虽然我没有任何经验,但它可能会起作用。
    • @ZsomborErdődy-Nagy - 您推荐了支持库,但同时声明片段不能在片段中,这不再是真的。支持库曾经对此存在一些问题,但自 v11 以来,在您发布的某个时间发布,提供了嵌套片段的配置,并带有一些稍微特定的逻辑来支持它(getChildFragmentManager)。因此,对于找到此线程的其他任何人,活动可能不在片段中,但片段现在可能在片段中。
    猜你喜欢
    • 2023-04-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多