在Fragment中的onCreateView之前调用setUserVisibleHint

Ami*_*dav 59 android callback android-fragments

我在那里工作ViewPager和使用Fragment我找到了

在Fragment中的onCreateView()之前调用setUserVisibleHint()

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

这是图书馆的问题吗?

我怎么能摆脱它?

编辑

我重写setUserVisibleHint()而不是调用super来摆脱它.

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    //FIXED: setUserVisibleHint() called before onCreateView() in Fragment causes NullPointerException
    //super.setUserVisibleHint(isVisibleToUser);
}
Run Code Online (Sandbox Code Playgroud)

vik*_*koo 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;
    }
} 
Run Code Online (Sandbox Code Playgroud)

使用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
}
Run Code Online (Sandbox Code Playgroud)

此代码将解决您的问题.因为它解决了我的问题.:)

此技巧将获取数据onCreateView()以便从一个页面直接跳转到另一个页面,而当您滑动视图时,它将从setUserVisibleHint()方法中获取数据.:)

  • @vikoo你是否建议我们不应该检查`isVisibleToUser`是真还是假?在你的第一个例子中为什么不检查`isVisibleToUser`是否为真,然后检查`getView()`是否为空. (5认同)
  • 我们的应用程序中isVisibleToUser标志不是trustworty.我们观察它在视图可见之前(有时,至少)变为真.我必须在此解决方案中创建一个本地标志.推荐的. (3认同)

Far*_*uti 33

您可以使用此逻辑,也可以viewDidAppear通过设置随时关闭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
    }
}
Run Code Online (Sandbox Code Playgroud)


DrM*_*eza 13

我找到了最好的解决方案

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
}
Run Code Online (Sandbox Code Playgroud)

这是改编版本的namrouti的回答.我在很多条件下测试了这个.它是安全的.


小智 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();
          }
    }
}
Run Code Online (Sandbox Code Playgroud)