2012-03-28 4 views
7

У меня есть макет для ландшафтного режима, который показывает ListView слева и FrameLayout справа. Когда элемент выбран из списка другой фрагмент добавляется в FrameLayoutНе удается удалить фрагмент из FrameLayout?

MyFragment myFragment = (MyFragment) fragmentManager.findFragmentById(R.id.myFrameLayout); 
FragmentTransaction ft = fragmentManager.beginTransaction(); 
if (myFragment == null) { 
    myFragment = new MyFragment(uri); 
    ft.replace(R.id.myFrameLayout, playerFragment); 
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
    ft.commitAllowingStateLoss(); 
} 

Позже я нажимаю удалить, в списке и удалить последний элемент в списке, и я стараюсь, чтобы удалить фрагмент так, что ничего , но он не работает, мой фрагмент остается на экране. Код для удаления:

MyFragment myFragment = (MyFragment) fragmentManager.findFragmentById(R.id.myFrameLayout); 
FragmentTransaction ft = fragmentManager.beginTransaction(); 
ft.remove(myFragment); 
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE); 
ft.commitAllowingStateLoss(); 

Любые идеи, по которым он не удаляется из виду?

+3

У меня такая же проблема. Достигнута ли какая-либо резолюция? – Jared

ответ

3

Вы объявляете фрагмент в xml? Приводя Dianne Hackborn от Google:

Определение фрагментов в XML в основном предназначены для вещей, которые собираются остаться вокруг. Если вы добавили и удалили , вы должны, вероятно, последовательно делать это динамически.

надеюсь, что это помогает

+0

Я думаю, что он ссылается на использование тега в макете XML. Я не использую это, я использую FrameLayout в качестве заполнителя и динамически обновляю фрагмент, который помещается в него. Я мог бы попробовать использовать метод FragmentTransaction.hide(), который упоминался в потоке, на который вы ссылались. – DaveJohnston

+0

Ну, этот API просто плохой. Вы делаете простой вызов 'remove()', и самая простая вещь, которую вы ожидали от него, не работает. – milosmns

+0

Он работает для фрагментов, добавленных с явной транзакцией, сделанной вами, программно. – Blackbelt

0

Когда вы найти свой фрагмент с помощью Id вы получили ссылку на фрагмент контейнера не фрагментировать себя. Используйте TAG, когда вы addiing фрагмент, а затем найти с помощью TAG:

MyFragment myFragment = (MyFragment) fragmentManager.findFragmentByTag("yourTag"); 
11

@DaveJohnston Я попробовал ваш код фрагмента удалить я просто формуют .... спасибо :)

Эй я не знаю, что это это решение вашей проблемы или нет, но вы пытаетесь таким образом, он будет работать:

подход добавить фрагмент:

YourFragment yourFrament; 

//Add your Fragment 
public void addYourFragment(){ 
yourFragment = new YourFragment(); 

FragmentTransaction transation = getSupportFragmentManager().beginTransaction(); 
transation.replace(R.id.yourFlowLayout, yourFragment); 

     transation.commit(); 

} 

подход для удаления фрагмента:

//Remove Fragment 
    public void removeYourFragment(){ 
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
      if (yourFragment != null) {   
       transaction.remove(yourFragment); 
       transaction.commit(); 
       transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE); 
       yourFragment = null; 
      } 
    } 
+0

Что произойдет, если я напишу transaction.remove (null)? удалит ли он самый большой фрагмент в стеке? или что будет? –

0

У меня было очень трудно найти так ссылаться на этот вопрос, возникающего при НЕ настройке <fragment> с помощью XML, но на самом деле установка каждый Fragment динамически FragmentTransaction и <FrameLayout>.

Упрощение решения Gru, решение для меня было просто добавлением .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) к моей замене транзакции, и это сработало! Предыдущие фрагменты теперь фактически скрыты от просмотра.

Я думаю, что другие переходы будут работать.

0
private static String TAG_FRAGMENT="MyFragment"; 
MyFragment myFragment = (MyFragment) fragmentManager.findFragmentById(R.id.myFrameLayout); 
FragmentTransaction ft = fragmentManager.beginTransaction(); 
if (myFragment == null) { 
     myFragment = new MyFragment(uri); 
    ft.replace(R.id.myFrameLayout, playerFragment,TAG_FRAGMENT); 
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
    ft.addToBackStack(TAG_FRAGMENT); 
    ft.commit(); 
} 

при замене фрагмента использовать ft.addToBackStack(null) метод после того, как легко удалить свой фрагмент.

Fragment fragment = getSupportFragmentManager().findFragmentByTag(TAG_FRAGMENT); 

if(fragment != null) 
getSupportFragmentManager().beginTransaction().remove(fragment).commit(); 
0

Если у вас есть Fragment, который не удаляется при замене Fragment в FrameLayout? вы можете удалить его, совершив отдельный переход удаления с FragmentTransaction.TRANSIT_FRAGMENT_CLOSE на него перед вызовом обычной замены commit.

Fragment removeThisFragment;//Keep a reference to the fragment you want to remove 
... 
FragmentManager fragmentManager = getSupportFragmentManager(); 
FragmentTransaction transaction = fragmentManager.beginTransaction(); 

// This fragment "sometimes" do not get replaced so we remove it here if it's added. 
     if(removeThisFragment!=null&&removeThisFragment.isAdded()) { 
      transaction = fragmentManager.beginTransaction(); 
      transaction.remove(removeThisFragment); 
      transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE); 
      transaction.commitAllowingStateLoss(); 
     } 

     // update the main content by replacing fragments 
     transaction = fragmentManager.beginTransaction(); 
     transaction.replace(R.id.content_frame, fragment, TAG_MAIN_FRAGMENT).commit(); 

Но я предлагаю, чтобы попытаться выяснить, почему первый фрагмент не будет заменен в первую очередь, проверьте, если он делает некоторые тяжелую работу или что-то держать его от того, чтобы заменить ?? но если вам нужно быстрое временное исправление, попробуйте приведенный выше код.

Смежные вопросы