在片段中的onCreateView之前调用setUserVisibleHint

我在ViewPager工作,在ViewPager使用Fragment

在片段中的onCreateView()之前调用setUserVisibleHint()

我从支持库android.support.v4.app.Fragment使用Fragment

这是图书馆的问题吗?

我怎样才能摆脱它?

编辑

我重写setUserVisibleHint()而不是调用超级来摆脱它。

 @Override public void setUserVisibleHint(boolean isVisibleToUser) { //FIXED: setUserVisibleHint() called before onCreateView() in Fragment causes NullPointerException //super.setUserVisibleHint(isVisibleToUser); } 
 // 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实例variables来决定是否在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()方法中获取数据。 🙂

你可以使用这个逻辑,也可以通过设置isVisible = false来closuresviewDidAppear

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

下面为我​​工作 ….

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

我find了最好的解决scheme

 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 } 

这是namrouti的答案的改进版本。 我在很多条件下testing了这个。 它是安全的。

我的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) { } } 

以下为我工作

请创build一个像这样的全局视图

 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 visible to user and view is not null then enter here. if (isUserVisible && view != null) { // do your stuff here. } } 

setUserVisibleHint()中创build这个代码:

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

在你的onCreateView()中

 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { if(!isActive){ init(); } } 
 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 } } } }