Дублирование фрагментов на транзакции фрагментов
Хорошо, всякий раз, когда я пытаюсь заменить фрагмент в моем приложении, он только добавляет фрагмент внутри контейнера, другой фрагмент, и оставляет текущий фрагмент. Я попытался вызвать замену и ссылку на представление, содержащий фрагмент, и путем ссылки на сам фрагмент. Ни один из них не работает. Я могу добавить фрагмент в представление с помощью диспетчера транзакций фрагмента, но даже если я попытаюсь удалить его после его добавления, это не сработает. Любая помощь будет оценена по достоинству. Вот мои файлы.
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();
}