findViewById im Fragment


1035

Ich versuche, eine ImageView in einem Fragment zu erstellen, die auf das ImageView-Element verweist, das ich im XML für das Fragment erstellt habe. Die findViewByIdMethode funktioniert jedoch nur, wenn ich eine Aktivitätsklasse erweitere. Gibt es sowieso welche, die ich auch in Fragment verwenden kann?

public class TestClass extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ImageView imageView = (ImageView)findViewById(R.id.my_image);
        return inflater.inflate(R.layout.testclassfragment, container, false);
    }
}

Die findViewByIdMethode weist einen Fehler auf, der besagt, dass die Methode undefiniert ist.


Verwenden Sie die ButterKnife Viewbinding-Bibliothek für Android. Zeigen Sie auch, wie es funktioniert, wie Sie es in Ihre Android-App-Entwicklung integrieren und verwenden, um Ihre Entwicklung zu beschleunigen.
Shomu

Es ist einige Zeit vergangen, aber Sie haben immer noch keine Antwort akzeptiert. Können Sie die Antwort auswählen, die Ihnen am meisten geholfen hat, damit diese als beantwortet markiert werden kann?
David3103

Es wird empfohlen, die
Datenbindung

Antworten:


1433

Verwenden Sie getView () oder den View-Parameter, um die onViewCreatedMethode zu implementieren . Es gibt die Stammansicht für das Fragment zurück (die von der onCreateView()Methode zurückgegebene) . Damit können Sie anrufen findViewById().

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    ImageView imageView = (ImageView) getView().findViewById(R.id.foo);
    // or  (ImageView) view.findViewById(R.id.foo); 

Da dies getView()erst danach funktioniert onCreateView(), können Sie es nicht innerhalb onCreate()oder in onCreateView()Methoden des Fragments verwenden.


323
Hinweis: Es funktioniert erst nach onCreateView (). Sie können dies also nicht in onCreate ()
Dmitry Zaytsev vom

7
Welche Funktion kann ich überschreiben, um dies zu implementieren, wenn onCreate nicht der richtige Ort ist?
Nico AD

16
Dies hilft nicht, wenn das ImageViewvom aufgeblasenen Layout kommt - siehe meine Antwort für Details. Ansonsten ist onCreateView der richtige Ort, um dies zu tun @ N-AccessDev
MattJenko

25
Der beste Ort, um dies zu tun, ist die onViewCreated-Methode
advantej

37
In der Dokumentation wird angegeben, dass dies onActivityCreated()der empfohlene Ort ist, um Verweise auf Ihre Ansichten zu finden und zu speichern. Sie müssen diese gespeicherten Referenzen bereinigen, indem Sie sie wieder auf nullin setzen onDestroyView(), da sonst die Referenz verloren geht Activity.
Monstieur

618

Sie müssen das Fragment Sicht und Aufruf zum Aufblasen findViewById()auf den Viewer zurückkehrt.

public View onCreateView(LayoutInflater inflater, 
                         ViewGroup container, 
                         Bundle savedInstanceState) {
     View view = inflater.inflate(R.layout.testclassfragment, container, false);
     ImageView imageView = (ImageView) view.findViewById(R.id.my_image);
     return view;
}

4
Wenn Sie V.findViewById (R.id.someid) ausführen, funktioniert dies sicherlich nur für alle Widgets, die sich in der aufgeblasenen Ansicht befinden. Was ist, wenn sich die Bildansicht, die er aufzublasen versucht, außerhalb der aufgeblasenen Ansicht befindet?
Raunak

18
Dann muss die Klasse, die die imageView "besitzt" und aufbläst, öffentlichen Zugriff darauf gewähren. Das ist allerdings eine sehr schlechte Praxis. Fragmente sollten nur Zugriff auf die in ihrem Layout vorhandenen UI-Elemente haben.
LeffelMania

1
Es sieht so aus, als ob etwas in Ihrem Code nicht stimmt (Aktualisierung der Benutzeroberfläche von einem Hintergrund-Thread), nicht meiner.
LeffelMania

1
Danke, es war nützlich. Als nicht verwandter Kommentar: Versuchen Sie, die Java-Namenskonventionen in Ihrem Code einzuhalten. "V" sieht in Java nicht wie ein Variablenname aus.
Altumano

3
Dies sollte die richtige Antwort sein. Der Akzeptierte verlässt dich mit NullPointerException.
Machado

132

Innerhalb der FragmentKlasse erhalten Sie die OnViewCreated () - Überschreibungsmethode, bei der Sie Ihre Ansichten immer initialisieren sollten, da Sie bei dieser Methode ein Ansichtsobjekt erhalten, mit dem Sie Ihre Ansichten wie folgt finden können:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    view.findViewById(R.id.yourId).setOnClickListener(this);

    // or
    getActivity().findViewById(R.id.yourId).setOnClickListener(this);
}

Denken Sie bei Fragment immer daran, dass diese onViewCreated()Methode nicht automatisch aufgerufen wird, wenn Sie null oder super.onCreateView()from onCreateView()method zurückgeben. Es wird standardmäßig bei aufgerufen wird ListFragmentals ListFragmentRückkehr FrameLayoutstandardmäßig.

Hinweis: Sie können die Fragmentansicht an einer beliebigen Stelle in der Klasse abrufen, indem Sie getView()einmal onCreateView()erfolgreich ausführen. dh

getView().findViewById("your view id");

4
Ich bin überrascht, dass nicht viele Leute diese Antwort positiv bewertet haben - dies ist der richtige Weg, um Listener für Fragmente einzurichten ... Vielleicht war dies eine neue Entwicklung in der API.
Sonny

Die Verwendung von viewübergeben an onViewCreatednoch Ursachen, NullPointerExceptionaber die Verwendung getActivity()ist in Ordnung. Irgendwelche Ideen warum?
dVaffection

@dVaffection Möglicherweise geben Sie in der onCreateView () -Lebenszyklusmethode des Fragments keine Nicht-Null-Ansicht zurück. Im Fall von getActivity erhalten Sie Ansichten von Ihrer Aktivität, anstatt die Hauptansicht zu fragmentieren. Dies hängt davon ab, welche ID Sie übergeben. Bitte überprüfen Sie, ob Sie eine Nicht-Null-Ansicht von onCreateView zurückgeben oder nicht. Dann lassen Sie mich wissen.
Ankur Chaudhary

@AnkurChaudhary Ich gebe die Ansicht von der onCreateViewMethode zurück. Ich habe gerade debuggt und es stellt sich heraus, dass es ein Layout gibt (in meinem Fall FrameLayout). Davon abgesehen, wenn ich versuche, ein Element zu finden, das zurückgegeben wird null. Warum passiert es?
dVaffection

@dVaffection können Sie bitte Ihre Fragmentklasse und das entsprechende Layout teilen.
Ankur Chaudhary

66

Mir ist klar, dass dies eine alte Frage ist, aber die vorherrschende Antwort lässt zu wünschen übrig.

Die Frage ist nicht klar, was erforderlich ist imageView- geben wir sie als Ansicht zurück oder speichern wir lediglich eine Referenz für später?

In beiden Fällen wäre der ImageViewrichtige Weg, dies zu tun , wenn das aus dem aufgeblasenen Layout stammt:

public class TestClass extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.testclassfragment, container, false);
        ImageView imageView = (ImageView)v.findViewById(R.id.my_image);
        return v;
    }
}

1
Wie würden Sie dann imageView von ListFragment aktualisieren? Würde dies FragmentManager erfordern? Mit anderen Worten, wie können Sie die Bildansicht in einem Detailfragment aus dem onListItemClick einer separaten Klasse aktualisieren?
Whyoz

1
Sie würden entweder einen Verweis auf die imageView an einem praktischen Ort speichern oder fragment.getView (). FindViewById (R.id.my_image), wenn Sie es benötigen. In einem ListFragment erstellen Sie unter der Annahme, dass sich das Bild in einem Listenelement befindet, im Allgemeinen einen Referenzhalter mit den setTag / getTag-Methoden des Listenansichtselements in der getView-Methode Ihres Adapters. Es gibt viele Beispiele dafür.
MattJenko

47

Holen Sie sich zuerst die Fragmentansicht und dann aus dieser Ansicht Ihre ImageView.

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.testclassfragment, container, false);
    ImageView imageView = (ImageView) view.findViewById(R.id.my_image);
    return view;
}

Ist die onCreate-Methode in einem Fragment nützlich?
Tsunaze

onCreateView erstellt die dem Fragment zugeordnete Ansichtshierarchie und gibt sie zurück. onCreate wird aufgerufen, um die erste Erstellung des Fragments durchzuführen. In der Tat hängt es davon ab, was Sie in diesen Methoden schreiben.
xevincent

Okay, aber wie kann ich eine Variable in onCreate deklarieren? Weil sich die Ansicht in der onCreateView-Methode befindet.
Tsunaze

@Tsunaze Hast du jemals herausgefunden, wie das mit der onCreate-Methode geht?
StuStirling

1
Genau. Diese Antwort sollte als Lösung markiert werden.
Boris Karloff



17

Sie können onViewCreated () überschreiben, das direkt aufgerufen wird, nachdem alle Ansichten aufgeblasen wurden. Hier können Sie die Mitgliedsvariablen Ihres Fragments ausfüllen View. Hier ist ein Beispiel:

class GalleryFragment extends Fragment {
    private Gallery gallery;

    (...)

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        gallery = (Gallery) view.findViewById(R.id.gallery);
        gallery.setAdapter(adapter);
        super.onViewCreated(view, savedInstanceState);
    }
}

17

Innerhalb der FragmentKlasse erhalten wir eine onViewCreated()Override-Methode, bei der wir unsere Ansichten immer initialisieren sollten, da wir bei dieser Methode ein viewObjekt erhalten. Mit diesem Objekt können wir unsere Ansichten wie folgt finden:

class MyFragment extends Fragment {
    private ImageView imageView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.my_fragment_layout, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        //initialize your view here for use view.findViewById("your view id")
        imageView = (ImageView) view.findViewById(R.id.my_image);
    }
}

2
ausgezeichnet hat gut funktioniert!
Vielen

15

Die Methode getView () funktioniert nicht mit Fragmenten außerhalb von OnCreate und ähnlichen Methoden.

Sie haben zwei Möglichkeiten: Übergeben Sie die Ansicht an die Funktion in oncreate (was bedeutet, dass Sie Ihre Funktionen nur ausführen können, wenn die Ansicht erstellt wird) oder legen Sie die Ansicht als Variable fest:

private View rootView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
    rootView = inflater.inflate(R.layout.fragment_contatos, container, false);
}

public void doSomething () {
    ImageView thumbnail = (ImageView) rootView.findViewById(R.id.someId);
}

11

1) Blasen Sie zuerst das Layout von Fragment auf, dann können Sie findviewbyId verwenden.

View view = inflater.inflate(R.layout.testclassfragment, container, false);
             ImageView imageView = (ImageView) view.findViewById(R.id.my_image);
             return view;

10
EditText name = (EditText) getView().findViewById(R.id.editText1);
EditText add = (EditText) getView().findViewById(R.id.editText2);  

9

Verwenden

imagebutton = (ImageButton) getActivity().findViewById(R.id.imagebutton1);

imageview = (ImageView) getActivity().findViewById(R.id.imageview1);

es wird klappen


9

stimmte dem Aufruf findViewById()der Ansicht zu.

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View V = inflater.inflate(R.layout.testclassfragment, container, false);
    ImageView imageView = (ImageView) V.findViewById(R.id.my_image);

    return V;
}

9

Hinweis :

Ab API-Ebene 26 müssen Sie das Ergebnis von findViewById auch nicht speziell umwandeln, da es Inferenz für seinen Rückgabetyp verwendet.

Jetzt können Sie einfach tun,

public View onCreateView(LayoutInflater inflater, 
                         ViewGroup container, 
                         Bundle savedInstanceState) {
     View view = inflater.inflate(R.layout.testclassfragment, container, false);
     ImageView imageView =  view.findViewById(R.id.my_image); //without casting the return type
     return view;
}

1
Ohne Casting half mir das erklärte Ding.
Shaurya Uppal

8

Gemäß der Dokumentation auf API-Ebene 11

Referenz im Back Stack http://developer.android.com/reference/android/app/Fragment.html

Funktionscode

/**
 * The Fragment's UI is just a simple text view showing its
 * instance number.
 */
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.hello_world, container, false);
    View tv = v.findViewById(R.id.text);
    ((TextView)tv).setText("Fragment #" + mNum);
    tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
    return v;
}

8

Wenn Sie getView()die Ansicht des Fragments zurückgeben, können Sie aufrufen, findViewById()um auf ein beliebiges Ansichtselement in der Fragmentansicht zuzugreifen.


3
Die Ansicht ist nicht die Aktivität
Steve M

7

Versuchen Sie dies, es funktioniert für mich

public class TestClass extends Fragment {
    private ImageView imageView;

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.testclassfragment, container, false);
        findViews(view);
        return view;
    }

    private void findViews(View view) {
        imageView = (ImageView) view.findViewById(R.id.my_image);
    }
}

Ja, dieser Code hier ist in Ordnung. Ihre Änderungen an den anderen sind nicht.
OneCricketeer

@ Cricket_007 ok welches kannst du mich sehen?
Bipin Bharti

Es tut mir leid, dass ich Ihr Englisch nicht ganz verstehen kann, aber jetzt ist alles behoben. Ich habe dir nichts zu zeigen.
OneCricketeer

5

Dies lässt sich am besten wie folgt umsetzen:

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

rootView = inflater.inflate(R.layout.testclassfragment, container, false);
        ImageView imageView = (ImageView) rootView.findViewById(R.id.my_image);
        return rootView
}

Auf diese Weise kann die rootView für jedes im XML-Layout definierte Steuerelement verwendet werden, und der Code ist auf diese Weise viel sauberer.

Hoffe das hilft :)


Ich dachte, das könnte möglich sein, aber es hat nicht funktioniert
Mike Brian Olivera

5

1) Deklarieren Sie Ihre Layoutdatei.

public View onCreateView(LayoutInflater inflater,ViewGroup container, 
                                 Bundle savedInstanceState) {
    return inflate(R.layout.myfragment, container, false);
}

2) Dann holen Sie sich die ID Ihrer Ansicht

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    TextView nameView = (TextView) view.findViewById(R.id.textview1);
}

4

Wenn Sie das Gradle- Skeleton-Plugin verwenden , werden automatisch die Ansichtshalterklassen mit Bezug auf Ihr Layout generiert.

public class TestClass extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        MyLayout myLayout = new MyLayout(inflater, container, false);
        myLayout.myImage.setImageResource(R.drawable.myImage);
        return myLayout.view;
    }
}

Angenommen, Sie haben eine ImageViewDeklaration in Ihrer my_layout.xmlDatei, wird automatisch die myLayout-Klasse für Sie generiert.


4

Versuche dies:

View v = inflater.inflate(R.layout.testclassfragment, container, false);
ImageView img = (ImageView) v.findViewById(R.id.my_image);

return v;

4

Versuchen

private View myFragmentView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{
myFragmentView = inflater.inflate(R.layout.myLayoutId, container, false);
myView = myFragmentView.findViewById(R.id.myIdTag)
return myFragmentView;
}

Es gibt keinen Grund für das Feld. Sie können jederzeit getView()später anrufen
OneCricketeer

3

Sie können findViewById()mit dem Aktivitätsobjekt, das Sie in Ihrer public void onAttach(Activity activity)Methode erhalten, innerhalb Ihres Fragments aufrufen .

Speichern Sie die Aktivität in einer Variablen, zum Beispiel:

In der Fragment-Klasse : private Activity mainActivity; In der onAttach()Methode: this.mainActivity=activity;

Führen Sie schließlich jede findViewById über die vairable aus: mainActivity.findViewById(R.id.TextView);


3

Es gibt noch eine weitere Methode namens onViewCreated.

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ImageView imageView = (ImageView) view.findViewById(R.id.imageview1);
}

2

Innerhalb der onCreateView-Methode

1) Zuerst müssen Sie das Layout / die Ansicht aufblasen, die Sie hinzufügen möchten, z. LinearLayout

LinearLayout ll = inflater.inflate(R.layout.testclassfragment, container, false);

2) Dann finden Sie Ihre imageView-ID im Layout

ImageView imageView = (ImageView)ll.findViewById(R.id.my_image);

3) Geben Sie das aufgeblasene Layout zurück

return ll;

Dies ist identisch mit der Antwort von LeffelMania.
Reti43

2

Sie müssen die Ansicht aufblasen

public class TestClass extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.testclassfragment, container, false);
    ImageView imageView = (ImageView)v.findViewById(R.id.my_image);
    return v
}}

2

In Fragmenten benötigen wir eine Ansicht dieses Fensters, damit wir eine onCreateView dieses Fragments erstellen können.

Rufen Sie dann die Ansicht ab und verwenden Sie sie, um auf jede Ansichts-ID dieser Ansichtselemente zuzugreifen.

  class Demo extends Fragment
    {
        @Override
        public View onCreateView(final LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState)
        {
            View view =inflater.inflate(R.layout.demo_fragment, container,false);
            ImageView imageview=(ImageView)view.findViewById(R.id.imageview1);

            return view;
        }
    }

1) Was trägt dies zu anderen Antworten bei? 2) Sie scheinen zweimal geantwortet zu haben
OneCricketeer

2

Hier kommt der Layout-Inflater ins Spiel. Layout Inflater ist eine Klasse, mit der wir die XML-Ansichten in Java-Code verwenden können. So können Sie die Root-XML-Ansicht in Variable v mit dem folgenden Code aufblasen. Mit v können Sie dann die untergeordneten Ansichten der Stammansicht v finden.

public class TestClass extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.testclassfragment, container, false);
    ImageView imageView = (ImageView)v.findViewById(R.id.my_image);
    return v;
    }
}

1

Der einfachste Weg, solche Dinge zu verwenden, ist die Verwendung von Buttermesser. Auf diese Weise können Sie mit @OnClick () so viele Onclciklistener hinzufügen, wie unten beschrieben:

public class TestClass extends Fragment {
    @BindView(R.id.my_image) ImageView imageView;
    @OnClick(R.id.my_image)
    public void my_image_click(){
        yourMethod();
    }
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.testclassfragment, container, false);
        ButterKnife.bind(getActivity,view);
        return view;
    }
}

Warum runtergestimmt, wenn Sie dies verwenden, können Sie mehrere onclicks auch in on-Anweisung verwenden.
Amit
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.