android懒加载简书,Android中ViewPager+Fragment懒加载解
决⽅案
⽂/程序员男神
前⾔
最近医院上线,我们开发都奔赴医院现场⽀持,每天加班到很晚。⾃⼰也搞的精神不振,还好都把问题解决了。后⾯的⼏天轻松了不少。本⽂就是最近在开发新需求遇到的问题,记录下来以便后⾯供⾃⼰参考。
aj
问题描述
在android开发中,经常会⽤到ViewPager+Fragment来实现切换Tab页。但是,由于ViewPager的内部机制,它总会默认⾄少预加载⼀个页⾯。
因为有时候⽤户希望选择了哪个Tab再去加载哪个Tab的数据,⽽不是预加载,如果当前页⾯和预加载页⾯都需要实时刷新当前Fragment,或者有⼤量的⽹络请求,可能就会⽐较慢。
解决⽅案1:
ViewPager因为内部机制,有预加载机制。那我们直接把ViewPager的预加载设置为0不就可以了?
vp.setOffscreenPageLimit(0);
查看源码:
/**
* Set the number of pages that should be retained to either side of the
* current page in the view hierarchy in an idle state. Pages beyond this
* limit will be recreated from the adapter when needed.
*
*
This is offered as an optimization. If you know in advance the number
* of pages you will need to support or have lazy-loading mechanisms in place
* on your pages, tweaking this setting can have benefits in perceived smoothness
* of paging animations and interaction. If you have a small number of pages (3-4)
* that you can keep active all at once, less time will be spent in layout for
* newly created view subtrees as the user pages back and forth.
*
*
You should keep this limit low, especially if your pages have complex layouts.
* This setting defaults to 1.
*
* @param limit How many pages will be kept offscreen in an idle state.
*/
public void setOffscreenPageLimit(int limit) {
if (limit < DEFAULT_OFFSCREEN_PAGES) {
Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " + DEFAULT_OFFSCREEN_PAGES);
limit = DEFAULT_OFFSCREEN_PAGES;
}
if (limit != mOffscreenPageLimit) {
mOffscreenPageLimit = limit;
populate();
}
}
我们分析得知:即使设置为0,也会把limit设置为默认值1。
解决⽅案2:
package com.winning.rims.tabtest.tst;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
/**
* Fragment预加载问题的解决⽅案:
* 1.可以懒加载的Fragment
* 2.切换到其他页⾯时停⽌加载数据(可选)
* Created by dj on 2018-09-10.
*/
public abstract class BaseFragment extends Fragment {
/**
* 视图是否已经初初始化
*/
protected boolean isInit = false;
protected boolean isLoad = false;
protected final String TAG = "BaseFragment";
private View view;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { view = inflater.inflate(setContentView(), container, false);
isInit = true;
/**初始化的时候去加载数据**/
isCanLoadData();
return view;
}
/**
* 视图是否已经对⽤户可见,系统的⽅法
*/
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
isCanLoadData();
}
/**
* 是否可以加载数据
* 可以加载数据的条件:
* 1.视图已经初始化
* 2.视图对⽤户可见
*/
private void isCanLoadData() {
if (!isInit) {
return;
}
if (getUserVisibleHint()) {
lazyLoad();
isLoad = true;
} else {
if (isLoad) {
stopLoad();
}
}
}
/**
* 视图销毁的时候讲Fragment是否初始化的状态变为false
*/
@Override
public void onDestroyView() {
isInit = false;
isLoad = false;
}
protected void showToast(String message) {
if (!TextUtils.isEmpty(message)) {
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show(); }
}
/**
* 设置Fragment要显⽰的布局
*
* @return 布局的layoutId
*/
protected abstract int setContentView();
/**
* 获取设置的布局
*
* @return
*/
protected View getContentView() {
return view;
}
/
**
* 出对应的控件
*
* @param id
* @param
* @return
*/
protected T findViewById(int id) {
return (T) getContentView().findViewById(id);
}
/**
android radiogroup* 当视图初始化并且对⽤户可见的时候去真正的加载数据
*/
protected abstract void lazyLoad();
/**
* 当视图已经对⽤户不可见并且加载过数据,如果需要在切换到其他页⾯时停⽌加载数据,可以调⽤此⽅法
*/
protected void stopLoad() {
}
}
⽅案2的⽤法:
(1)、创建新的Fragment类,继承BaseFragment;
(2)、setContentView(),返回该xml布局⽂件;
(3)、lazyLoad(),在此⽅法内加载需要的数据;
(4)、stopLoad()⽅法可选,当视图已经对⽤户不可见并且加载过数据,如果需要在切换到其他页⾯时停⽌加载数据,可以覆写此⽅法。package com.winning.rims.tabtest.tst;
import android.util.Log;
import com.winning.rims.tabtest.R;
/**
* 描述: Fragment1
* 作者|时间: djj on 2018/9/11 16:14
*
*/
public class Fragment1 extends BaseFragment {
@Override
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论