viewpager+fragment+tablayout适配器和fragment的一些应用

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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值