Estoy trabajando en ViewPager y el uso de Fragment no he encontrado

setUserVisibleHint() llama antes de onCreateView() en el Fragmento

Estoy usando Fragment de apoyo de la biblioteca android.support.v4.app.Fragment

Es que este es un problema con la Biblioteca ?

¿Cómo puedo deshacerme de él ?

EDITAR

Anular setUserVisibleHint() y no llamar a super para deshacerse de él.

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    //FIXED: setUserVisibleHint() called before onCreateView() in Fragment causes NullPointerException
    //super.setUserVisibleHint(isVisibleToUser);
}
  • Tuve este problema hace 2 horas demasiado, ¿qué quieres hacer?
  • sabemos que nuestro punto de vista obtener inflado en onCreateView() luego la usamos; lo mismo estoy creando Personalizado Veiw en onCreateView() y posteriormente utilizarla en setUserVisibleHint() VERDADERO
  • Yo uso ese método para actualizar los datos de los fragmentos. si necesita actualizar o mostrar sus datos es necesario comprobar getView() en setUserVisibleHint, si es nulo, por lo que onCreateView no se llama sin embargo, y usted puede utilizar ese método de onCreateView(); para el primer almuerzo o saltando algún fragmento, a continuación, cambiar un valor Booleano para Evitar duplicar método de llamada, Espero que este muy útil para que usted ( poner el método de actualización en onCreateView y setUserVisibleHint )
  • tiene u tiene la solución para el ur problema..estoy también se enfrenta a un problema similar que se mencionan aquí stackoverflow.com/q/25200404/2624806
  • Parece que esto está sucediendo en la Malvavisco y de seguridad.
  • es este un error de google? sigue pasando.. ¿por qué es eso? sé cómo implementar soluciones, pero ¿tienes idea de por qué está pasando esto?

InformationsquelleAutor Amit Yadav | 2014-06-11

11 Comentarios

  1. 91
    //create boolean for fetching data
    private boolean isViewShown = false;
    
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (getView() != null) {
            isViewShown = true;
            //fetchdata() contains logic to show data when page is selected mostly asynctask to fill the data
            fetchData();
        } else {
            isViewShown = false;
        }
    } 

    Uso isViewShown variable de instancia para decidir si para recuperar los datos en onCreateView() o en setUserVisibleHint().

    A continuación el código contiene la lógica para onCreateView():

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.main_layout, container, false);
    
       //view initialization steps.......
    
       if (!isViewShown) {
            fetchData();
       } 
       //do other stuff
    }

    Este código va a resolver su problema. Como Lo ha resuelto mi problema. 🙂

    Este truco de recuperar los datos en onCreateView() directa de saltar de una página a otra, mientras que cuando pase la vista se capturará los datos de setUserVisibleHint() método. 🙂

    • solución inteligente:)
    • Pero, ¿qué getView () ¿?
    • asegura que la vista no es nulo por lo que no se consigue NPE
    • Qué sugiere usted que se supone que no debemos comprobar si isVisibleToUser es verdadero o falso??? En el primer ejemplo, ¿por Qué no comprobar si isVisibleToUser es cierto, a continuación, compruebe si getView() es nulo..
    • El isVisibleToUser bandera no es trustworty en nuestra aplicación. Nos observador se convierte (a veces, al menos) la verdad antes de que la vista es visible. Tuve que crear una bandera local como en esta solución. Se recomienda.
    • setUserVisibleHint obras antes de onCreateView, esto hace que su respuesta equivocada
    • Directo de salto está bien. Pero, este enfoque cargas de Datos antes de fragmento visible. La ejecución de la red de la llamada antes de que llegó a los respectivos fragmento. Recomendamos esta respuesta-> stackoverflow.com/a/32223340/8035209

  2. 33

    puede utilizar esta lógica, también puede desactivar viewDidAppear cualquier momento mediante la configuración de isVisible = false

    public class MyFragment extends Fragment {
        private Boolean isStarted = false;
        private Boolean isVisible = false;
    
        @Override
        public void onStart() {
            super.onStart();
            isStarted = true;
            if (isVisible && isStarted){
                viewDidAppear();
            }
        }
    
        @Override
        public void setUserVisibleHint(boolean isVisibleToUser) {
            super.setUserVisibleHint(isVisibleToUser);
            isVisible = isVisibleToUser;
            if (isStarted && isVisible) {
                viewDidAppear();
            }
        }
    
        public void viewDidAppear() {
           //your logic
        }
    }
    • No hay que ser un ‘isStarted = false’ en onStop?
    • como me recuerda esto funcionó muy bien para mí, pero siéntase libre de modificar la respuesta y la agregamos
  3. 13

    He encontrado la mejor solución

    private boolean isVisible;
    private boolean isStarted;
    
    @Override
    public void onStart() {
        super.onStart();
        isStarted = true;
        if (isVisible)
            sendRequest(); //your request method
    }
    
    @Override
    public void onStop() {
        super.onStop();
        isStarted = false;
    }
    
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        isVisible = isVisibleToUser;
        if (isVisible && isStarted)
            sendRequest(); //your request method
    }

    Es una versión mejorada de fareed namrouti‘s respuesta. He probado esto en muchas condiciones. Es seguro.

    • Esto funciona perfectamente. He probado también en viewpager. +1 estoy confundido poco ¿por qué no podemos llamar onResume de los padres fragmento.
  4. 5
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment, container, false);
    
        if (getUserVisibleHint()) {
             sendRequest();
        }
    
        return view;
    }
    
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            if (isResumed()){ 
                 sendRequest();
              }
        }
    }
    • Bueno, tengo un problema con esto, la onPreExecute método es no cambiar la visibilidad de mi barra de progreso
  5. 3

    A continuación Trabajó para mí….

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState)
    {
        ////create class member variable to store view
        viewFrag =inflater.inflate(R.layout.fragment_main_favorite, container, false);
    
        //Inflate the layout for this fragment
        return viewFrag;
    }

    y el uso de este

     @Override
        public void setUserVisibleHint(boolean visible)
        {
            super.setUserVisibleHint(visible);
    
    
                if (visible)
                {
    
                    View v =  viewFrag ;
                    if (v == null) {
                        Toast.makeText(getActivity(), "ERROR ", Toast.LENGTH_LONG ).show();
                        return;
                    }
                }
    
        }
  6. 1

    Mi SightFragment.java aquí, debe restablecer los indicadores en onDestroyView():

    package cc.cubone.turbo.core.app;
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.view.View;
    /**
    * Fragment for handling view after it has been created and visible to user for the first time.
    *
    * <p>Specially in {@link android.support.v4.view.ViewPager}, the page will be created beforehand
    * but not be visible to user.
    *
    * <p>Call {@link android.support.v4.view.ViewPager#setOffscreenPageLimit(int)} to set the number of
    * pages that should be retained.
    *
    * Reference:
    * <ul>
    * <li><a href="http://stackoverflow.com/questions/10024739/how-to-determine-when-fragment-becomes-visible-in-viewpager">
    * How to determine when Fragment becomes visible in ViewPager</a>
    * </ul>
    */
    public class SightFragment extends Fragment {
    private boolean mUserSeen = false;
    private boolean mViewCreated = false;
    public SightFragment() {
    }
    /*public boolean isUserSeen() {
    return mUserSeen;
    }
    public boolean isViewCreated() {
    return mViewCreated;
    }*/
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (!mUserSeen && isVisibleToUser) {
    mUserSeen = true;
    onUserFirstSight();
    tryViewCreatedFirstSight();
    }
    onUserVisibleChanged(isVisibleToUser);
    }
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
    //Override this if you want to get savedInstanceState.
    mViewCreated = true;
    tryViewCreatedFirstSight();
    }
    @Override
    public void onDestroyView() {
    super.onDestroyView();
    mViewCreated = false;
    mUserSeen = false;
    }
    private void tryViewCreatedFirstSight() {
    if (mUserSeen && mViewCreated) {
    onViewCreatedFirstSight(getView());
    }
    }
    /**
    * Called when the new created view is visible to user for the first time.
    */
    protected void onViewCreatedFirstSight(View view) {
    //handling here
    }
    /**
    * Called when the fragment's UI is visible to user for the first time.
    *
    * <p>However, the view may not be created currently if in {@link android.support.v4.view.ViewPager}.
    */
    protected void onUserFirstSight() {
    }
    /**
    * Called when the visible state to user has been changed.
    */
    protected void onUserVisibleChanged(boolean visible) {
    }
    }
  7. 1

    Mientras que la mayoría de estas soluciones funciona, usted ni siquiera necesita para rastrear el estado por sí mismo.

    Con las versiones actuales de fo con el apoyo de la biblioteca hay un isResumed() método que no, probablemente lo que más se intenta lograr mediante el uso de un isStarted bandera:

    Devolver true si el fragmento está en la reanudación de estado. Esto es cierto para la duración de onResume() y onPause() así.

    Y, a continuación, es tan fácil como:

        @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isResumed()) {
    updateUi(isVisibleToUser);
    }
    }
  8. 1

    Que simple variante de trabajo en mi código:

    @Override
    public void onStart() {
    super.onStart();
    if (getUserVisibleHint()) {
    updateUI(); //your logic
    }
    }

    y

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isResumed() && isVisibleToUser) {
    updateUI(); //your logic
    }
    }
  9. 0

    Crear este código en tu setUserVisibleHint() :

    if(isVisibleToUser && getView() != null){
    isActive = true;
    init();
    }else if(isVisibleToUser && getView() == null){
    isActive = false;
    }else{
    isActive = true;
    }

    En su onCreateView() :

    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    if(!isActive){
    init();
    }
    }
  10. 0

    A CONTINUACIÓN TRABAJÓ PARA MÍ

    Por favor, cree una vista global como este

    private View view; 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
    //Inflate view layout
    view =inflater.inflate(R.layout.your_fragment, container, false);
    //return view
    return view;
    }

    y el uso de este

    @Override
    public void setUserVisibleHint(boolean isUserVisible)
    {
    super.setUserVisibleHint(isUserVisible);
    //When fragment is visible to user and view is not null then enter here.
    if (isUserVisible && view != null)
    {
    //do your stuff here.
    }
    }
  11. 0

    Esta es la mejor solución que he encontrado.

        @Override
    public void onCreateView() {
    super.onStart();
    if (getUserVisibilityHint()){
    //do stuff
    }
    }
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isResumed() && isVisibleToUser) {
    //do stuff
    }
    }

Dejar respuesta

Please enter your comment!
Please enter your name here