ViewPager+Fragment研究总结
来源:互联网 发布:淘宝美工网上兼职 编辑:程序博客网 时间:2024/06/18 06:54
viewpager+fragment在日常的开发中经常用到,viewpager为了提高用户进行左右切换时的流畅度,实现了一套预加载的功能,在默认情况下,viewpager会预加载一个页面(默认情况下为1,可以自己设置),即当你使用viewpager+fragment时,除了当前可见的第一个fragment会被加载之外,这个fragment后面的一个fragment也会被加载,这样用户进行切屏时就会更为流畅。但是在一些特殊情况下,我们可能不需要预加载的功能,我们更希望当fragment对用户可见时才进行加载或者是网络请求或者是特殊的操作(友盟统计页面访问情况等)。
这次的预期效果就是当fragment对用户可见时才进行网络请求,其中网络请求是通过AsyncTask实现的延迟操作。先看下效果图。
具体实现很简单,主要是通过fragment中setUserVisibleHint(boolean isVisibleToUser)方法进行当前fragment是否可见的判断。只有当此时的fragment对用户可见并且已经被创建才进行网络请求。在网络请求成功后加一个标示,防止来回切pagerview时进行重复的网络请求。下面看下源码。
public class MyFragment extends Fragment { private boolean isVisible = false;//fragment 可见标示 private boolean isCreated = false;//fragment 已经被加载标示 private boolean hasLoaded = false;//fragment 已做过网络请求标示 private String contentStr; private TextView content; private LinearLayout layout; public static final String KEY = "FRAGMENT_KEY"; private String TAG = "fragment"; public static MyFragment newInstance(String content) {//初始化fragment MyFragment fragment = new MyFragment(); Bundle bundle = new Bundle(); bundle.putString(KEY, content); fragment.setArguments(bundle); return fragment; } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if(layout==null){ layout = (LinearLayout) inflater.inflate(R.layout.fragment, container, false); content = (TextView) layout.findViewById(R.id.content); Bundle bundle = getArguments(); if (bundle != null) { contentStr = bundle.getString(KEY); } isCreated = true; loading(" in onCreateView "); Log.v(TAG, contentStr + " isCreated "); return layout; }else{ Log.v(TAG, contentStr + " layout != null "); return layout; } } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (isVisibleToUser) { isVisible = true; } else { isVisible = false; } loading(" in setUserVisibleHint "); } private void loading(String str) { if (hasLoaded) { return; } if (isCreated && isVisible) {//可见并且已经被创建时,做网络请求 UIHelper.showDialogForLoading(getActivity(), "正在加载...", true); Log.v(TAG, contentStr + str + "--->loading "); new AsyncTask<Void, Void, Boolean>() { @Override protected Boolean doInBackground(Void... params) { try { Thread.sleep(2000); } catch (Exception e) { e.printStackTrace(); return false; } return true; } @Override protected void onPostExecute(Boolean aBoolean) { if (aBoolean) { hasLoaded = true; content.setText(contentStr); UIHelper.hideDialogForLoading(); } } }.execute(); } }}
我们在关键的地方打一下log,看下loading方法是在oncreatView中执行还是在setUserVisibleHint中执行。
在再看下MainActivity的源码。
public class MainActivity extends AppCompatActivity { private ViewPager viewPager; private ArrayList<MyFragment> fragments=new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager= (ViewPager) findViewById(R.id.view_pager); fragments.add(MyFragment.newInstance("first fragment")); fragments.add(MyFragment.newInstance("second fragment")); fragments.add(MyFragment.newInstance("third fragment")); MyFragmentAdapter adapter=new MyFragmentAdapter(getSupportFragmentManager(),fragments); viewPager.setAdapter(adapter); } class MyFragmentAdapter extends FragmentPagerAdapter{ private ArrayList<MyFragment> fragments; public MyFragmentAdapter(FragmentManager fm,ArrayList<MyFragment> fragments) { super(fm); this.fragments=fragments; } @Override public Fragment getItem(int position) { return fragments.get(position); } @Override public int getCount() { return fragments.size(); } }}
下面看下log。这是第一次运行时的log。
first fragment in onCreateView --->loadingfirst fragment isCreatedsecond fragment isCreated
因为viewPager在默认情况下,会预加载一个页面。(可以通过setOffscreenPageLimit设置预加载页面数)。所以当只是第一个fragment对用户可见时,第二个fragment已经被加载好了。并且第一个fragment是在onCreateView 中执行的loading方法,原因是此时setUserVisibleHint方法在onCreateView 之前调用但是此时isCreated为false所以无法执行网络请求。
下面切到到第二个fragment,此时的log。
second fragment in setUserVisibleHint --->loadingthird fragment isCreated
此时第二个fragment因为已经被加载好了,并且在setUserVisibleHint方法中得知以为可见状态,所以执行了loading方法。于此同时第三个fragemnt也已经被加载。下面切到第三个fragment。
third fragment in setUserVisibleHint --->loading
与之前同理,因为此前第三个fragment已经被加载,而且此时对用户可见,可以执行loading方法。
最后贴一下工具类的代码。
public class UIHelper {
private static Dialog mLoadingDialog;public static void showDialogForLoading(Activity context, String msg, boolean cancelable) { if(context==null){ return; } View view = LayoutInflater.from(context).inflate(R.layout.loading_dialog, null); TextView loadingText = (TextView)view.findViewById(R.id.dialog_content); loadingText.setText(msg); mLoadingDialog = new Dialog(context, R.style.loading_dialog_style); mLoadingDialog.setCancelable(cancelable); mLoadingDialog.setContentView(view, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); mLoadingDialog.show();}public static void hideDialogForLoading() { if(mLoadingDialog != null && mLoadingDialog.isShowing()) { mLoadingDialog.cancel(); }}
}
- ViewPager+Fragment研究总结
- ViewPager+Fragment收集研究
- Viewpager+Fragment组合研究
- ViewPager + Fragment 用法总结
- TabHost fragment 和 Viewpager 总结
- activity fragment viewpager的总结
- Android Tab大总结 Fragment+TabPageIndicator+ViewPager
- Fragment+ViewPager
- Viewpager&Fragment
- viewpager + fragment
- viewpager+fragment
- viewpager+fragment
- ViewPager+Fragment
- viewPager+fragment
- ViewPager+Fragment
- ViewPager+Fragment
- viewpager+fragment
- Fragment+ViewPager
- 分布式日志收集系统Apache Flume的设计介绍
- glew库配置:无法识别的外部符号 glewInit()
- linux下如何查看某个软件 是否安装??? 安装路径在哪???
- MPLSVPN 命令集
- ios开发之常用的NSLOG日志打印格式
- ViewPager+Fragment研究总结
- python NumPy函数库基础
- 2012 ACM/ICPC Asia Regional Changchun Online(hdu 4267 - 4277)线段树+dp+dfs+树形dp
- iOS网络开发——JSON数据解码(使用NSJSONSerialization)
- Microsoft Avro简介及配置实战
- Spring注解
- 二维码ZXing
- 解决ERROR ITMS-90046: "Invalid Code Signing Entitlements.
- 程序员的年龄天花板