2013-09-04 33 views
5

Próbuję skonfigurować FragmentStatePagerAdapter, aby utworzyć przewijany interfejs karty na jednym z moich fragmentów podobnych do this example. W moja aktywność na onCreate:Wyjątek NullPointerException podczas wywoływania findViewById() w celu uzyskania widoku fragmentu

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.base); 

    setVersionString(); 
    setupActionBar(); 
    setupNavigationDrawer(); 
    setupFragments(); 
} 

ustawić widok treści do następnego układu (R.layout.base):

<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/drawer_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context=".BaseActivity" > 

    <!-- The main content view --> 
    <FrameLayout 
     android:id="@+id/main_frame" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 

    <!-- The navigation drawer --> 
    <ListView 
     android:id="@+id/nav_drawer" 
     android:layout_width="240dp" 
     android:layout_height="match_parent" 
     android:layout_gravity="start" 
     android:choiceMode="singleChoice" 
     android:divider="@android:color/transparent" 
     android:dividerHeight="0dp" 
     android:background="#FFF" /> 

</android.support.v4.widget.DrawerLayout> 

Następnie należy zadzwonić pod następujące funkcję:

private void setupFragments() { 
    // Check that the activity is using the correct layout 
    if (findViewById(R.id.main_frame) != null) { 
     // Initialize the first fragment 
     MainFragment firstFrag = new MainFragment(); 

     // Pass any extras from an intent to the Fragment 
     firstFrag.setArguments(getIntent().getExtras()); 

     // Add the first Fragment to the screen 
     getSupportFragmentManager().beginTransaction() 
      .add(R.id.main_frame, firstFrag).commit(); 

     tabsAdapter = firstFrag.getAdapter(); 
     Log.d("Base.LOG", "tabsAdapter = " + tabsAdapter); 
     tabsAdapter.addTab(DummyFragment.class, null); 
    } 
} 

w próbie ustaw FragmentStatePagerAdapter jako adapter dla widoku w układzie fragmentu (R.layout.main):

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

    <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="#33b5e5" 
     android:textColor="#fff" 
     android:paddingTop="4dp" 
     android:paddingBottom="4dp" /> 
</android.support.v4.view.ViewPager> 

i kod mojego fragment wygląda leżeć to:

private View mView; 
private TabbedPagerAdapter mTabPageAdapter; 
private ViewPager mTabPager; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    Log.d("Main.LOG", "onCreate called"); 
    mView = inflater.inflate(R.layout.main, container, false); 
    Log.d("Main.LOG", "Layout inflated"); 
    setupTabs(); 
    Log.d("Main.LOG", "Tabs setup"); 

    return mView; 
} 

@Override 
public void onResume() { 
    super.onResume(); 
    Log.d("Main.LOG", "onResume called"); 
} 

/** Set up the ViewPager and Adapter to handle the primary tabs */ 
private void setupTabs() { 
    // Initialize the adapter 
    mTabPageAdapter = new TabbedPagerAdapter(getActivity(), 
      getActivity().getSupportFragmentManager()); 

    // Initialize the view pager 
    mTabPager = (ViewPager) mView.findViewById(R.id.main_page); 
    Log.d("Main.LOG", "mTabPager = " + mTabPager); 
    Log.d("Main.LOG", "mTabPageAdapter = " + mTabPageAdapter); 
    mTabPager.setAdapter(mTabPageAdapter); 
} 

/* Accessor for TabbedPagerAdapter */ 
public TabbedPagerAdapter getAdapter() { 
    return mTabPageAdapter; 
} 

Aplikacja siła zamyka się, gdy próbuję dodać kartę z NullPointerException. Komunikaty debugowania w show dziennika: Wyświetlany tabsAdapter = null

zanim którykolwiek z komunikatów debugowania fragment za:

D/Base.LOG (27173). Jak mogę się upewnić, że układ jest zawyżony przed próbą uzyskania dostępu do jego widoków lub podklas?

+0

Czy możesz pokazać xml dla R.layout.main? również jeśli chcesz się dowiedzieć, czy coś się dzieje, napompuj, po prostu umieść onResume w fragmencie i sprawdź, czy inflacja jest zrobiona, ponieważ onResume będzie zawsze wywoływany po onCreateView – Raigex

+0

@Raigex To jest drugi. Zmodyfikowałem, aby uwzględnić, który jest który. Co sugerujesz zrobić w metodzie onResume? –

+0

Nic tak naprawdę, ale możesz skorzystać z metody wznowienia, aby sprawdzić, czy została ona zawyżona (np. FragView! = Null), a następnie możesz ją zarejestrować i zawęzić problem. – Raigex

Odpowiedz

2

Jak na mój komentarz

public class MainFragment extends Fragment 
{ 
    private MainInterface mInterface = null; 
    //make sure to set the above somehow 

    public interface MainInterface{ 
     public void onFragmentReady(.....); 
    } 

    ... //Do regular stuff here 

    public void onResume() 
    { 
     //Do what you need to do in onResume 
     if(mInterface != null) 
     { 
      mInteface.onFragmentReady(); 
     } 
    } 
} 

Powinno to umożliwić, aby wiedzieć, kiedy fragment jest gotowy i można zrobić getTabAdapter wymaga czasu.

1

Czy dzwonisz pod numer setContentView(...) w ramach metody swojej aktywności, zanim zadzwonisz pod numer setupFragments(...)?

Jeśli tak: Czy układ przypisany do działania zawiera ViewPager?

Moja rekomendacja: Ponieważ są oczywiście używając ViewPager wewnątrz fragmentu zrobić inicjalizacji ViewPager wewnątrz Fragmenty onCreateView(...) metody.

Przykład:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

    // ASSUMING your layout.main contains the ViewPager 
    View v = inflater.inflate(R.layout.main, container, false); 

    ViewPager pager = (ViewPager) v.findViewById(R.id.pager); 
    // and so on ... 

    return v; 
} 
+0

Nie, nie jestem, zobacz edycję. Myślałem, że został wywołany przez konstruktora. Czy muszę sam wywołać tę metodę? Myślałem o inicjalizacji 'ViewPager' wewnątrz fragmentu. Ale chciałbym móc dodawać zakładki z głównego działania. Jak mogę uzyskać adapter do metody 'onCreateView'? –

+0

Możesz także zarządzać zakładkami z Fragmentu. Co masz na myśli, mówiąc o tym, jak zdobyć adapter? Dokładnie w taki sam sposób, jak w działaniu. Zauważ również, że klasa Fragment posiada metodę getActivity(). –

+0

Początkowo myślałem, że będę musiał przekazać fragmenty tabulatorów z głównego działania do głównego fragmentu adapterowi, co wydaje się być kłopotliwe. Moja nowa myśl polega na stworzeniu metody 'getAdapter', która zwróci adapter do głównego działania, dzięki czemu będę mógł dodawać karty z tego miejsca. Ale spójrz na moją edycję. Wziąłem twoją radę i dodałem kilka komunikatów debugowania, jak sugeruje Raigex, do dziennika i wygląda na to, że 'onCreateView' nigdy nie jest w ogóle wywoływany. –

Powiązane problemy