1.viewpager+fragment往往系统都会自带预加载
下面给出取消预加载,实现懒加载的方法。
创建BaseFragment,实现fragment复用功能
public abstract class BaseFragment extends Fragment{
protected View mRootView;
public Context mContext;
protected boolean isVisible;
private boolean isPrepared;
private boolean isFirst = true;
public BaseFragment2() {
// Required empty public constructor
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
// Log.d("TAG", "fragment->setUserVisibleHint");
if (getUserVisibleHint()) {
isVisible = true;
lazyLoad();
} else {
isVisible = false;
onInvisible();
}
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getActivity();
setHasOptionsMenu(true);
// Log.d("TAG", "fragment->onCreate");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mRootView == null) {
mRootView = initView();
}
// Log.d("TAG", "fragment->onCreateView");
return mRootView;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Log.d("TAG", "fragment->onActivityCreated");
isPrepared = true;
lazyLoad();
}
protected void lazyLoad() {
if (!isPrepared || !isVisible || !isFirst) {
return;
}
Log.d("TAG", getClass().getName() + "->initData()");
initData();
isFirst = false;
}
//do something
protected void onInvisible() {
}
public abstract View initView();
public abstract void initData();
}
fragment直接继承就可以实现懒加载。可直接使用,fragment实现initView和initData方法,分别加载布局文件,和网络请求。可以实现懒加载、第一次加载请求网络数据,切换界面加载缓存。
2.viewpager+fragment实现添加或删除fragment动态刷新数据的viewpager适配器,直接调用 mAdapter.notifyDataSetChanged();不会刷新适配器,要修改viewpager适配器内容来实现刷新。
在你需要刷新的地方调用notifyDataSetChanged();刷新
//viewpager适配器
private class CommonPagerAdapter extends NameVisibleFragmentPagerAdapter {
private ArrayList<Fragment> fragmentList;
public CommonPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragmentList) {
super(fm);
this.fragmentList = fragmentList;
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList != null ? fragmentList.size():0;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == ((Fragment)object).getView();
}
@Override
public CharSequence getPageTitle(int position) {
return userChannelList.get(position).getName();
}
}
NameVisibleFragmentPagerAdapter 自定义适配器布局
package com.sanbanhui.helper.adapter;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
/*
* Copy from android.support.v4.app.FragmentPagerAdapter.
* the fragment names(the tag in fragment manager) in this adapter is visible
* by calling the public method getFragmentName(position).
*/
public abstract class NameVisibleFragmentPagerAdapter extends PagerAdapter {
private static final String TAG = "FragmentPagerAdapter";
private static final boolean DEBUG = false;
private final FragmentManager mFragmentManager;
private FragmentTransaction mCurTransaction = null;
private Fragment mCurrentPrimaryItem = null;
private SparseArray<String> nameSet = new SparseArray<String>();
public NameVisibleFragmentPagerAdapter(FragmentManager fm) {
mFragmentManager = fm;
}
/**
* Return the Fragment associated with a specified position.
*/
public abstract Fragment getItem(int position);
@Override
public void startUpdate(ViewGroup container) {
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
final long itemId = getItemId(position);
// Do we already have this fragment?
String name = makeFragmentName(container.getId(), itemId);
if (TextUtils.isEmpty(nameSet.get(position))) {
nameSet.put(position, name);
}
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
mCurTransaction.attach(fragment);
} else {
fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
mCurTransaction.add(container.getId(), fragment,
makeFragmentName(container.getId(), itemId));
}
if (fragment != mCurrentPrimaryItem) {
if (null != mCurrentPrimaryItem) {
mCurrentPrimaryItem.setUserVisibleHint(false);
mCurrentPrimaryItem.setMenuVisibility(false);
}
}
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
+ " v=" + ((Fragment)object).getView());
mCurTransaction.detach((Fragment)object);
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment)object;
if (fragment != mCurrentPrimaryItem) {
if (null != mCurrentPrimaryItem) {
mCurrentPrimaryItem.setUserVisibleHint(false);
mCurrentPrimaryItem.setMenuVisibility(false);
}
if (fragment != null) {
fragment.setUserVisibleHint(true);
fragment.setMenuVisibility(true);
}
}
mCurrentPrimaryItem = fragment;
}
@Override
public void finishUpdate(ViewGroup container) {
if (mCurTransaction != null) {
mCurTransaction.commitAllowingStateLoss();
mCurTransaction = null;
mFragmentManager.executePendingTransactions();
}
}
@Override
public boolean isViewFromObject(View view, Object object) {
return ((Fragment)object).getView() == view;
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
}
/**
* Return a unique identifier for the item at the given position.
*
* <p>The default implementation returns the given position.
* Subclasses should override this method if the positions of items can change.</p>
*
* @param position Position within this adapter
* @return Unique identifier for the item at position
*/
public long getItemId(int position) {
return position;
}
public Fragment getFragmentAtPosition(int position) {
if (!TextUtils.isEmpty(nameSet.get(position))) {
return mFragmentManager.findFragmentByTag(nameSet.get(position));
}
return null;
}
public String getFragmentName(int position) {
return nameSet.get(position);
}
private static String makeFragmentName(int viewId, long id) {
return "android:switcher:" + viewId + ":" + id;
}
}
3.实现新闻APP类似频道管理,添加、删除、排序、制定的viewpager适配器
//viewpager适配器
private class CommonPagerAdapter extends NameVisibleFragmentPagerAdapter {
private ArrayList<Fragment> fragmentList;
int id = 1;
Map<String,Integer> IdsMap = new HashMap<>();
List<String> preIds = new ArrayList<>();
public CommonPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragmentList) {
super(fm);
this.fragmentList = fragmentList;
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
return super.instantiateItem(container, position);
}
@Override
public long getItemId(int position) {
return IdsMap.get(getPageTitle(position));
}
@Override
public int getItemPosition(Object object) {
int newId=-1;
int i=0;
int size=getCount();
int preId = 0;
if(object instanceof YaowenFragment)
{
String title = "要闻";
preId = preIds.indexOf(title);
for(;i<size;i++){
if(getPageTitle(i).equals(title)){
newId=i;
break;
}
}
}else if(object instanceof KuaixunFragment)
{
String title = "快讯";
preId = preIds.indexOf(title);
for(;i<size;i++){
if(getPageTitle(i).equals(title)){
newId = i;
break;
}
}
}else
{
ZixunContentFragment fragment= (ZixunContentFragment) object;
String title = fragment.getTitle();
preId = preIds.indexOf(fragment.getTitle());
for(;i<size;i++){
if(getPageTitle(i).equals(fragment.getTitle())){
newId = i;
break;
}
}
}
if(newId!=-1&&newId==preId){
return POSITION_UNCHANGED;
}
if(newId!=-1){
return newId;
}
return POSITION_NONE;
}
@Override
public void notifyDataSetChanged()
{
userChannelList = ((ArrayList<ChannelItem>) ChannelManage.getManage(AndroidApplication.getInstance().getSQLHelper()).getUserChannel());
mFragments.clear();
if (userChannelList != null && userChannelList.size() > 0)
{
if(!IdsMap.containsKey("要闻")){
IdsMap.put("要闻" , id++);
}
mFragments.add(new YaowenFragment());
if (userChannelList.size() > 1) {
for (int i = 1; i < userChannelList.size(); i++) {
LogUtils.showLog("callback" , userChannelList.get(i).getName());
if (userChannelList.get(i).getName().equals("快讯")) {
mFragments.add(new KuaixunFragment());
if(!IdsMap.containsKey("快讯")){
IdsMap.put("快讯" , id++);
}
} else
{
zxFragment = new ZixunContentFragment().newInstance(i, userChannelList.get(i).getName());
mFragments.add(zxFragment);
if(!IdsMap.containsKey(userChannelList.get(i).getName())){
IdsMap.put(userChannelList.get(i).getName() , id++);
}
}
}
}
}
this.fragmentList = mFragments;
super.notifyDataSetChanged();
preIds.clear();
int size = getCount();
for(int i = 0 ; i < size ; i++)
{
preIds.add((String) getPageTitle(i));
}
}
@Override
public int getCount() {
return fragmentList != null ? fragmentList.size():0;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == ((Fragment)object).getView();
}
@Override
public CharSequence getPageTitle(int position) {
return userChannelList.get(position).getName();
}
}
在使用viewpager+fragment遇到的坑:在有大量fragment的时候,切换界面的时候特别卡,原因是在布局中使用自定义lsitview。会导致切换卡顿,在fragment+viewpager中最好别用设置高度的listview。