com.inovex.zabbixmobile.adapters.BaseServicePagerAdapter.java Source code

Java tutorial

Introduction

Here is the source code for com.inovex.zabbixmobile.adapters.BaseServicePagerAdapter.java

Source

/*
This file is part of ZAX.
    
   ZAX is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
    
   ZAX is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
    
   You should have received a copy of the GNU General Public License
   along with ZAX.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.inovex.zabbixmobile.adapters;

import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import java.util.Collection;
import java.util.TreeSet;

/**
 * Base class for a pager adapter maintained by a service. The base
 * functionality is similar to {@link FragmentPagerAdapter}.
 *
 * @param <T>
 *            class of the items in this adapter's data set
 */
public abstract class BaseServicePagerAdapter<T> extends PagerAdapter {

    protected TreeSet<T> mObjects;
    private static final String TAG = BaseServicePagerAdapter.class.getSimpleName();
    private static final boolean DEBUG = true;
    protected int mCurrentPosition;
    protected FragmentManager mFragmentManager;
    protected FragmentTransaction mCurTransaction = null;
    private Fragment mCurrentPrimaryItem = null;
    private boolean mRefresh;

    public BaseServicePagerAdapter() {
        mObjects = new TreeSet<T>();
    }

    public void setFragmentManager(FragmentManager fm) {
        this.mFragmentManager = fm;
    }

    @Override
    public void startUpdate(ViewGroup container) {
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        if (mFragmentManager == null)
            return null;
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }

        final Long itemId = getItemId(position);
        if (itemId == null)
            return null;

        // Do we already have this fragment?
        String name = makeFragmentName(container.getId(), itemId);
        Fragment fragment = mFragmentManager.findFragmentByTag(name);
        if (fragment != null && !mRefresh) {
            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) {
            fragment.setMenuVisibility(false);
            fragment.setUserVisibleHint(false);
        }

        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        // if the fragment was detached, the fragment manager should be null
        if (mFragmentManager == null)
            return;
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        mCurTransaction.detach((Fragment) 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);
            }
            mCurrentPrimaryItem = fragment;
        }
    }

    @Override
    public void finishUpdate(ViewGroup container) {
        if (mFragmentManager == null)
            return;
        if (mCurTransaction != null) {
            try {
                mCurTransaction.commitAllowingStateLoss();
                mCurTransaction = null;
                // Commenting out the following two lines fixes a
                // "Recursive entry to executePendingTransactions" exception
                // I don't know why and hope this doesn't break anything
                //            if (mFragmentManager != null)
                //               mFragmentManager.executePendingTransactions();
            } catch (IllegalStateException e) {
                // this exception is thrown if the activity has been destroyed
                // which unfortunately happens from time to time
                e.printStackTrace();
                mCurTransaction = null;
            }
        }
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        if (object == null || view == null)
            return false;
        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 abstract Long getItemId(int position);

    protected static String makeFragmentName(int viewId, long id) {
        return "android:switcher:" + viewId + ":" + id;
    }

    /**
     * Creates a page (fragment) for a certain position.
     *
     * @param position
     *            the position within the adapter
     * @return the created fragment
     */
    protected abstract Fragment getItem(int position);

    @Override
    public int getCount() {
        return mObjects.size();
    }

    /**
     * Wrapper for {@link TreeSet#addAll(Collection)}.
     *
     * @param objects
     */
    public void addAll(Collection<? extends T> objects) {
        this.mObjects.addAll(objects);
    }

    /**
     * Returns an item from the underlying data set.
     *
     * @param position
     *            position of the item
     * @return
     */
    @SuppressWarnings("unchecked")
    public T getObject(int position) {
        if (position >= mObjects.size())
            return null;
        return (T) mObjects.toArray()[position];
    }

    /**
     * Returns the current item.
     *
     * @return
     */
    @SuppressWarnings("unchecked")
    public T getCurrentObject() {
        if (mObjects.size() <= mCurrentPosition) {
            if (mObjects.size() > 0)
                return (T) mObjects.toArray()[0];
            return null;
        }
        return (T) mObjects.toArray()[mCurrentPosition];
    }

    /**
     * Wrapper for {@link TreeSet#clear()}.
     */
    public void clear() {
        mObjects.clear();
        mRefresh = true;
    }

    public int getCurrentPosition() {
        return mCurrentPosition;
    }

    public void setCurrentPosition(int position) {
        this.mCurrentPosition = position;
    }

}