2013-09-29 27 views
36

Czy ktoś może mi pomóc, aby dowiedzieć się, jaki może być problem z tym programem. W metodzie findViewById() zwraca wartość null dla wszystkich identyfikatorów i powoduje to wyjątek wskaźnika pustego później. Nie mogę zrozumieć, dlaczego findViewById() nie może znaleźć widoku. Jakieś sugestie?Wskaźnik zerowy Wyjątek - findViewById()

Jest to kod główny:

public class MainActivity extends Activity { 

    ViewPager pager; 
    MyPagerAdapter adapter; 
    LinearLayout layout1, layout2, layout3; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     layout1 = (LinearLayout) findViewById(R.id.first_View); 
     layout2 = (LinearLayout) findViewById(R.id.second_View); 
     layout3 = (LinearLayout) findViewById(R.id.third_View); 

     adapter = new MyPagerAdapter(); 
     pager = (ViewPager) findViewById(R.id.main_pager); 
     pager.setAdapter(adapter); 
    } 

    private class MyPagerAdapter extends PagerAdapter 
    { 

     @Override 
     public int getCount() { 
      return 3; 
     } 

     @Override 
     public Object instantiateItem(ViewGroup collection, int position) { 

      LinearLayout l = null; 

      if (position == 0) 
      { 
       l = layout1; 
      } 
      if (position == 1) 
      { 
       l = layout2; 
      } 

      if (position == 2) 
      { 
       l = layout3; 
      } 
       collection.addView(l, position); 
       return l; 
     } 

     @Override 
     public boolean isViewFromObject(View view, Object object) { 
      return (view==object); 
     } 

     @Override 
     public void destroyItem(ViewGroup collection, int position, Object view) { 
       collection.removeView((View) view); 
     } 
    } 
} 

A powiązanych plików XML:

activity_main układ:

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


    <android.support.v4.view.ViewPager 
         android:layout_width="match_parent" 
         android:layout_height="match_parent" 
         android:id="@+id/main_pager"/> 
</LinearLayout> 

activity_first układ:

<?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:id="@+id/first_View"> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/hello_world" /> 

<Button 
    android:id="@+id/button1" 
    style="?android:attr/buttonStyleSmall" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Button" /> 

</LinearLayout> 

activity_second l ayout:

<?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:id="@+id/second_View"> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/hello_world" /> 

</LinearLayout> 

A activity_third układ:

<?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:id="@+id/third_View"> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/hello_world" /> 

</LinearLayout> 

Odpowiedz

63

findViewById() zwraca View jeśli istnieje w układzie podany w setContentView(), w przeciwnym razie zwraca wartość null i to, co się z tobą dzieje.

Przykład, jeśli wyłączysz setContentView(R.layout.activity_first);, a następnie zadzwonisz pod numer findViewById(R.id.first_View);, zwróci on widok, który jest twoim układem.

Ale jeśli zadzwonisz findViewById(R.id.second_View); powróci null ponieważ nie jest widok w układzie activity_first.xml nazywa @+id/second_View.

+0

Dołączyłem wszystkie układy do głównego układu i nie mam już wyjątku wskaźnika pustego. Dzięki za wskazówkę. – user2629828

+3

Gdy użyłem tego w innym widoku niż aktualnie wyświetlany widok, ten pojawił się. Aby pozbyć się tego niechcianego zachowania, odesłałem widok bez użycia setContentView w następujący sposób. layout1 = (LinearLayout) View.inflate (this, R.layout.first_View, null); Następnie, aby uzyskać dostęp do czegokolwiek w środku, mógłbym użyć Button botton = (Button) layout1.findViewById (R.id.button1); Po prostu dodając, aby pomocne było sombody. –

+0

Dlaczego? Jaka jest przewaga nas zmuszająca? –

2

Widoki, które próbujesz uzyskać, nie są zdefiniowane w układzie activity_main. Trzeba programowo nadmuchać poglądy ty próbujesz dodać do pager.-

@Override 
public Object instantiateItem(ViewGroup collection, int position) { 
    LinearLayout l = null; 

    if (position == 0) { 
     l = (LinearLayout) View.inflate(this, R.layout.activity_first, null); 
    } 
    if (position == 1) { 
     l = (LinearLayout) View.inflate(this, R.layout.activity_second, null); 
    } 
    if (position == 2) { 
     l = (LinearLayout) View.inflate(this, R.layout.activity_third, null); 
    } 

    collection.addView(l, position); 
    return l; 
} 
+0

W jaki sposób uzyskasz dostęp do widoków w swojej głównej aktywności? – Denny

1

dodać te widoki do adaptera pager przed uzyskaniem dostępu do nich.

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    adapter = new MyPagerAdapter(); 
    pager = (ViewPager) findViewById(R.id.main_pager); 
    pager.setAdapter(adapter); 

    layout1 = (LinearLayout) findViewById(R.id.first_View); 
    layout2 = (LinearLayout) findViewById(R.id.second_View); 
    layout3 = (LinearLayout) findViewById(R.id.third_View); 

} 

w adapterze pagera:

public Object instantiateItem(View collection, int position) { 
    if(position == 0){ 
     View layout = inflater.inflate(R.layout.activity_first, null); 

     ((ViewPager) collection).addView(layout); 

     return layout; 
    } 
    ... and so forth. 

} 

stąd można uzyskać do nich dostęp poprzez findViewById.

0

Co @Warlock powiedziane wyżej ma rację, należy początkowym LinearLayout Układ1, Layout2, layout3 przez odpowiedni sposób:

LinearLayout layout1 = (LinearLayout) View.inflate(this, R.layout.first_View, null); 
LinearLayout layout2 = (LinearLayout) View.inflate(this, R.layout.second_View, null); 
LinearLayout layout3 = (LinearLayout) View.inflate(this, R.layout.third, null); 

chcesz radzę pomóc

0

w Android, findViewById(R.id.some_id) prace, gdy jesteś znajdowanie widoku w zestawie układu.

To znaczy, jeśli masz ustawiony układ powiedzieć:

setContentView(R.layout.my_layout); 

Odwiedzin można znaleźć tylko w tym układzie (my_layout).

W kodzie layout1, layout2, layout3 wszystkie są trzy różne układy i one nie są ustawione do działania.

0

Sposób findViewById musi znaleźć to, co jest w układzie (co nazywa się w setContentView)

0

Czasami trzeba oczyścić swój projekt w Eclipse (projekt - Clean ..).

1

Otrzymałem ten błąd dzisiaj i było to tak proste do wyjaśnienia, że ​​"twarzą w twarz".

Po prostu spróbuj dodać element UI do pliku układu xml w twoim katalogu res/layout-port !!!

1

Podkreślenie

W tych przypadkach, w klasie aktywności.

Activity.findViewById(int id)

uważa się, że identyfikuje się za pomocą atrybutu id z XML, który poddano obróbce w onCreate(Bundle).


inaczej, takie jak fragment, zasilacz, a View ze LayoutInflater itp

View.findViewById(int id)

Look dla rzutem dziecko z danym id. Jeśli widok ten ma podany identyfikator, zwróć ten widok.


obu przypadkach

Zwraca
Widok jeśli okaże lub null inaczej.


Teraz ponownie sprawdzić swoje pliki XML. Upewnij się, że ustawiłeś odpowiednią wartość na setContentView lub inflater.inflate.

W przypadku aktywności zadzwoń pod numer findViewById po setContentView.

Następnie upewnij się, że istnieje widok, którego szukasz z android:id="@+id/..." w tym układzie. Upewnij się, że numer + ma wartość @+id, co spowoduje dodanie zasobu do wartości R.id, aby upewnić się, że można go znaleźć z poziomu Java.