Дублирование фрагментов на транзакции фрагментов

Хорошо, всякий раз, когда я пытаюсь заменить фрагмент в моем приложении, он только добавляет фрагмент внутри контейнера, другой фрагмент, и оставляет текущий фрагмент. Я попытался вызвать замену и ссылку на представление, содержащий фрагмент, и путем ссылки на сам фрагмент. Ни один из них не работает. Я могу добавить фрагмент в представление с помощью диспетчера транзакций фрагмента, но даже если я попытаюсь удалить его после его добавления, это не сработает. Любая помощь будет оценена по достоинству. Вот мои файлы.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //Setup the actionabar. Use setDrawableBackground to set a background image for the actionbar.
    final ActionBar actionbar = getActionBar();
    actionbar.setDisplayShowTitleEnabled(false);
    actionbar.setDisplayUseLogoEnabled(true);
    actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionbar.addTab(actionbar.newTab().setText(R.string.home_tab_text).setTabListener(this),true);
    actionbar.addTab(actionbar.newTab().setText(R.string.insert_tab_text).setTabListener(this));

    Fragment fragment = new insert_button_frag();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    transaction.replace(R.id.button_fragment, fragment);
    transaction.addToBackStack(null);

    transaction.commit();
}

Вот макет

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

    <LinearLayout
        android:orientation="vertical"
        android:id="@+id/button_fragment_container"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <fragment
            android:name="com.bv.silveredittab.home_button_frag"
            android:id="@+id/button_fragment"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>

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

        <fragment
            android:name="com.bv.silveredittab.quick_insert_frag"
            android:id="@+id/quick_insert_frag"
            android:layout_width="350dip"
            android:layout_height="fill_parent" />

        <fragment
            android:name="com.bv.silveredittab.editor_frag"
            android:id="@+id/editor_frag"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

    </LinearLayout>

</LinearLayout>

И вот код фрагмента

public class insert_button_frag extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        return inflater.inflate(R.layout.insert_buttons,container, false);
    }
}

Как я уже сказал. Я попытался ссылаться на родительское представление фрагментов, чтобы заменить его, и сам фрагмент (по id), и все же он добавляет только новый фрагмент внутри содержащего представления, в котором находится исходный фрагмент.

Ответ 1

Я решил это, используя местозаполнитель в моем макете, а затем прикрепляю к нему фрагмент во время выполнения.

Как и вы, если бы я создал экземпляр своего фрагмента в моем макете xml, содержимое останется видимым после замены его другим фрагментом во время выполнения.

Ответ 2

Проблема заключается в этой строке:

transaction.replace(R.id.button_fragment, fragment);

replace имеет две перегруженные формы. В обоих из них первым аргументом является контейнер фрагмента, который нужно заменить, а не сам фрагмент. Итак, в вашем случае вам нужно позвонить

transaction.replace(R.id.button_fragment_container, fragment);

edit: Я вижу в вашем вопросе, что вы пробовали оба. Я проверил и проверил поведение. Это похоже на ошибку в API FragmentTransaction.

Edit2: не ошибка в конце концов. Вы просто не можете заменить фрагменты, добавленные статически в файл макета. Вы можете заменить только те, которые вы добавили программно (Android: нельзя заменить один фрагмент другим)

Ответ 3

У меня была такая же проблема. Взгляните на эту ссылку: Дублирование фрагментов Android

Интересно, является ли тот факт, что вы передаете контейнер в метод inflater.inflate(), заставляет его создавать новый фрагмент внутри старого вместо оптовой замены. Я предоставляю "null" моим надувным устройствам в рабочей версии.

Вот основные положения версии, с которыми я работаю...

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
   View newFrag = new View(getActivity().getApplicationContext());
   newFrag = inflater.inflate(R.id.frag, null);
   return newFrag;
}

Ответ 4

руководство для разработчиков Google довольно запутанно, потому что вначале он показывает, что в xml реализован фрагмент с жесткой кодировкой. Но если вы действительно хотите заменить существующий фрагмент на новый, тогда вы должны добавить его (первый) во время выполнения.

Что официальный сайт - это

FragmentTransaction replace (int containerViewId, фрагмент фрагмента, тег String)

Заменить существующий фрагмент, добавленный в контейнер. Это по сути то же самое, что и вызов remove (Fragment) для всех в настоящее время добавлены фрагменты, которые были добавлены с тем же контейнером, и затем add (int, Fragment, String) с теми же аргументами, которые приведены здесь.

Вы должны заметить, что в нем говорится, что Заменить существующий фрагмент, который был добавлен в контейнер

Итак, ваш xml должен выглядеть так: someActivity.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    tools:context="someActivity">

    <ImageView
        .../>

    <LinearLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="bottom"/>

</RelativeLayout>

А чем в вашей деятельности в OnCreate()

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        [...]
        getSupportFragmentManager().beginTransaction()
                .add(R.id.fragment_container, new FirstFragment).commit();

    }

Чем вы можете легко заменить фрагмент своей анимацией и событием, добавьте ее обратно в стек, чтобы сохранить его состояние.

private SecondFrag getSecondFrag(){
    if(secondFrag == null)
        secondFrag = new SecondFrag()
    return secondFrag;
}

private void openRechargeFragment(){
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setCustomAnimations(R.anim.show_frag, R.anim.hide_frag,
                R.anim.show_frag, R.anim.hide_frag);
        ft.replace(R.id.fragment_container, getSecondFrag(), "myTAG");
        ft.addToBackStack(null);
        ft.commit();
}