片段事务后片段在活动的布局中不可见。

时间:2014-12-04 15:04:06

标签: android android-layout android-fragments transactions android-viewpager

我有一个

public class MainFragmentActivity extends SherlockFragmentActivity implements  ActionBar.TabListener

包含FragmentPagerAdapter中的多个选项卡。在这个应用程序中,你可以有0,1或几只宠物。如果你有0只宠物,其中一个标签包含一个只包含信息文本的片段。如果您有1只宠物,则选项卡包含一个包含相关信息的片段,并使用保存按钮更新操作栏。如果您有多只宠物,则标签包含相同的片段,就像您有0只宠物一样,但操作栏包含一个子菜单,您可以在其中选择其中一只宠物。当您选择一个片段事务时,片段事务将更改为相同的片段,就像您只有一只宠物一样。片段事务还应使用保存按钮更新操作栏。

当我有0或1只宠物时,两种不同的碎片可以正常工作。该问题仅发生在片段事务之后。

以下是我进行片段事务时会发生的事情:

  1. 当前片段正在被销毁和分离。

  2. 附加新片段。运行onCreate(),onCreateView(),onResume,onCreateOptionsMenu()。操作栏菜单按原样更新,但选项卡为空。当我在第二个片段上运行isInLayout()时,它返回false,但是当我在其他(可见)片段上运行该方法时也会发生这种情况。

  3. 在第二个片段中的onResume()中,方法isVisible(),isMenuVisible(),isAdded()都返回true。 isHidden()返回false。

    由于新/第二个片段中的代码运行应该如此,我认为片段事务是否正常?我试图在MainFragmentActivity中的FragmentPagerAdapter上运行notifyDataSetChanged()而没有结果。

    在MainFragmentActivity中我使用以下导入(以及更多但与问题无关):

    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentPagerAdapter;
    import android.support.v4.app.FragmentTransaction;
    import android.support.v4.view.ViewPager;
    import com.actionbarsherlock.app.ActionBar;
    import com.actionbarsherlock.app.ActionBar.Tab;
    import com.actionbarsherlock.app.SherlockFragment;
    import com.actionbarsherlock.app.SherlockFragmentActivity;
    import com.actionbarsherlock.view.Menu;
    import com.actionbarsherlock.view.MenuItem;
    

    在片段中我使用以下导入:

    import com.actionbarsherlock.app.SherlockFragment;
    import com.actionbarsherlock.view.Menu;
    import com.actionbarsherlock.view.SubMenu;
    import com.actionbarsherlock.view.MenuInflater;
    import com.actionbarsherlock.view.MenuItem;
    

    如您所见,我将v4支持与ActionBarSherlock结合使用。这还没有成为问题。

    这是交易的样子:

    FragmentTransaction transaction = this.getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.pager, secondFragment);
    transaction.commit();
    

    我也试过

    getFragmentManager().beginTransaction().replace(R.id.pager, secondFragment).commit();
    

    具有相同的结果。

    以下是MainFragmentActivitys布局的外观:

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>        
    
    </LinearLayout>
    

    我当然搜索过但未能在此处找到任何其他类似问题。请帮忙,如何强制将片段添加到Main的布局?

1 个答案:

答案 0 :(得分:0)

好的,很久以前我做过类似的事情(我想)。深入研究我的代码,看起来好像我也遇到过麻烦。

我发现我没有将其他片段添加到Viewpager布局,而是使用此布局添加到父R.id.details

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/details"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Turios" >

    <android.support.v4.view.ViewPager
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/display_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <android.support.v4.view.PagerTitleStrip
            android:id="@+id/pager_title_strip"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:background="#333"
            android:paddingBottom="4dp"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:paddingTop="4dp"
            android:textColor="#fff" >
        </android.support.v4.view.PagerTitleStrip>
    </android.support.v4.view.ViewPager>


</FrameLayout>

以下是我最终用来处理标签选择的代码。

@Override
public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) {
    int position = tab.getPosition();
    FragmentTransaction t = fm.beginTransaction();

    ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left);

    if (position == DisplayFragment.NAVIGATION_INDEX) {

        if (!device.isMultiPane() && mapsFragment != null
                && mapsOptionsFragment != null) {
            t.detach(mapsFragment);
            t.detach(mapsOptionsFragment);
        }

        if (browserFragment != null) {
            t.detach(browserFragment);
        }

    }

    if (position == GoogleMapFragment.NAVIGATION_INDEX) {

        t = addMapFragment(t);

    }
    if (position == BrowserFragment.NAVIGATION_INDEX) {
        if (browserFragment == null) {
            browserFragment = new BrowserFragment();
            t.add(R.id.details, browserFragment,
                    Turios.FRAGMENT_BROWSER_TAG);
        } else {
            t.attach(browserFragment);
        }
    }

    t.commit();

}

@Override
public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {
    int position = tab.getPosition();
    FragmentTransaction t = fm.beginTransaction();

    if (position == GoogleMapFragment.NAVIGATION_INDEX) {
        if (mapsFragment.isVisible() && mapsOptionsFragment.isVisible()) {
            t.detach(mapsFragment);
            t.detach(mapsOptionsFragment);
        }
    }
    if (position == BrowserFragment.NAVIGATION_INDEX) {
        if (browserFragment.isVisible()) {
            t.detach(browserFragment);
        }
    }
    t.commitAllowingStateLoss();
}

@Override
public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {
}

private FragmentTransaction addMapFragment(FragmentTransaction ft) {
    if (mapsFragment == null) {
        AddressHolder address = (device.isMultiPane()) ? null
                : getSelectedAddressHolder();
        mapsFragment = GoogleMapFragment.newInstance(address);
        ft.add(R.id.details, mapsFragment, Turios.FRAGMENT_MAP_TAG);

        mapsOptionsFragment = new GoogleMapOptionsFragment();
        ft.add(R.id.details, mapsOptionsFragment, FRAGMENT_MAP_OPTIONS_TAG);
    } else {
        ft.attach(mapsFragment);
        ft.attach(mapsOptionsFragment);
    }
    return ft;
}

所以我将我的片段作为公共变量引用并根据需要手动附加/分离。要处理方向更改,还原片段,我在onCreate

    if (savedInstanceState != null) {

        Log.i(TAG, "savedInstanceState not null");

        // restore fragments
        browserFragment = (BrowserFragment) fm
                .findFragmentByTag(FRAGMENT_BROWSER_TAG);
        mapsFragment = (GoogleMapFragment) fm
                .findFragmentByTag(FRAGMENT_MAP_TAG);

        mapsOptionsFragment = (GoogleMapOptionsFragment) fm
                .findFragmentByTag(FRAGMENT_MAP_OPTIONS_TAG);
    }
    ...

我希望这会对你有所帮助。如果有的话,它指的是它并不像人们想象的那么简单。