我使用viewpager+fragment实现懒加载。代码如下:
1.fragment
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
/**
* @author zsl
* @date 2019/11/22.
*/
public abstract class LazyFragment extends Fragment {
private View root;
protected boolean isLoaded;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (root==null){
root = inflater.inflate(getLayoutResource(),container,false);
}
isLoaded = false;
initView(root);
return root;
}
@Override
public void onResume() {
super.onResume();
if (!isLoaded){
lazyLoad(true);
}
}
@Override
public void onPause() {
super.onPause();
if (!isLoaded){
lazyLoad(false);
}
}
@Override
public void onDestroy() {
super.onDestroy();
}
protected void log(String s){
Log.e("LazyFragment",s);
}
/**
* 初始化资源控件
*
* @param view root
*/
protected abstract void initView(View view);
/**
* 获取布局资源
*
* @return layout resource id
*/
protected abstract int getLayoutResource();
/**
* 是否需要懒加载
* @param startLoad true 需要懒加载,false 不需要懒加载
*/
protected void lazyLoad(boolean startLoad){}
/**
* 子类数据未获取,需要重新获取数据
*
* 如果需要重新获取,子类生命周期再次走到 onResume 时,会重新加载数据
*
* @param reload 是否需要重新获取
*/
protected void loaded(boolean loaded){
isLoaded = loaded;
log("数据需要重新加载");
}
}
2.adapter
import java.util.List;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
/**
* @author zsl
* @date 2019/11/22.
*/
public class LazyFragmentAdapter extends FragmentStatePagerAdapter {
private List items;
public LazyFragmentAdapter(@NonNull FragmentManager fm, int behavior) {
super(fm, behavior);
}
public void setItems(List list){
this.items = list;
}
public List getItems() {
return items;
}
@NonNull
@Override
public Fragment getItem(int position) {
return items==null?null:items.get(position);
}
@Override
public int getCount() {
return items==null?0:items.size();
}
}
3.使用:
import android.os.Bundle;
import com.zsl.appmarket.R;
import com.zsl.appmarket.app.ui.fragment.Fragmeng1;
import com.zsl.appmarket.app.ui.fragment.Fragmeng2;
import com.zsl.appmarket.app.ui.fragment.Fragmeng3;
import com.zsl.appmarket.app.ui.fragment.Fragmeng4;
import com.zsl.appmarket.app.ui.fragment.Fragmeng5;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.ViewPager;
import static androidx.fragment.app.FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT;
/**
* @author zsl
* @date 2019/11/22.
*/
public class LazyFragmentTest extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lazy_fragment);
ViewPager vp = findViewById(R.id.vp);
final LazyFragmentAdapter adapter = new LazyFragmentAdapter(getSupportFragmentManager(), BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
adapter.setItems(getItems());
vp.setAdapter(adapter);
}
private List getItems() {
ArrayList items = new ArrayList<>();
items.add(Fragmeng1.newInstance());
items.add(Fragmeng2.newInstance());
items.add(Fragmeng3.newInstance());
items.add(Fragmeng4.newInstance());
items.add(Fragmeng5.newInstance());
return items;
}
4.自定义的viewpager:
(由于原生的viewpager的高度不会随子item高度改变,即设置子item高度无效,所以自定义viewpager)
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.ViewPager;
/**
* @author zsl
* @date 2019/11/22.
*/
public class CustomViewPager extends ViewPager {
public CustomViewPager(@NonNull Context context) {
super(context);
}
public CustomViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
for (int i = 0,len = getChildCount(); i < len; i++) {
View child = getChildAt(i);
ViewGroup.LayoutParams lp = child.getLayoutParams();
int childWidth = getChildMeasureSpec(widthMeasureSpec, 0, lp.width);
int childHeight = getChildMeasureSpec(heightMeasureSpec, 0, lp.height);
child.measure(childWidth,childHeight);
int measuredHeight = child.getMeasuredHeight();
height = Math.max(measuredHeight,height);
}
heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(height,MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
5.对于是需要懒加载,根据LazyFragment子类实际业务决定。
@Override
protected void lazyLoad(boolean startLoad) {
log("Fragmeng1 lazyLoad:"+startLoad);
//根据是否已经获取到数据,来传入true或false调用loader方法告知父类下次切换回来是否需要重新加载数据
loaded(false);
}