在片段中的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 } } } }
- Android:具有多个可点击button的ListView元素
- 检测Android上的networking连接types
- Android – 使滑动抽屉滑动从左到右
- 如何在android中使用getSharedPreferences
- 电话:用于文本input的数字键盘
- 在android中使用GSONparsing带有dynamic“键”和“值”的JSON
- Android(JSONObject)如何通过平面JSON对象循环来获取每个键和每个值
- 在没有AlertDialog的情况下,多select微调器
- ksoap2 org.xmlpull.v1.xmlpullparserexception预计的start_tag错误