我有一个片段,显示了用MPAndroidChart创建的折线图。加载片段大约需要200毫秒。
我想通过在片段变得可见后加载图表数据数据来提高应用程序的感知性能。
因此,我需要在片段变为可见之后立即执行代码,但仅在它第一次变为可见时执行。
我不能使用onResume(),因为它在片段可见之前被调用。
注意:我不能使用异步任务,它需要在ui线程上完成。
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是内置的,当用户查看当前片段时为true。在用户第一次看到这个片段之前,它将保持为假。如果你想让一些代码在每次用户查看片段时执行,把代码放在这个区域,但在If语句之外。
_areLecturesLoaded被初始化为false,一旦片段第一次被调用,它就被设置为true,确保If语句在将来不会被调用,并且其中的代码只执行一次
视图、小部件、按钮等的所有初始化都必须在onCreate()中完成,以确保没有空指针和其他此类讨厌的异常的可能性。
在UI线程上做任何冗长的事情都是不好的做法——您将在处理过程中阻塞整个UI(因为只有一个UI线程)。200ms其实很长,它是1/5秒,很容易被人眼察觉,想象你在玩一个5fps的游戏。
感知性能就是永远不会有UI延迟。
使用AsyncTask
或AsyncTaskLoader
来处理你的数据,回调将在UI线程上调用,所以不用担心。您可以通过将数据存储在成员变量中来控制它是否是一次性的。如果是null
——加载,如果不是——立即使用。
如果你的数据是相当静态的,不是很大-预加载它之前,你的片段打开(说,当活动开始,甚至当应用程序启动),只是通过数据片段时(通过Bundle
参数)。
可以通过使用静态布尔变量来实现。我使用下面的代码只在应用程序第一次启动时显示进度对话框。
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;
}
}
}
定义和覆盖
@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.
}
放到onViewCreated()方法中