2013-06-02 14 views
14

Próbuję używać fragmentów Androida w bardzo prosty sposób, podobnie jak samouczek na stronie programisty Androida.Fragment Androida otrzymuje pusty kontener w onCreateView()

Mam Aktywny (MediaInfoActivity) z następującego kodu:

public class MediaInfoActivity extends FragmentActivity { 
    private final String TAG = "MediaInfoActivity"; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Log.i(TAG, "onCreate()"); 
     setContentView(R.layout.media_info_activity_layout); 
    } 

} 

Oto kod dla pliku media_info_activity_layout.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <fragment class="com.hawkforce.test.MediaInfoFragment" 
      android:id="@+id/mediaInfoFragment" 
      android:layout_weight="1" 
      android:layout_width="match_parent" 
      android:layout_height="0dp" /> 

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

    <fragment class="com.hawkforce.test.MediaPlayerBarFragment" 
       android:id="@+id/mediaPlayerBar" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" /> 

    </FrameLayout> 

I wreszcie jest tutaj kod dla MediaInfoFragment:

public class MediaInfoFragment extends Fragment { 
    private final static String TAG = "MediaInfoFragment"; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Log.i(TAG, "onCreate()"); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     Log.i(TAG, "onCreateView()"); 
     if (container == null) { 
      Log.i(TAG, "onCreateView(): container = null"); 
     } 

     return inflater.inflate(R.layout.media_info_fragment_layout, container, false); 
    } 

} 

Oto mój problem: kontener przekazany w metodzie onCreateView() MediaInfoFragment ma wartość null. Jak zrozumiałem, powinno tak być tylko w przypadku fragmentów innych niż UI. Jednak mój Fragment posiada interfejs użytkownika, który wyświetla się OK na ekranie po uruchomieniu MediaInfoActivity. Powoduje problemy, ponieważ nie zastosowano stylu zadeklarowanego w pliku układu XML tego fragmentu.

Oto moja Log:

I/MediaInfoActivity: onCreate() 
I/MediaInfoFragment: onCreate() 
I/MediaInfoFragment: onCreateView() 
I/MediaInfoFragment: onCreateView(): container = null 

Am I brakuje czegoś oczywiste tutaj?

+0

Używasz wartości false, co oznacza, że ​​nie jest ona dołączona do kontenera. –

+0

Masz na myśli w nadmuchiwaczu, prawda? Zmieniłem go na prawdziwy, ale nie było żadnej zmiany. Plus ten wiersz: 'onCreateView(): container = null' jest wyświetlany przed wywołaniem nadmuchiwacza. Mój problem polega na tym, że Android przekazuje wartość null jako drugi argument metody onCreateView() i nie rozumiem, skąd to pochodzi. – HawkForce

+0

- http://stackoverflow.com/questions/27306805/android-fragment-oncreateview-container-is-null - http://stackoverflow.com/questions/24589202/android-fragments-container-variable-in- oncreateview-is-null – pRaNaY

Odpowiedz

2

nie jestem pewien, ponieważ nie mam kod SDK przede mną, ale myślę, że cykl życia nazywając Fragment „onCreateView” funkcja różni się między tymi dwoma przypadkami: 1. Statyczne ustawienia fragmentu w układzie 2. Ładowanie pragmatycznie z FragmentManager.

W pierwszym przypadku debugger dostać się Fragment.onCreateView() metody natychmiast po dodaniu zawartość widoku z działalnością dominującą w ramach onCreate() kodu:

Dzwoniąc: setContentView (R.layout.some_layoue); Zobaczysz debugger dostać się Fragment.onCreateView() przed przejściem do następnego wiersza

W drugim przypadku Fragment.onCreateView() powołano się dopiero po onCreate() z aktywność została zakończona.

Wygląda to jak błąd w projekcie dla mnie, ale prawdopodobnie jako cecha projektu. W każdym razie kontener ma wartość null podczas dodawania fragmentu statycznie, ponieważ obiekt pokrewny nie został jeszcze utworzony.

W rzeczywistości różnica między tymi dwiema sytuacjami jest znacznie większa. W przypadku fragmentów statycznych przechodzenie między fragmentami nie utworzy poprawnie hierarchii widoków.

Na przykład, jeśli doda przycisk-A do fragmentu A i okrągłą B fragmentowi-B i przełączyć fragmenty z kodem wygląda następująco (podkreślając tylko odpowiedni kod):

public void turnOnFragment() { 
    FragmentManager manager = getFragmentManager(); 
    if (manager != null) { 
     manager.beginTransaction() 
       .setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out) 
       .attach(this) 
       .commit(); 
    } 
} 



public void turnOffFragment() { 
    FragmentManager manager = getFragmentManager(); 
    if (manager != null) { 
     manager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); 
     manager.beginTransaction() 
       .setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out) 
       .detach(this) 
       .commit(); 


    } 
} 

Ty zobaczymy, że w przypadku fragmentów statycznych wyświetlane są przyciski z obu fragmentów, chociaż są włączane i wyłączane. Jeśli jednak fragmenty są dodawane programowo, przełącznik działa dobrze, a hierarchia widoku jest czyszczona i wyświetla tylko przycisk z odpowiedniego fragmentu.

ta jest oparta na moim doświadczeniu z wersją 4.4.2

3

Trzeba tylko stworzyć inflater jak mieszka w swoim fragmentem.

View rootView; 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    if (rootView == null) { 
     rootView = inflater.inflate(R.layout.activity_my_cart, null); 
    } else { 
     ((ViewGroup) container.getParent()).removeView(rootView); 
    } 
    return rootView; 
} 

Mam nadzieję, że zadziała jak na twoje pytanie.

Powiązane problemy