我使用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<Fragment> items; public LazyFragmentAdapter(@NonNull FragmentManager fm, int behavior) { super(fm, behavior); } public void setItems(List<Fragment> list){ this.items = list; } public List<Fragment> 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<Fragment> getItems() { ArrayList<Fragment> 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); }