1183 votes

findViewById dans le fragment

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 du Fragment. Cependant, l'élément findViewById ne fonctionne que si je prolonge une classe Activity. Existe-t-il un moyen de l'utiliser également 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);
    }
}

El findViewById comporte une erreur qui indique que la méthode n'est pas définie.

0 votes

Utilisez la bibliothèque ButterKnife viewbinding pour Android. Démontrez également comment elle fonctionne, comment l'intégrer et l'utiliser dans votre développement d'applications Android pour accélérer votre développement.

0 votes

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é pour qu'elle soit considérée comme acceptée ?

0 votes

Il est conseillé d'utiliser Data Binding ou View Binding au lieu de manual findViewById.

1599voto

advantej Points 6414

Utilice getView() ou le paramètre View de l'implémentation de la onViewCreated méthode. Elle renvoie la vue Racine pour le fragment (celui qui est renvoyé par 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 getView() ne fonctionne qu'après onCreateView() vous on ne peut pas l'utiliser à l'intérieur onCreate() o onCreateView() méthodes du fragment .

338 votes

Note : cela ne fonctionne qu'après onCreateView(). Vous ne pouvez donc pas l'utiliser dans onCreate().

7 votes

Quelle est donc la fonction que je peux surcharger pour mettre en œuvre cette fonction si onCreate n'est pas le bon endroit ?

17 votes

Cela ne sert à rien si le ImageView provient 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

665voto

LeffelMania Points 5484

Vous devez gonfler la vue du Fragment et appeler findViewById() sur le View il revient.

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 votes

Lorsque vous faites V.findViewById(R.id.someid), cela ne fonctionnera sûrement que pour tous les widgets qui se trouvent dans la vue gonflée. Et si l'imageView qu'il essaie de gonfler se trouve en dehors de la vue gonflée ?

21 votes

Ensuite, la classe qui "possède" et gonfle l'imageView doit fournir un accès public à celle-ci. C'est une très mauvaise pratique. Les fragments ne devraient avoir accès qu'aux éléments de l'interface utilisateur présents dans leur layout.

0 votes

Notez que findViewById doit être appelé sur la vue qui est gonflée, et non sur getView().

153voto

Ankur Chaudhary Points 303

À l'intérieur de Fragment vous obtiendrez onViewCreated() La méthode de surcharge où vous devriez toujours initialiser vos vues comme dans cette méthode vous obtenez l'objet de vue en utilisant lequel 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);
}

En cas de fragment, n'oubliez jamais que onViewCreated() ne sera pas appelée automatiquement si vous renvoyez null ou super.onCreateView() de onCreateView() méthode. Elle sera appelée par défaut en cas de ListFragment comme ListFragment retourner FrameLayout par défaut.

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

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

7 votes

Je suis surpris que peu de personnes aient voté pour cette réponse - c'est la bonne façon de configurer les écouteurs sur les fragments... Peut-être s'agit-il d'un nouveau développement de l'API.

0 votes

Utilisation de view transmis à onViewCreated cause encore NullPointerException mais en utilisant getActivity() est bien. Vous savez pourquoi ?

0 votes

@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, dans le cas de getActivity vous obtenez des vues de votre activité plutôt que la vue principale du fragment dépend de l'id que vous passez. S'il vous plaît vérifier si vous retournez une vue non nulle de onCreateView ou non ? Puis laissez-moi savoir.

69voto

MattJenko Points 660

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

La question n'est pas claire quant à ce qui est exigé de imageView - le renvoyons-nous en tant que vue, ou sauvegardons-nous simplement une référence pour plus tard ?

Quoi qu'il en soit, si le ImageView provient du modèle gonflé, la façon correcte de procéder serait la suivante :

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 votes

Comment alors mettre à jour imageView à partir de ListFragment ? Cela nécessiterait-il un FragmentManager ? En d'autres termes, comment pouvez-vous mettre à jour l'imageView dans un fragment de détail à partir du onListItemClick d'une classe distincte ?

1 votes

Vous pouvez soit enregistrer une référence à l'imageView quelque part à portée de main, 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éerez généralement un support de référence avec les méthodes setTag/getTag de l'élément de vue de liste dans la méthode getView de votre adaptateur - il existe de nombreux exemples de la façon de procéder.

0 votes

@MattJenko, pouvez-vous partager plus de détails ou un exemple de comment faire pour avoir une solution fonctionnelle lorsque la mise en page gonflée est utilisée ? Par exemple, j'ai un viewpager2 avec un tablayout (4 onglets) médiatisé, et je gonfle les vues edittext dans le fragment, et j'ai besoin d'accéder à l'editext pour chaque vue du viewpager2 à partir de l'activité principale. Comment faire exactement ?

53voto

xevincent Points 1848

Obtenez d'abord la vue du fragment, puis obtenez 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;
}

0 votes

Alors, la méthode onCreate est-elle utile dans un Fragment ?

0 votes

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 fait, tout dépend de ce que vous écrivez dans ces méthodes.

0 votes

Ok, mais comment puis-je déclarer une variable dans le onCreate ? Parce que la vue est à l'intérieur de la méthode onCreateView.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X