com.zhangtielei.demos.badge_number.tabs.adapter.MainTabsPagerAdapter.java Source code

Java tutorial

Introduction

Here is the source code for com.zhangtielei.demos.badge_number.tabs.adapter.MainTabsPagerAdapter.java

Source

/*
 * Copyright (C) 2016 Tielei Zhang (zhangtielei.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.zhangtielei.demos.badge_number.tabs.adapter;

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.support.v4.view.ViewPager;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import com.zhangtielei.demos.badge_number.BuildConfig;
import com.zhangtielei.demos.badge_number.tabs.FirstFragment;
import com.zhangtielei.demos.badge_number.tabs.PlaceHolderFragment;
import com.zhangtielei.demos.badge_number.tabs.SecondFragment;
import com.zhangtielei.demos.badge_number.tabs.ThirdFragment;

/**
 * Created by charleszhang on 2/5/16.
 * ??pager adapter?Tab??????
 */
public class MainTabsPagerAdapter extends PagerAdapter {
    private static final String LOG_TAG = "MainTabsPagerAdapter";
    private static final boolean DEBUG = BuildConfig.DEBUG;

    public static final int FRAGMENT_COUNT = 3;//??
    public static final int FRAGMENT_INDEX_FIRST = 0;
    public static final int FRAGMENT_INDEX_SECOND = 1;
    public static final int FRAGMENT_INDEX_THIRD = 2;

    private final FragmentManager mFragmentManager;
    private final ViewPager viewPager;
    private FragmentTransaction mCurTransaction;
    private Fragment mCurrentPrimaryItem;

    private SparseArray<Fragment> fragmentMap;
    /**
     * ???
     */
    private boolean[] fragmentsAccess;

    public MainTabsPagerAdapter(FragmentManager fm, ViewPager viewPager) {
        mFragmentManager = fm;
        this.viewPager = viewPager;
        if (DEBUG) {
            Log.d(LOG_TAG, "FRAGMENT_COUNT " + FRAGMENT_COUNT);
        }
        fragmentMap = new SparseArray<Fragment>(FRAGMENT_COUNT);
        initFragmentAccess(FRAGMENT_COUNT);
    }

    private void initFragmentAccess(int count) {
        fragmentsAccess = new boolean[count];
        for (int i = 0; i < fragmentsAccess.length; i++) {
            fragmentsAccess[i] = false;
        }
    }

    private Fragment getItem(int position) {
        Fragment fragment = null;
        if (position == FRAGMENT_INDEX_FIRST) {
            fragment = new FirstFragment();
        } else if (position == FRAGMENT_INDEX_SECOND) {
            fragment = new SecondFragment();
        } else if (position == FRAGMENT_INDEX_THIRD) {
            fragment = new ThirdFragment();
        }
        return fragment;
    }

    private static String makeFragmentName(int index) {
        return "tabs:" + index;
    }

    @Override
    public int getCount() {
        return FRAGMENT_COUNT;
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    @Override
    public void startUpdate(ViewGroup container) {
        //nothing to do
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        String tag = makeFragmentName(position);
        Fragment fragment = mFragmentManager.findFragmentByTag(tag);

        if (fragment == null) {
            //fragment
            fragment = new PlaceHolderFragment();
            if (DEBUG) {
                Log.v(LOG_TAG, "Adding item #" + position + ": f=" + fragment);
            }
            if (mCurTransaction == null) {
                mCurTransaction = mFragmentManager.beginTransaction();
            }
            mCurTransaction.add(container.getId(), fragment, tag);
        } else {
            //?1??2view pageroffscreen limit???
            boolean ignore = false;
            if (fragmentsAccess[position]) {
                if (fragment instanceof PlaceHolderFragment) {
                    //??fragment
                    if (mCurTransaction == null) {
                        mCurTransaction = mFragmentManager.beginTransaction();
                    }
                    if (DEBUG) {
                        Log.v(LOG_TAG, "Remove #" + position + ": f=" + fragment);
                    }
                    mCurTransaction.remove(fragment);
                    fragment = getItem(position);
                    mCurTransaction.add(container.getId(), fragment, tag);
                    fragmentMap.put(position, fragment);
                    if (DEBUG) {
                        Log.v(LOG_TAG, "Re-Add #" + position + ": f=" + fragment);
                    }
                } else {
                    ignore = true;
                    fragmentMap.put(position, fragment);//?fragment?map??
                }
            } else {
                ignore = true;
            }

            if (ignore) {
                if (DEBUG) {
                    Log.v(LOG_TAG,
                            "Ignore instantiate item #" + position + ": f=" + fragment + ", f.X="
                                    + fragment.getView().getLeft() + ", container child count: "
                                    + container.getChildCount());
                }
                /**
                 * ??????viewX?????layout?
                 */
                viewPager.requestLayout();
            }
        }

        if (fragment != mCurrentPrimaryItem) {
            fragment.setMenuVisibility(false);
            fragment.setUserVisibleHint(false);
        }

        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        if (DEBUG) {
            Log.v(LOG_TAG, "Ignore destroy item #" + position + ": f=" + object);
        }
    }

    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        Fragment fragment = (Fragment) object;
        if (fragment != mCurrentPrimaryItem) {
            if (mCurrentPrimaryItem != null) {
                mCurrentPrimaryItem.setMenuVisibility(false);
                mCurrentPrimaryItem.setUserVisibleHint(false);
            }
            if (fragment != null) {
                fragment.setMenuVisibility(true);
                fragment.setUserVisibleHint(true);
            }
            if (!fragmentsAccess[position]) {
                if (DEBUG) {
                    Log.v(LOG_TAG, "Set Primary Item to " + position + " for the first time");
                }
                fragmentsAccess[position] = true;
                viewPager.post(new Runnable() {
                    @Override
                    public void run() {
                        notifyDataSetChanged();
                    }
                });
            }
            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;
    }

    /**
     * ?fragment?fragment
     *
     * @param fragmentIndex ?{@link #FRAGMENT_INDEX_FIRST},{@link #FRAGMENT_INDEX_SECOND}, {@link #FRAGMENT_INDEX_THIRD}
     * @return
     */
    public Fragment getFragment(int fragmentIndex) {
        return fragmentMap.get(fragmentIndex);
    }

}