findViewById en Fragment

1035

Estoy tratando de crear un ImageView en un Fragmento que se referirá al elemento ImageView que he creado en el XML para el Fragmento. Sin embargo, el findViewByIdmétodo solo funciona si extiendo una clase de actividad. ¿Hay alguna forma de que también pueda usarlo en 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 findViewByIdmétodo tiene un error que indica que el método no está definido.

simplificado.
fuente
Utilice la biblioteca de enlace de vista ButterKnife para Android. También demuestre cómo funciona, cómo integrarse y usarlo en el desarrollo de su aplicación de Android para acelerar su desarrollo.
Shomu
'Ha pasado algún tiempo' pero aún no has aceptado una respuesta. ¿Puedes seleccionar la respuesta que más te ayudó para que se pueda marcar como contestada?
David3103
Se recomienda utilizar Data Binding orang View Binding en lugar de findViewById manual
mochadwi

Respuestas:

1433

Use getView () o el parámetro View desde la implementación del onViewCreatedmétodo. Devuelve la vista raíz del fragmento (la que devuelve el onCreateView()método) . Con esto puedes llamar 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); 

Como getView()funciona solo después onCreateView(), no puede usarlo dentro onCreate()o los onCreateView()métodos del fragmento.

advantej
fuente
323
Nota: solo funciona después de onCreateView (). Entonces, no puedes usar esto en onCreate ()
Dmitry Zaytsev
77
Entonces, ¿cuál es la función que puedo anular para implementar esto si onCreate no es el lugar correcto?
Nico AD
16
Esto no ayuda si ImageViewproviene del diseño inflado; consulte mi respuesta para obtener más detalles. De lo contrario, onCreateView es el lugar correcto para hacer esto @ N-AccessDev
MattJenko
25
El mejor lugar para hacer esto es el método
onViewCreated
37
La documentación indica que onActivityCreated()es el lugar recomendado para buscar y almacenar referencias a sus vistas. Usted debe limpiar estas referencias almacenados mediante el establecimiento de vuelta a nullen onDestroyView()o que se escape el Activity.
Monstieur
618

Necesitas inflar la vista del Fragmento y llamar findViewById()al Viewque regresa.

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
fuente
44
Cuando haces V.findViewById (R.id.someid), seguramente eso solo funcionará para todos los widgets que están en la vista inflada. ¿Qué sucede si la imageView que intenta inflar está fuera de la vista inflada?
Raunak
18
Entonces, la clase que "posee" e infló el imageView necesita proporcionar acceso público a él. Sin embargo, esa es una muy mala práctica. Los fragmentos solo deberían tener acceso a los elementos de la interfaz de usuario presentes en su diseño.
LeffelMania
1
Parece que hay algo mal en su código (actualizar la interfaz de usuario desde un hilo de fondo), no el mío.
LeffelMania
1
Gracias, fue útil. Como comentario no relacionado: intente atenerse a las convenciones de nomenclatura de Java en su código. "V" no se parece a un nombre de variable en Java.
altumano
3
Esta debería ser la respuesta correcta. El aceptado te deja con NullPointerException.
Machado
132

Dentro de la Fragmentclase obtendrá el método de anulación onViewCreated () donde siempre debe inicializar sus vistas, ya que en este método obtiene un objeto de vista con el que puede encontrar sus vistas como:

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

Siempre recuerde en el caso de Fragment que el onViewCreated()método no se llamará automáticamente si está devolviendo null o super.onCreateView()del onCreateView()método. Se llamará de forma predeterminada en caso de devolución ListFragmentcomo predeterminada.ListFragmentFrameLayout

Nota: puede obtener la vista de fragmentos en cualquier lugar de la clase utilizando getView()una vez que onCreateView()se haya ejecutado correctamente. es decir

getView().findViewById("your view id");
Ankur Chaudhary
fuente
44
Me sorprende que no mucha gente haya votado por esta respuesta: esta es la forma correcta de configurar escuchas en fragmentos ... Quizás este fue un nuevo desarrollo en la API.
Sonny
Usar viewpasado a onViewCreatedcausas inmóviles NullPointerExceptionpero usar getActivity()está bien. Alguna idea de por qué?
dVaffection
@dVaffection Es posible que no esté devolviendo una vista no nula en el método de fragmento de ciclo de vida onCreateView (). Ahora, en el caso de getActivity, obtendrá vistas de su actividad en lugar de fragmentar la vista principal, dependiendo de la identificación que esté pasando. Por favor, compruebe si está devolviendo una vista no nula de onCreateView o no? Entonces hazmelo saber.
Ankur Chaudhary
@AnkurChaudhary Devuelvo la vista del onCreateViewmétodo. Acabo de depurar y resulta que hay un diseño (en mi caso FrameLayout). Dicho esto cuando trato de encontrar un elemento, devuelve null. Por que esta sucediendo?
dVaffection
@dVaffection, ¿puede compartir su clase de fragmento y el diseño correspondiente?
Ankur Chaudhary
66

Me doy cuenta de que esta es una vieja pregunta, pero la respuesta predominante deja algo que desear.

La pregunta no está clara de qué se requiere imageView: ¿la estamos devolviendo como la vista, o simplemente guardamos una referencia para más adelante?

De cualquier manera, si ImageViewproviene del diseño inflado, la forma correcta de hacerlo sería:

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
fuente
1
¿Cómo actualizarías imageView desde ListFragment? ¿Esto requeriría FragmentManager? En otras palabras, ¿cómo puede actualizar imageView en un fragmento de detalle de onListItemClick de una clase separada?
whyoz
1
Puede guardar una referencia a imageView en algún lugar útil, o fragment.getView (). FindViewById (R.id.my_image) cuando lo necesite. En un ListFragment, suponiendo que la imagen esté en un elemento de la lista, generalmente crearía un titular de referencia con los métodos setTag / getTag del elemento de vista de lista en el método getView de su Adaptador; hay muchos ejemplos de cómo hacerlo.
MattJenko
47

Obtenga primero la vista de fragmentos y luego obtenga de esta vista su 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
fuente
Entonces, ¿el método onCreate es útil en un Fragmento?
Tsunaze
onCreateView crea y devuelve la jerarquía de vistas asociada con el fragmento. Se llama a onCreate para realizar la creación inicial del fragmento. De hecho, depende de lo que escriba en estos métodos.
xevincent
De acuerdo, pero ¿cómo puedo declarar variable en onCreate? Porque la vista está dentro del método onCreateView.
Tsunaze
@Tsunaze ¿alguna vez descubriste cómo hacer esto con el método onCreate?
StuStirling
1
Estoy de acuerdo. Esta respuesta debe marcarse como la solución.
Boris Karloff
25

También puedes hacerlo en el onActivityCreatedMétodo.

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

Como lo hacen aquí: http://developer.android.com/reference/android/app/Fragment.html (en desuso en el nivel de API 28)

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

y

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

es posible.

friiky
fuente
18

getView() dará la vista raíz

View v = getView().findViewByID(R.id.x); 
desarrollador de sueños
fuente
17

Puede anular onViewCreated (), que se llama justo después de que se hayan inflado todas las vistas. Es el lugar correcto para completar las Viewvariables miembro de su Fragmento . Aquí hay un ejemplo:

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
fuente
17

Dentro de la Fragmentclase obtenemos el onViewCreated()método de anulación donde siempre debemos inicializar nuestras vistas porque en este método obtenemos el viewobjeto. Usando este objeto podemos encontrar nuestras vistas como a continuación:

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
fuente
2
excelente funcionó bien! muchas gracias
Vivek
15

El método getView () no funcionará en fragmentos fuera de OnCreate y métodos similares.

Tiene dos formas: pasar la vista a la función en el oncreate (lo que significa que solo puede ejecutar sus funciones cuando se está creando la vista) o establecer la vista como una 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
fuente
11

1) primero infla el diseño de Fragment y luego puedes usar findviewbyId.

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

Utilizar

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

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

funcionará

Manoj ahirwar
fuente
9

de acuerdo con llamar findViewById()a la 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;
}
Pajeh
fuente
9

Nota :

Desde el nivel 26 de API, tampoco necesita emitir específicamente el resultado de findViewById, ya que utiliza la inferencia para su tipo de retorno.

Entonces ahora puedes simplemente hacer,

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
fuente
1
Sin casting lo explicado me ayudó.
shaurya uppal
8

De acuerdo con la documentación sobre API nivel 11

Referencia, en Back Stack http://developer.android.com/reference/android/app/Fragment.html

Código 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;
}
Diestro
fuente
8

El uso getView()devuelve la vista del fragmento, luego puede llamar findViewById()para acceder a cualquier elemento de vista en la vista de fragmento.

Mahmoud Badri
fuente
3
la vista no es la actividad
Steve M
7

Prueba esto, me funciona

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
fuente
Sí, este código aquí está bien. Sus ediciones a la otra no lo son.
OneCricketeer
@ cricket_007 ok, ¿cuál me viste?
Bipin Bharti
Lo siento, no puedo entender tu inglés, pero todo está arreglado ahora. No tengo nada que mostrarte.
OneCricketeer
5

La mejor manera de implementar esto es la siguiente:

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 esta manera, el rootView se puede usar para cada control definido en el diseño xml y el código es mucho más limpio de esta manera.

Espero que esto ayude :)

Michele La Ferla
fuente
pensé que esto podría ser posible, pero no funcionó
Mike Brian Olivera
5

1) Declara tu archivo de diseño.

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

2) Luego, obtenga la identificación de su vista

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

Utilice el complemento de esqueleto de gradle , generará automáticamente las clases de titular de vista con la referencia a su diseño.

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

Ahora, suponiendo que haya ImageViewdeclarado en su my_layout.xmlarchivo, generará automáticamente la clase myLayout para usted.

Ilya Gazman
fuente
4

Prueba esto:

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

return v;
AbhayBohra
fuente
4

tratar

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
fuente
No hay razón para el campo. Siempre puedes llamar getView()más tarde
OneCricketeer
3

Puedes llamar findViewById()con el objeto de actividad que obtienes dentro de tu public void onAttach(Activity activity)método dentro de tu Fragmento.

Guarde la actividad en una variable, por ejemplo:

En la clase Fragment : private Activity mainActivity; En el onAttach()método: this.mainActivity=activity;

Finalmente ejecute cada findViewById a través de lo deseable: mainActivity.findViewById(R.id.TextView);

Sr. sorpresa
fuente
3

Hay un método más llamado onViewCreated.

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

Dentro del método onCreateView

1) primero debe inflar el diseño / vista que desea agregar, por ejemplo. LinearLayout

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

2) Luego puede encontrar su ID de imageView desde el diseño

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

3) devolver el diseño inflado

return ll;
Devendra Kulkarni
fuente
Esto es idéntico a la respuesta de LeffelMania.
Reti43
2

Tienes que inflar 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
}}
Surajit Mondal
fuente
2

En fragmentos, necesitamos una vista de esa ventana para poder hacer un onCreateView de este Fragmento.

Luego obtenga la vista y úsela para acceder a todos y cada uno de los identificadores de los elementos de esa 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;
        }
    }
Mayank Garg
fuente
1) ¿Qué agrega esto a otras respuestas? 2) Parece que has respondido dos veces
OneCricketeer
2

El inflador de diseño aparece aquí. Layout Inflater es una clase que nos permite utilizar las vistas XML en código Java. Por lo tanto, puede inflar la vista xml raíz en la variable v con el siguiente código. Y luego usando v, puede encontrar las vistas secundarias de la vista raíz 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
fuente
1

La forma más fácil de usar estas cosas es usar butterknife. De esta manera, puede agregar tantos Onclciklisteners solo con @OnClick () como se describe a continuación:

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
fuente
Por qué votó en contra, si usa esto, puede usar múltiples onclicks también en la declaración.
Amit