ViewPager实现Fragment懒加载

Fragment生命周期

Fragment的生命周期可以参考文章:

http://blog.csdn.net/lmj623565791/article/details/37970961

ViewPager实现首页

首页使用的是ViewPager和Fragment来实现,首页效果图:
首页
但是Fragment的复杂的生命周期就会带来一个问题,比如我们刚打开APP,这个时候我们只想AFragment加载数据,而其他的页面的数据并不加载.但是真实的情况是,当AFragment可见,BFragment的数据也会同时加载.这是因为使用ViewPager是会预加载Fragment的临近的Fragment,虽然临近的Fragment是不可见的但是他的OnResume方法其实已经执行了,如果我们的网络初始化函数 写在onCreateView里面,显然是不合适.下面我们来看一具体的日志信息.
1.刚进入APP:
这里写图片描述
这个时候,A和B的页面逻辑同时加载完毕,如果在onCreateView里面有网络请求的逻辑,显然这样的效果不是,我们需要的.
2.单击BFragment:
这里写图片描述
在BFragment可见是,由于之前BFragment的onResume已经执行完毕,所以BFragment不会继续执行他的生命周期,这样时候会预加载CFragment.
4.单击CFragment:
这里写图片描述
这个时候,在预加载DFragment的时候,也会同时执行AFragment的onDestoryView方法即将Fragment的View被移除.
5.单击DFragment:
这里写图片描述
由于D Fragment的onResume方法已经执行完毕,所以BFragment的onDestoryView会执行.
6:在次回去单击CFragment:
这里写图片描述
7:再次回去单击AFragment:
这里写图片描述

setUserVisibleHint和getUserVisibleHint方法

getUserVisibleHint该方法用于告诉系统,这个Fragment的UI是否是可见.setUserVisibleHint方法是系统的方法,setUserVisibleHint方法是优先于onAttach方法执行的.在该方法内我们可以通过getUserVisibleHint方法获取到当前的Fragment是否可见.如果可见设置isVisible为true.如果不可见设置为false.
代码:
BaseFragment:

public abstract class BaseFragment extends Fragment
{

    //当前的Fragment是否可见
    protected boolean isVisible ;

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        Log.i("TAG",this.toString() +"  setUserVisibleHint");
        if(getUserVisibleHint())
        {
            isVisible = true;
            onVisible();
        }
        else
        {
            isVisible = false;
            onInVisible();
        }
    }

    /**
     * 当Fragment可见时执行的函数
     */
    private void onVisible()
    {
        lazyLoad();
    }

    /**
     * 当Fragment不可见执行的函数
     */
    private void onInVisible()
    {

    }
    protected abstract void lazyLoad();
}



MainActivity:

public class MainActivity extends FragmentActivity implements View.OnClickListener{
private List list = new ArrayList<>();
private AFragment aFragment;
private BFragment bFragment;
private CFragment cFragment;
private DFragment dFragment;

private ViewPager mvp;
private LinearLayout merchant_lay;
private LinearLayout order_lay;
private LinearLayout privilege_lay;
private LinearLayout mine_lay;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initFragment();
    initView();
    MyAdapter adapter = new MyAdapter(this.getSupportFragmentManager(),list);
    mvp.setAdapter(adapter);
    mvp.setCurrentItem(0);
}

private void initFragment()
{
    aFragment = new AFragment();
    bFragment = new BFragment();
    cFragment = new CFragment();
    dFragment = new DFragment();
    list.add(aFragment);
    list.add(bFragment);
    list.add(cFragment);
    list.add(dFragment);
}

private void initView()
{
    mvp = (ViewPager)this.findViewById(R.id.mvp);
    merchant_lay = (LinearLayout)this.findViewById(R.id.merchant_lay);
    order_lay = (LinearLayout)this.findViewById(R.id.order_lay);
    privilege_lay = (LinearLayout)this.findViewById(R.id.privilege_lay);
    mine_lay = (LinearLayout)this.findViewById(R.id.mine_lay);


    merchant_lay.setOnClickListener(this);
    order_lay.setOnClickListener(this);
    privilege_lay.setOnClickListener(this);
    mine_lay.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    switch (v.getId())
    {
        case R.id.merchant_lay:
            mvp.setCurrentItem(0);
            break;
        case R.id.order_lay:
            mvp.setCurrentItem(1);
            break;
        case R.id.privilege_lay:
            mvp.setCurrentItem(2);
            break;
        case R.id.mine_lay:
            mvp.setCurrentItem(3);
            break;
    }
}

}


Adapter:

public class MyAdapter extends FragmentPagerAdapter {
    private List<Fragment> mList;
    public MyAdapter(FragmentManager fm,List<Fragment> list) {
        super(fm);
        this.mList = list;
    }

    @Override
    public int getCount() {
        return mList != null ? mList.size() : 0;
    }

    @Override
    public Fragment getItem(int position) {
        return mList != null ? mList.get(position) : null;
    }
}


AFragmnet:

public class AFragment extends BaseFragment {
private static final String TAG = AFragment.class.getSimpleName();
//标志是否已经加载完毕
private boolean isPrepared;
//是否已经加载过一次,第二次则不加载。
private boolean mHasLoadedOnce = false;
@Override
public void onAttach(Context context) {
Log.i(“TAG”, TAG + ” onAttach”);
super.onAttach(context);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    Log.i("TAG", TAG + "  onCreate");
    super.onCreate(savedInstanceState);
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Log.i("TAG", TAG + "  onCreateView");
    View view = inflater.inflate(R.layout.fragment_a,container,false);
    isPrepared = true;
    lazyLoad();
    return view;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    Log.i("TAG", TAG + "  onActivityCreated");
    super.onActivityCreated(savedInstanceState);
}

@Override
public void onStart() {
    Log.i("TAG", TAG + "  onStart");
    super.onStart();
}

@Override
public void onResume() {
    Log.i("TAG", TAG + "  onResume");
    super.onResume();
}


@Override
public void onStop() {
    Log.i("TAG", TAG + "  onStop");
    super.onStop();
}

@Override
public void onPause() {
    Log.i("TAG", TAG + "  onPause");
    super.onPause();
}

@Override
public void onDestroyView() {
    Log.i("TAG", TAG + "  onDestroyView");
    super.onDestroyView();
}

@Override
public void onDestroy() {
    Log.i("TAG", TAG + "  onDestroy");
    super.onDestroy();
}


@Override
public void onDetach() {
    Log.i("TAG", TAG + "  onDetach");
    super.onDetach();
}

@Override
protected void lazyLoad()
{
    Log.i("TAG", TAG +"   lazy" + isPrepared + "   " + isVisible + "  " + mHasLoadedOnce);
    if (!isPrepared || !isVisible || mHasLoadedOnce) {
        return;
    }
    mHasLoadedOnce = true;
}

}

ViewPager的不可滑动设置

public class MyViewPager extends ViewPager {

    private boolean isCanScroll = false;

    public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public void setScanScroll(boolean isCanScroll) {
        this.isCanScroll = isCanScroll;
    }

    @Override
    public void scrollTo(int x, int y) {
        super.scrollTo(x, y);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent arg0) {
        if (isCanScroll) {
            return super.onInterceptTouchEvent(arg0);
        } else {
            return false;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent arg0) {
        if (isCanScroll) {
            return super.onTouchEvent(arg0);
        } else {
            return false;
        }
    }

}

布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <RelativeLayout
        android:id="@+id/main_activity_layout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:background="#CE112D"
        android:gravity="center_vertical"
        android:orientation="vertical" >


        <com.example.dengquan.lazyloadmodule.viewpager.MyViewPager
            android:id="@+id/mvp"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="@android:color/white"
            android:layout_above="@+id/bottomView">
        </com.example.dengquan.lazyloadmodule.viewpager.MyViewPager>

        <include
            android:id="@id/bottomView"
            layout="@layout/bottom_view"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_alignParentBottom="true"/>
    </RelativeLayout>
</LinearLayout>

补充

如果想更新某个Fragment可以通过广播来更新,或者(EventBus,otto).

参考文献:

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1021/1813.html

代码下载地址:

https://github.com/jessandroid/lazyloadfragment

发布了38 篇原创文章 · 获赞 10 · 访问量 8万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章