我们大多在开发时都使用的viewpager+fragment的布局形式,这里面存在着很多小问题。
问题:
1,fragment适配器会实例化所有的fragment对象。
2,默认会加载后一个的布局。
3,每次都会执行fragment的onCreateView方法。
4,布局会重叠。
5,很难掌控数据请求。
.......
有这么多问题,但我们仍然还是在使用,所以这些问题就必须解决
在使用viewpager+fragment的适配器管理方式时,不是用show()和hide()来显示和隐藏fragment的时。
最理想的状态就是,数据只加载一次,并且布局不会重叠。
网上大多说的懒加载都只有两个判断条件:
1,布局是否加载完;
2,是否可见;
我这里还要加第三个判断条件:
3,是否是第一次可见(如果是第二次可见,我们也是不需要再次加载fragment的,因为我们的fragment一直都没有销毁);
直接贴代码:
package com.example.lazy_fragment.fragment; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; import com.example.lazy_fragment.Main2Activity; import com.example.lazy_fragment.R; import java.util.ArrayList; /** * A simple {@link Fragment} subclass. */ public class F2 extends Fragment implements View.OnClickListener { private View root = null;//布局是否存在,存在就不再添加,不然会重叠 private ListView listView; private boolean isVisible = false;//是否可见 private boolean isPrepared = false;//布局是否加载好 private boolean isFirstVisible = true;//是否第一次看见 private TextView tv_open2; public F2() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment System.out.println("执行了f2"); if (root == null) { root = inflater.inflate(R.layout.fragment_f2, container, false); } isPrepared = true; initView(root); return root; } private void initView(View root) { if (!isPrepared || !isVisible) { return; } System.out.println("f2布局初始化完成"); listView = (ListView) root.findViewById(R.id.listView); tv_open2 = (TextView) root.findViewById(R.id.tv_open2); tv_open2.setOnClickListener(this); initData(); } //可以单独的进行数据请求 private void initData() { System.out.println("f2数据初始化完成"); ArrayList list_data = new ArrayList(); for (int i = 0; i < 20; i++) { list_data.add("我是条目====" + i); } ArrayAdapter adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, list_data); listView.setAdapter(adapter); } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); System.out.println("现在的状态setUserVisibleHint:" + isVisibleToUser); if (getUserVisibleHint()) { System.out.println("F2可见"); isVisible = true; if (isFirstVisible) {//如果第一次看见,我们加载布局并请求数据 isFirstVisible = false; initView(root); } } else {//不可见我们执行其他操作 isVisible = false; System.out.println("F2不可见"); } } @Override public void onHiddenChanged(boolean hidden) {//这种方法不会调用,我们不是用的show()和hide()方法 super.onHiddenChanged(hidden); System.out.println("现在的状态onHiddenChanged:" + hidden); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.tv_open2: startActivity(new Intent(getActivity(), Main2Activity.class)); break; default: break; } } }
这就是模板,直接套用就可以了。要封装也是可以的。
再一次对fragment进行了理解
//--------end------------