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.

vereinfacht.
quelle
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.

advantej
quelle
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;
}
LeffelMania
quelle
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");
Ankur Chaudhary
quelle
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;
    }
}
MattJenko
quelle
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;
}
xevincent
quelle
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
25

Sie können dies auch in der onActivityCreatedMethode tun .

public void onActivityCreated(Bundle savedInstanceState) { 
      super.onActivityCreated(savedInstanceState);
}

Wie hier: http://developer.android.com/reference/android/app/Fragment.html (veraltet in API-Level 28)

getView().findViewById(R.id.foo);

und

getActivity().findViewById(R.id.foo);

Sind möglich.

friiky
quelle
18

getView() gibt die Root-Ansicht

View v = getView().findViewByID(R.id.x); 
Traumentwickler
quelle
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);
    }
}
Lez
quelle
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);
    }
}
Vipul Prajapati
quelle
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);
}
Sagits
quelle
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;
Priti
quelle
10
EditText name = (EditText) getView().findViewById(R.id.editText1);
EditText add = (EditText) getView().findViewById(R.id.editText2);  
Sandhu
quelle
9

Verwenden

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

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

es wird klappen

Manoj ahirwar
quelle
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;
}
Pajeh
quelle
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;
}
Kartik Shandilya
quelle
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;
}
Dexter
quelle
8

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

Mahmoud Badri
quelle
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);
    }
}
Bipin Bharti
quelle
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 :)

Michele La Ferla
quelle
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);
}
Nanda Gopal
quelle
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.

Ilya Gazman
quelle
4

Versuche dies:

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

return v;
AbhayBohra
quelle
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;
}
Ramkumar.M
quelle
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);

Herr Überraschung
quelle
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);
}
Raja Jawahar
quelle
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;
Devendra Kulkarni
quelle
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
}}
Surajit Mondal
quelle
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;
        }
    }
Mayank Garg
quelle
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;
    }
}
Wijay Sharma
quelle
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;
    }
}
Amit
quelle
Warum runtergestimmt, wenn Sie dies verwenden, können Sie mehrere onclicks auch in on-Anweisung verwenden.
Amit