findViewById dans un fragment

1035

J'essaie de créer une ImageView dans un fragment qui fera référence à l'élément ImageView que j'ai créé dans le XML pour le fragment. Cependant, la findViewByIdméthode ne fonctionne que si j'étends une classe Activity. Y a-t-il une façon dont je peux également l'utiliser dans 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);
    }
}

La findViewByIdméthode contient une erreur qui indique que la méthode n'est pas définie.

simplifié.
la source
Utilisez la bibliothèque de visualisation de ButterKnife pour Android. Démontrez également comment cela fonctionne, comment intégrer et utiliser dans le développement de votre application Android pour accélérer votre développement.
Shomu
«Un certain temps» s'est écoulé, mais vous n'avez toujours pas accepté de réponse. Pouvez-vous sélectionner la réponse qui vous a le plus aidé afin que cela puisse être marqué comme ayant été répondu?
David3103
Il est recommandé d'utiliser la liaison de données orang View Binding à la place du manuel findViewById
mochadwi

Réponses:

1433

Utilisez getView () ou le paramètre View de l'implémentation de la onViewCreatedméthode. Il renvoie la vue racine du fragment (celle renvoyée par la onCreateView()méthode) . Avec cela, vous pouvez appeler 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); 

Comme cela getView()ne fonctionne qu'après onCreateView(), vous ne pouvez pas l'utiliser à l'intérieur onCreate()ni dans les onCreateView()méthodes du fragment.

advantej
la source
323
Remarque: cela ne fonctionne qu'après onCreateView (). Donc, vous ne pouvez pas utiliser ceci dans onCreate ()
Dmitry Zaytsev
7
Alors, quelle est la fonction que je peux remplacer pour implémenter cela si onCreate n'est pas le bon endroit?
Nico AD
16
Cela n'aide pas si le ImageViewprovient de la disposition gonflée - voir ma réponse pour plus de détails. Sinon, onCreateView est le bon endroit pour le faire @ N-AccessDev
MattJenko
25
Le meilleur endroit pour le faire la méthode
onViewCreated
37
La documentation indique que onActivityCreated()c'est l'endroit recommandé pour rechercher et stocker des références à vos vues. Vous devez nettoyer ces références stockées en les redéfinissant nulldans onDestroyView()ou vous fuirez le Activity.
Monstieur
618

Vous devez gonfler la vue du fragment et appeler findViewById()le Viewretour.

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
la source
4
Lorsque vous effectuez V.findViewById (R.id.someid), cela ne fonctionnera sûrement que pour tous les widgets qui sont dans la vue gonflée. Que faire si l'image qu'il essaie de gonfler est en dehors de la vue gonflée?
Raunak
18
Ensuite, la classe qui "possède" et a gonflé l'imageView doit lui fournir un accès public. C'est cependant une très mauvaise pratique. Les fragments ne doivent avoir accès qu'aux éléments de l'interface utilisateur présents dans leur mise en page.
LeffelMania
1
Il semble qu'il y ait quelque chose de mal dans votre code (mise à jour de l'interface utilisateur à partir d'un fil d'arrière-plan), pas le mien.
LeffelMania
1
Merci, c'était utile. Comme commentaire indépendant: essayez de vous en tenir aux conventions de dénomination Java dans votre code. "V" ne ressemble pas à un nom de variable en Java.
altumano
3
Ce devrait être la bonne réponse. L'accepté vous laisse NullPointerException.
Machado
132

Dans la Fragmentclasse, vous obtiendrez la méthode de remplacement onViewCreated () où vous devriez toujours initialiser vos vues car dans cette méthode, vous obtenez un objet de vue à l'aide duquel vous pouvez trouver vos vues comme:

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

Rappelez-vous toujours qu'en cas de Fragment, cette onViewCreated()méthode ne sera pas appelée automatiquement si vous retournez null ou super.onCreateView()from onCreateView()method. Il sera appelé par défaut en cas de ListFragmentcomme ListFragmentretour FrameLayoutpar défaut.

Remarque: vous pouvez obtenir la vue fragmentée n'importe où dans la classe en utilisant getView()une fois qu'elle onCreateView()a été exécutée avec succès. c'est à dire

getView().findViewById("your view id");
Ankur Chaudhary
la source
4
Je suis surpris que peu de gens aient voté pour cette réponse - c'est la bonne façon de configurer des écouteurs sur des fragments ... C'était peut-être un nouveau développement dans l'API.
Sonny
L'utilisation de viewpassé à onViewCreatedprovoque toujours NullPointerExceptionmais l'utilisation getActivity()est très bien. Des idées pourquoi?
dVaffection
@dVaffection Il se peut que vous ne retourniez pas une vue non nulle dans la méthode de cycle de vie onCreateView () du fragment. Maintenant, en cas de getActivity, vous obtenez des vues de votre activité plutôt que de fragmenter la vue principale dépend de l'ID que vous transmettez. Veuillez vérifier si vous retournez une vue non nulle de onCreateView ou non? Alors faites le moi savoir.
Ankur Chaudhary
@AnkurChaudhary Je retourne la vue de la onCreateViewméthode. Je viens de déboguer et il s'avère qu'il y a une mise en page (dans mon cas FrameLayout). Cela étant dit, lorsque j'essaie de trouver un élément, il revient null. Pourquoi cela se produit-il?
dVaffection
@dVaffection pouvez-vous s'il vous plaît partager votre classe de fragment et la disposition correspondante.
Ankur Chaudhary
66

Je me rends compte que c'est une vieille question, mais la réponse dominante laisse à désirer.

La question n'est pas claire de ce qui est requis de imageView - est-ce que nous le repassons comme vue, ou simplement conservons-nous une référence pour plus tard?

Quoi qu'il en soit, si le ImageViewprovient de la disposition gonflée, la bonne façon de le faire serait:

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
la source
1
Comment alors mettre à jour imageView depuis ListFragment? Cela nécessiterait-il FragmentManager? En d'autres termes, comment pouvez-vous mettre à jour l'imageView dans un fragment de détail à partir de onListItemClick d'une classe distincte?
whyoz
1
Vous pouvez soit enregistrer une référence à l'imageView dans un endroit pratique, soit fragment.getView (). FindViewById (R.id.my_image) lorsque vous en avez besoin. Dans un ListFragment, en supposant que l'image se trouve dans un élément de liste, vous créez généralement un support de référence avec les méthodes setTag / getTag de l'élément d'affichage de liste dans la méthode getView de votre adaptateur - il existe de nombreux exemples de la façon de procéder.
MattJenko
47

Obtenez d'abord la vue fragmentée puis récupérez à partir de cette vue votre 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
la source
Alors, la méthode onCreate est-elle utile dans un fragment?
Tsunaze
onCreateView crée et renvoie la hiérarchie de vues associée au fragment.onCreate est appelé pour effectuer la création initiale du fragment. En effet, cela dépend de ce que vous écrivez dans ces méthodes.
xevincent
D'accord, mais comment puis-je déclarer une variable dans onCreate? Parce que la vue est à l'intérieur de la méthode onCreateView.
Tsunaze
@Tsunaze avez-vous déjà découvert comment procéder à partir de la méthode onCreate?
StuStirling
1
Je suis d'accord. Cette réponse doit être marquée comme la solution.
Boris Karloff
25

Vous pouvez également le faire dans la onActivityCreatedméthode.

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

Comme ils le font ici: http://developer.android.com/reference/android/app/Fragment.html (déconseillé au niveau 28 de l'API)

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

et

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

sont possibles.

friiky
la source
18

getView() donnera la vue racine

View v = getView().findViewByID(R.id.x); 
développeur de rêve
la source
17

Vous pouvez remplacer onViewCreated () qui est appelé juste après que toutes les vues ont été gonflées. C'est le bon endroit pour remplir les Viewvariables membres de votre fragment . Voici un exemple:

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
la source
17

À l'intérieur de la Fragmentclasse, nous obtenons une onViewCreated()méthode de remplacement où nous devons toujours initialiser nos vues car dans cette méthode, nous obtenons un viewobjet. En utilisant cet objet, nous pouvons trouver nos vues comme ci-dessous:

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
la source
2
excellent a bien fonctionné! merci beaucoup
Vivek
15

La méthode getView () ne fonctionnera pas sur les fragments en dehors d'OnCreate et des méthodes similaires.

Vous avez deux façons, passez la vue à la fonction sur le oncreate (ce qui signifie que vous ne pouvez exécuter vos fonctions que lorsque la vue est en cours de création) ou définissez la vue en tant que variable:

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
la source
11

1) gonflez d'abord la disposition de Fragment, puis vous pouvez utiliser findviewbyId.

View view = inflater.inflate(R.layout.testclassfragment, container, false);
             ImageView imageView = (ImageView) view.findViewById(R.id.my_image);
             return view;
priti
la source
10
EditText name = (EditText) getView().findViewById(R.id.editText1);
EditText add = (EditText) getView().findViewById(R.id.editText2);  
sandhu
la source
9

Utilisation

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

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

ça va marcher

Manoj ahirwar
la source
9

a accepté d'appeler findViewById()le point de vue.

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
la source
9

Remarque :

À partir du niveau 26 de l'API, vous n'avez pas non plus besoin de transtyper spécifiquement le résultat de findViewById car il utilise l'inférence pour son type de retour.

Alors maintenant, vous pouvez simplement le faire,

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
la source
1
Sans casting, la chose expliquée m'a aidé.
shaurya uppal
8

Selon la documentation sur l'API niveau 11

Référence, dans Back Stack http://developer.android.com/reference/android/app/Fragment.html

petit code

/**
 * 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
la source
8

En utilisant getView()renvoie la vue du fragment, vous pouvez appeler findViewById()pour accéder à n'importe quel élément de vue dans la vue de fragment.

Mahmoud Badri
la source
3
la vue n'est pas l'activité
Steve M
7

Essayez ça ça marche pour moi

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
la source
Oui, ce code ici est correct. Vos modifications à l'autre ne le sont pas.
OneCricketeer
@ cricket_007 ok lequel pouvez-vous me voir?
Bipin Bharti
Je suis désolé, je ne comprends pas très bien votre anglais, mais tout est corrigé maintenant. Je n'ai rien à te montrer.
OneCricketeer
5

La meilleure façon de mettre en œuvre cela est la suivante:

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
}

De cette façon, le rootView peut être utilisé pour chaque contrôle défini dans la disposition xml et le code est beaucoup plus propre de cette façon.

J'espère que cela t'aides :)

Michele La Ferla
la source
je pensais que cela pourrait être possible, mais cela n'a pas fonctionné
Mike Brian Olivera
5

1) Déclarez votre fichier de mise en page.

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

2) Ensuite, obtenez l'identifiant de votre vue

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

Utilisez le plugin squelette gradle , il générera automatiquement les classes de détenteurs de vues avec la référence à votre mise en page.

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

En supposant maintenant que vous aviez un ImageViewdéclaré dans votre my_layout.xmlfichier, il générera automatiquement la classe myLayout pour vous.

Ilya Gazman
la source
4

Essaye ça:

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

return v;
AbhayBohra
la source
4

essayer

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
la source
Il n'y a aucune raison pour le terrain. Vous pouvez toujours appeler getView()plus tard
OneCricketeer
3

Vous pouvez appeler findViewById()avec l' objet d'activité que vous obtenez dans votre public void onAttach(Activity activity)méthode à l'intérieur de votre fragment.

Enregistrez l'activité dans une variable par exemple:

Dans la classe Fragment : private Activity mainActivity; Dans la onAttach()méthode: this.mainActivity=activity;

Enfin, exécutez chaque findViewById via le vairable: mainActivity.findViewById(R.id.TextView);

mrSurprise
la source
3

Il existe une autre méthode appelée onViewCreated.

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

À l'intérieur de la méthode onCreateView

1) vous devez d'abord gonfler la disposition / vue que vous souhaitez ajouter, par exemple. Disposition linéaire

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

2) Ensuite, vous pouvez trouver votre identifiant imageView à partir de la mise en page

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

3) renvoyer la disposition gonflée

return ll;
Devendra Kulkarni
la source
Ceci est identique à la réponse de LeffelMania.
Reti43
2

Vous devez gonfler la vue

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
la source
2

Dans les fragments, nous avons besoin d'une vue de cette fenêtre afin de faire une onCreateView de ce fragment.

Obtenez ensuite la vue et utilisez-la pour accéder à chaque identifiant de vue de ces éléments de vue.

  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
la source
1) Qu'est-ce que cela ajoute aux autres réponses? 2) Vous semblez avoir répondu deux fois
OneCricketeer
2

Le gonfleur de disposition entre en photo ici. L'inflateur de mise en page est une classe qui nous permet d'utiliser les vues XML dans le code java. Vous pouvez donc gonfler la vue xml racine dans la variable v avec le code suivant. Et puis, en utilisant v, vous pouvez trouver les vues enfant de la vue racine 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;
    }
}
Wijay Sharma
la source
1

La façon la plus simple d'utiliser de telles choses est d'utiliser butterknife. Par cela, vous pouvez ajouter autant d'Onclciklisteners que par @OnClick () comme décrit ci-dessous:

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
la source
Pourquoi voté contre, si vous utilisez cela, vous pouvez également utiliser plusieurs onclicks dans la déclaration on.
Amit