findViewById in Fragment


1035

Sto cercando di creare un ImageView in un frammento che farà riferimento all'elemento ImageView che ho creato nell'XML per il frammento. Tuttavia, il findViewByIdmetodo funziona solo se estendo una classe Activity. Esiste un modo in cui posso usarlo anche in Fragment?

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);
    }
}

Il findViewByIdmetodo contiene un errore che indica che il metodo non è definito.


Usa la libreria viewbinding di ButterKnife per Android. Dimostra anche come funziona, come integrarlo e utilizzarlo nello sviluppo di app Android per velocizzare lo sviluppo.
Shomu,

È passato un po 'di tempo ma non hai ancora accettato una risposta. Puoi selezionare la risposta che ti ha aiutato di più in modo che possa essere contrassegnata come risposta?
David3103

È incoraggiante utilizzare Data Binding o View Binding invece manuale findViewById
mochadwi

Risposte:


1433

Utilizzare getView () o il parametro View dall'implementazione del onViewCreatedmetodo. Restituisce la vista radice per il frammento (quella restituita dal onCreateView()metodo) . Con questo puoi chiamare 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); 

Come getView()funziona solo dopo onCreateView(), non è possibile utilizzarlo all'interno onCreate()o sui onCreateView()metodi del frammento.


323
Nota: funziona solo dopo onCreateView (). Quindi, non puoi usarlo in onCreate ()
Dmitry Zaytsev il

7
quindi qual è la funzione che posso ignorare per implementarlo se onCreate non è il posto giusto?
Nico AD,

16
Questo non aiuta se ImageViewproviene dal layout gonfiato - vedi la mia risposta per i dettagli. Altrimenti, onCreateView è il posto giusto per fare questo @ N-AccessDev
MattJenko

25
Il posto migliore per farlo è il metodo
onViewCreated

37
La documentazione indica che onActivityCreated()è il luogo consigliato per trovare e archiviare riferimenti alle proprie visualizzazioni. È necessario ripulire questi riferimenti memorizzati ripristinandoli in nullin onDestroyView()o si perderanno Activity.
Monstieur,

618

Devi gonfiare la vista del frammento e invocare findViewById()il Viewsuo ritorno.

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
Quando esegui V.findViewById (R.id.someid), sicuramente funzionerà solo per tutti i widget che sono nella vista gonfiata. Cosa succede se l'immagine che sta cercando di gonfiare è al di fuori della vista gonfiata?
Raunak,

18
Quindi la classe che "possiede" e gonfia l'immagine imageView deve fornire accesso pubblico ad essa. Questa è una brutta pratica però. I frammenti dovrebbero avere accesso solo agli elementi dell'interfaccia utente presenti nel loro layout.
LeffelMania,

1
Sembra che ci sia qualcosa di sbagliato nel tuo codice (aggiornamento dell'interfaccia utente da un thread in background), non mio.
LeffelMania,

1
Grazie, è stato utile Come commento indipendente: prova a rispettare le convenzioni di denominazione Java nel tuo codice. "V" non sembra un nome di variabile in Java.
altumano,

3
Questa dovrebbe essere la risposta giusta. Quello accettato ti lascia con NullPointerException.
Machado,

132

All'interno della Fragmentclasse otterrai il metodo di sostituzione onViewCreated () in cui dovresti sempre inizializzare le tue visualizzazioni poiché in questo metodo ottieni l'oggetto view usando il quale puoi trovare le tue visualizzazioni come:

@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);
}

Ricorda sempre in caso di frammento che il onViewCreated()metodo non verrà chiamato automaticamente se stai restituendo null o super.onCreateView()dal onCreateView()metodo. Si chiamerà per impostazione predefinita in caso di ListFragmentcome ListFragmentil ritorno FrameLayoutdi default.

Nota: è possibile ottenere la vista frammento in qualsiasi punto della classe utilizzando getView()una volta onCreateView()eseguita correttamente. vale a dire

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

4
Sono sorpreso che non molte persone abbiano votato a favore di questa risposta - questo è il modo corretto di impostare gli ascoltatori su frammenti ... Forse questo è stato un nuovo sviluppo nell'API.
Sonny,

L'uso è viewpassato a onViewCreatedcause ancora, NullPointerExceptionma l'uso getActivity()va bene. Qualche idea sul perché?
dVaffection,

@dVaffection È possibile che non si stia restituendo una vista non nulla nel metodo del frammento del ciclo di vita onCreateView (). Ora in caso di getActivity stai ottenendo viste dalla tua attività piuttosto che frammentare la vista principale dipende da quale ID stai passando. Verifica che stai restituendo una vista non nulla da onCreateView o no? Allora fammi sapere.
Ankur Chaudhary,

@AnkurChaudhary Ritorna la vista dal onCreateViewmetodo. Ho appena eseguito il debug e risulta che c'è un layout (nel mio caso FrameLayout). Detto questo quando provo a trovare un elemento, ritorna null. Perché sta succedendo?
dVaffection

@dVaffection puoi condividere la tua classe di frammento e il layout corrispondente.
Ankur Chaudhary,

66

Mi rendo conto che questa è una vecchia domanda, ma la risposta prevalente lascia a desiderare.

La domanda non è chiara di cosa è richiesto imageView: stiamo passando indietro come vista o semplicemente salvando un riferimento per dopo?

Ad ogni modo, se ImageViewproviene dal layout gonfiato, il modo corretto per farlo sarebbe:

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
Come aggiorneresti imageView da ListFragment? Ciò richiederebbe FragmentManager? In altre parole, come è possibile aggiornare imageView in un frammento di dettaglio da onListItemClick di una classe separata?
whyoz,

1
Salveresti un riferimento a imageView da qualche parte a portata di mano, oppure fragment.getView (). FindViewById (R.id.my_image) quando ne hai bisogno. In un ListFragment, supponendo che l'immagine si trovi in ​​un elemento dell'elenco, in genere si creerebbe un supporto di riferimento con i metodi setTag / getTag dell'elemento di visualizzazione elenco nel metodo getView dell'adapter - ci sono molti esempi di come farlo.
MattJenko,

47

Ottieni prima la vista frammento e quindi ottieni da questa vista 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;
}

Quindi, il metodo onCreate è utile in un frammento?
Tsunaze,

onCreateView crea e restituisce la gerarchia della vista associata al fragment.onCreate viene chiamato per eseguire la creazione iniziale del frammento. In effetti, dipende da cosa scrivi in ​​questi metodi.
Xevincent,

Ok, ma come posso dichiarare la variabile in onCreate? Perché la vista è all'interno del metodo onCreateView.
Tsunaze,

@Tsunaze hai mai scoperto come farlo dal metodo onCreate?
StuStirling,

1
Sono d'accordo. Questa risposta dovrebbe essere contrassegnata come soluzione.
Boris Karloff,



17

Puoi sovrascrivere onViewCreated () che viene chiamato subito dopo aver gonfiato tutte le viste. È il posto giusto per inserire le Viewvariabili membro del tuo frammento . Ecco un esempio:

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

All'interno della Fragmentclasse otteniamo il onViewCreated()metodo di override in cui dovremmo sempre inizializzare le nostre viste perché in questo metodo otteniamo un viewoggetto. Usando questo oggetto possiamo trovare le nostre opinioni come di seguito:

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
eccellente ha funzionato bene! grazie mille
Vivek,

15

Il metodo getView () non funzionerà su frammenti esterni a OnCreate e metodi simili.

Hai due modi, passa la vista alla funzione oncreate (ciò significa che puoi eseguire le tue funzioni solo quando viene creata la vista) o impostare la vista come variabile:

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) prima gonfia il layout di Fragment, quindi puoi usare findviewbyId.

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

Uso

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

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

Funzionerà


9

concordato con la chiamata findViewById()alla vista.

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

Nota :

Dal livello API 26, inoltre, non è necessario eseguire il cast specifico del risultato di findViewById poiché utilizza l'inferenza per il tipo di ritorno.

Quindi ora puoi semplicemente fare

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
Senza il casting le cose spiegate mi hanno aiutato.
Shaurya uppal,

8

Secondo la documentazione sul livello API 11

Riferimento, in Back Stack http://developer.android.com/reference/android/app/Fragment.html

codice corto

/**
 * 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

Utilizzando getView()restituisce la vista del frammento, quindi è possibile chiamare findViewById()per accedere a qualsiasi elemento della vista nella vista frammento.


3
la vista non è l'attività
Steve M

7

Prova questo funziona per me

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);
    }
}

Sì, questo codice qui va bene. Le tue modifiche all'altra no.
OneCricketeer,

@ cricket_007 ok quale mi vedi?
Bipin Bharti,

Mi dispiace di non riuscire a capire bene il tuo inglese, ma ora tutto è risolto. Non ho niente da mostrarti.
OneCricketeer,

5

Il modo migliore per implementarlo è il seguente:

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
}

In questo modo, rootView può essere utilizzato per ogni controllo definito nel layout xml e il codice è molto più pulito in questo modo.

Spero che sia di aiuto :)


pensavo che ciò potesse essere possibile, ma non ha funzionato
Mike Brian Olivera il

5

1) Dichiara il tuo file di layout.

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

2) Quindi, ottieni l'ID della tua vista

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

4

Utilizza il plug-in gradle skeleton , genererà automaticamente le classi del titolare della vista con riferimento al layout.

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;
    }
}

Ora supponendo che tu ne abbia ImageViewdichiarato uno nel tuo my_layout.xmlfile, genererà automaticamente la mia classe myLayout per te.


4

Prova questo:

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

return v;

4

provare

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;
}

Non c'è motivo per il campo. Puoi sempre chiamare in getView()seguito
OneCricketeer l'

3

Puoi chiamare findViewById()con l' oggetto attività che ottieni nel tuo public void onAttach(Activity activity)metodo all'interno del tuo frammento.

Salvare l'attività in una variabile, ad esempio:

Nella classe Frammento : private Activity mainActivity; Nel onAttach()metodo: this.mainActivity=activity;

Infine esegui ogni findViewById attraverso il vairable: mainActivity.findViewById(R.id.TextView);


3

Esiste un altro metodo chiamato onViewCreated.

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

2

All'interno del metodo onCreateView

1) per prima cosa devi gonfiare il layout / vista che vuoi aggiungere ad es. LinearLayout

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

2) Quindi puoi trovare il tuo ID imageView dal layout

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

3) restituire il layout gonfiato

return ll;

Questo è identico alla risposta di LeffelMania.
Reti43,

2

Devi gonfiare la vista

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 frammenti abbiamo bisogno di una vista di quella finestra in modo da creare un onCreateView di questo frammento.

Quindi ottieni la vista e usala per accedere a tutti gli ID di vista di quegli elementi della vista.

  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) Cosa aggiunge questo ad altre risposte? 2) Sembra che tu abbia risposto due volte
OneCricketeer,

2

Il gonfiatore di layout appare in figura qui. Il gonfiatore del layout è una classe che ci rende in grado di utilizzare le viste XML nel codice java. Quindi puoi gonfiare la vista XML radice nella variabile v con il seguente codice. Quindi, usando v, è possibile trovare le viste figlio della vista radice v.

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

Il modo più semplice per usare queste cose è usare il coltello da burro Con questo puoi aggiungere tanti Onclciklisteners semplicemente da @OnClick () come descritto di seguito:

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;
    }
}

Perché mai votato, se lo usi, puoi usare più onclick anche nell'istruzione on.
Tra l'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.