在片段第一次可见后立即执行代码

时间:2015-09-03 14:37:10

标签: android fragment lifecycle

我有一个片段,显示使用MPAndroidChart创建的折线图。加载片段大约需要200毫秒。

我想通过在片段可见后立即加载图表数据数据来提高感知的应用性能。

因此我需要在片段变得可见之后立即执行代码,但只有第一次它变得可见。

我不能使用onResume(),因为它在片段可见之前被调用。

注意:我不能使用异步任务,需要在UI线程上完成。

5 个答案:

答案 0 :(得分:7)

public class MyFragment extends Fragment{
  Boolean _areLecturesLoaded =false;
  @Override
  onCreateView(){
    //Inflate the required views. Code gets executed once View is made but not shown
    return v;
}
@Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        //Code executes EVERY TIME user views the fragment

        if (isVisibleToUser && !_areLecturesLoaded ) {
            _areLecturesLoaded = true;
            // Code executes ONLY THE FIRST TIME fragment is viewed.
        }
    }
}

isVisisbleToUser是内置的,当用户正在查看当前片段时,它是真的。在用户第一次看到片段之前,它将保持为假。如果您希望每次用户查看片段时都执行一些代码,请将代码放在此区域中但在if语句之外。

_areLecturesLoaded初始化为false,并且第一次将片段设置为true时,将其设置为true,以确保将来不会调用If语句,并且仅在此时执行代码

所有初始化视图窗口小部件按钮等必须在onCreate()中完成,以确保不会出现空指针和其他此类讨厌的异常。

答案 1 :(得分:1)

在UI线程上做任何冗长的事情都是不好的做法 - 你将在整个UI中处理你的处理时间(因为只有一个UI线程)。 200ms实际上非常长,它是1/5秒,很容易被人眼检测到,想象你以5fps的帧速率玩游戏。

感知性能完全不是因为UI滞后。

使用AsyncTaskAsyncTaskLoader处理您的数据,将在UI线程上调用回调,因此不必担心。您可以通过将数据存储在例如成员变量中来控制它是否是一次性的。如果它是null - 加载,如果没有 - 立即使用。

如果您的数据相当静态且不是很大 - 在打开片段之前预先加载它(例如,当Activity启动时,或者甚至在应用程序启动时),并在执行时将数据传递给片段(通过一个Bundle参数。)

答案 2 :(得分:1)

可以使用静态布尔变量来实现。我使用下面的代码仅在第一次启动应用程序时显示进度对话框。

public class SettingsFragment extends Fragment {

    static boolean _areLecturesLoaded = true;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_settings, container, false);

        return rootView;
    }

    private class Getlimits extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pd = ProgressDialog.show(getActivity(), "", "Loading...", true);
            pd.setCancelable(false);
        }

        @Override
        protected Void doInBackground(Void... arg0) {
            //your background code
            if(_areLecturesLoaded) {
                try {
                    Thread.sleep(3500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            // Dismiss the progress dialog
            if (pd.isShowing())
                pd.dismiss();
            _areLecturesLoaded = false;
        }
    }
}

答案 3 :(得分:1)

定义和覆盖

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

}

然后在这两行中放入onCreateView()函数

      setUserVisibleHint(false);
      setUserVisibleHint(true);

然后将您要完成的代码放在onStart()函数的片段开始处

@Override
public void onStart() {
    super.onStart();
     //your initial code is here.
}

答案 4 :(得分:0)

将它放在onViewCreated()方法中。