web-dev-qa-db-ja.com

フラグメントのonCreateViewの前に呼び出されるsetUserVisibleHint

私はViewPagerに取り組んでおり、Fragmentを使用しています

フラグメントのonCreateView()の前に呼び出されるsetUserVisibleHint()

サポートライブラリAndroid.support.v4.app.FragmentFragmentを使用しています

これはライブラリの問題ですか?

どうすればそれを取り除くことができますか?

[〜#〜] edit [〜#〜]

SetUserVisibleHint()をオーバーライドし、superを呼び出して削除しません。

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    //FIXED: setUserVisibleHint() called before onCreateView() in Fragment causes NullPointerException
    //super.setUserVisibleHint(isVisibleToUser);
}
59
Amit Yadav
_// 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;
    }
} 
_

isViewShownインスタンス変数を使用して、onCreateView()またはsetUserVisibleHint()のどちらでデータをフェッチするかを決定します。

以下のコードには、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
}
_

このコードは問題を解決します。それは私の問題を解決しました。 :)

このトリックは、あるページから別のページに直接ジャンプするためにonCreateView()のデータをフェッチしますが、ビューをスワイプするとsetUserVisibleHint()メソッドからデータをフェッチします。 :)

90
vikoo

このロジックを使用できます。また、isVisible = falseを設定することにより、いつでもviewDidAppearをオフにできます。

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

最適なソリューションが見つかりました

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
}

運命ナムルーティの答えの改良版です。 これを多くの条件でテストしました。安全です。

13
DrMorteza
@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();
          }
    }
}
4
Gev Kostanyan

私の下で働いた ....

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

これを使う

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

    }
3
Vijay

その単純なバリアントは私のコードで動作します:

@Override
public void onStart() {
    super.onStart();

    if (getUserVisibleHint()) {
        updateUI(); // your logic
    }
}

そして

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if (isResumed() && isVisibleToUser) {
       updateUI(); // your logic
    }
}
1
V.March

このソリューションのほとんどは機能しますが、自分で状態を追跡する必要さえありません。

サポートライブラリの現在のバージョンには、isResumed()メソッドがあり、おそらくほとんどの人がisStartedフラグを使用して達成しようとしています。

フラグメントが再開状態の場合、trueを返します。これは、onResume()およびonPause()の期間にも当てはまります。

そして、それは次のように簡単です:

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

私の SightFragment.Java ここで、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) {
    }

}
1
joinAero
public class MyFragment extends Fragment {

private boolean manageVisibility;


public MyFragment() {
    // Required empty public constructor
}

public static CommunityFragment newInstance() {

    Bundle args = new Bundle();

    CommunityFragment fragment = new CommunityFragment();
    fragment.setArguments(args);
    return fragment;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    manageVisibility = true;
    return inflater.inflate(R.layout.fragment_community, container, false);
}


@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if (manageVisibility && isVisibleToUser) {
       // fragment is visible
        }
    } else if (manageVisibility) {
       // fragment is invisible
        }
    }
  } 
}
0
Levon Petrosyan

私のために働いた以下

このようなグローバルビューを作成してください

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

これを使う

@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.
            }
    }
0
Rahul

これは私が見つけた最高のソリューションです。

    @Override
    public void onCreateView() {
        super.onStart();
        if (getUserVisibilityHint()){
            //do stuff
        }
    }

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