com.lkunic.lib.activityaddonlib.twopane.fragments.showcase.ItemShowcaseFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.lkunic.lib.activityaddonlib.twopane.fragments.showcase.ItemShowcaseFragment.java

Source

/**********************************************************************
 * Copyright (c) 2015 Luka Kunic, "ItemShowcaseFragment.java"
 * 
 * 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.
 *
 * Author: lkunic
 * Last modified: 08/02/2015
 **********************************************************************/
package com.lkunic.lib.activityaddonlib.twopane.fragments.showcase;

import java.util.List;

import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;

import com.lkunic.lib.activityaddonlib.R;
import com.lkunic.lib.activityaddonlib.twopane.fragments.ItemDetailFragment;
import com.lkunic.lib.activityaddonlib.views.ShowcaseButton;

/**
 * This fragment contains a header image with a title overlay and a tab-like interface for displaying
 * additional information about the item.
 */
public abstract class ItemShowcaseFragment extends ItemDetailFragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_item_showcase, container, false);

        setupContent(view);

        return view;
    }

    /**************************************************************************************************/
    /**** Private support methods ****/
    /**************************************************************************************************/

    /**
     * Sets up the fragment and it's views.
     * @param view The layout view.
     */
    @Override
    protected void setupContent(View view) {
        // Make sure item data is available before setting up content.
        getItemData();

        // Populate the view holder if needed
        if (viewHolder == null) {
            viewHolder = new ViewHolder();

            viewHolder.showcaseItemImage = (ImageView) view.findViewById(R.id.showcase_image);
            viewHolder.showcaseItemTitle = (TextView) view.findViewById(R.id.showcase_title);
            viewHolder.viewPager = (ViewPager) view.findViewById(R.id.pager);
            viewHolder.pagerButtonBar = (LinearLayout) view.findViewById(R.id.pager_button_bar);
        }

        // Set the item image
        viewHolder.showcaseItemImage.setImageBitmap(getShowcaseImage());

        // Set the item title
        viewHolder.showcaseItemTitle.setText(getShowcaseItemTitle());

        // Set up the view pager
        ItemShowcaseInfoFragment[] infoFragments = getInfoFragments();
        if (viewHolder.viewPager.getAdapter() == null) {
            // The ViewPager doesn't have an adapter yet, create it and populate with info fragments
            viewHolder.viewPager.setAdapter(new ShowcasePagerAdapter(getChildFragmentManager(), infoFragments));
            viewHolder.viewPager.setOnPageChangeListener(showcasePageChangeListener);
        } else {
            // The ViewPager already has an adapter, populate it with new info fragments
            ShowcasePagerAdapter adapter = (ShowcasePagerAdapter) viewHolder.viewPager.getAdapter();
            adapter.setPagerItems(infoFragments);
            adapter.notifyDataSetChanged();
        }

        // Build the button bar for controlling the view pager
        ShowcaseButton showcaseButton;
        LinearLayout showcaseButtonContainer;
        LayoutParams showcaseButtonParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,
                1);

        // Remove all buttons that could have been populated by previous item
        viewHolder.pagerButtonBar.removeAllViews();

        for (int i = 0, n = infoFragments.length; i < n; i++) {
            // Create a new showcase button and populate it with data from corresponding fragment
            showcaseButton = new ShowcaseButton(getActivity(), infoFragments[i].getQuantity(),
                    infoFragments[i].getQuantityName());

            // Setup the showcase view so that it can be used as a tab button
            showcaseButtonContainer = (LinearLayout) showcaseButton.findViewById(R.id.container);
            showcaseButtonContainer.setTag(i);
            showcaseButtonContainer.setOnClickListener(showcaseButtonClickListener);
            showcaseButtonContainer.setBackgroundResource(i % 2 == 0 ? R.drawable.showcase_button_background_light
                    : R.drawable.showcase_button_background_dark);

            // Add the button to the button bar
            showcaseButton.setLayoutParams(showcaseButtonParams);
            viewHolder.pagerButtonBar.addView(showcaseButton);
        }

        viewHolder.viewPager.setCurrentItem(0, true);
        selectPageButton(0);
    }

    /**
     * Selects the current page of the view pager.
     * 
     * @param pageNumber
     * Index of the page to select.
     */
    private void selectPageButton(int pageNumber) {
        for (int i = 0, n = viewHolder.pagerButtonBar.getChildCount(); i < n; i++) {
            if (i == pageNumber) {
                viewHolder.pagerButtonBar.getChildAt(i).setSelected(true);
            } else {
                viewHolder.pagerButtonBar.getChildAt(i).setSelected(false);
            }
        }
    }

    /**************************************************************************************************/
    /**** Listeners ****/
    /**************************************************************************************************/

    /**
     * Listens for clicks of the pager buttons.
     */
    private OnClickListener showcaseButtonClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            viewHolder.viewPager.setCurrentItem((int) v.getTag(), true);
        }
    };

    /**
     * Listens for page changes in the view pager.
     */
    private OnPageChangeListener showcasePageChangeListener = new OnPageChangeListener() {

        @Override
        public void onPageSelected(int position) {
            selectPageButton(position);
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageScrollStateChanged(int state) {
        }
    };

    /**************************************************************************************************/
    /**** Abstract methods ****/
    /**************************************************************************************************/

    /**
     * Provides a list of fragments to be displayed in the view pager.
     */
    protected abstract ItemShowcaseInfoFragment[] getInfoFragments();

    /**
     * Provides the bitmap image to be displayed for the selected item.
     */
    protected abstract Bitmap getShowcaseImage();

    /**
     * Provides the title for the selected item.
     */
    protected abstract String getShowcaseItemTitle();

    /**************************************************************************************************/
    /**** View holder ****/
    /**************************************************************************************************/

    private static class ViewHolder {
        public ImageView showcaseItemImage;
        public TextView showcaseItemTitle;
        public ViewPager viewPager;
        public LinearLayout pagerButtonBar;
    }

    private ViewHolder viewHolder;

    /**************************************************************************************************/
    /**** ShowcasePagerAdapter ****/
    /**************************************************************************************************/

    private static class ShowcasePagerAdapter extends FragmentPagerAdapter {
        private FragmentManager mFragmentManager;
        private ItemShowcaseInfoFragment[] mFragments;

        public ShowcasePagerAdapter(FragmentManager fm, ItemShowcaseInfoFragment[] fragments) {
            super(fm);

            mFragmentManager = fm;
            setPagerItems(fragments);
        }

        public void setPagerItems(ItemShowcaseInfoFragment[] fragments) {
            List<Fragment> activeFragments = mFragmentManager.getFragments();

            // The fragment manager stores fragment instances, which means it doesn't update the data in the fragment
            // If there are any active ShowcaseInfoFragments, iterate through them and remove them
            if (activeFragments != null && activeFragments.size() != 0) {
                for (Fragment activeFragment : activeFragments) {
                    if (activeFragment instanceof ItemShowcaseInfoFragment) {
                        mFragmentManager.beginTransaction().remove(activeFragment).commit();
                    }
                }
            }

            mFragments = fragments;
        }

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

        @Override
        public Fragment getItem(int position) {
            return mFragments[position];
        }

        @Override
        public int getCount() {
            return mFragments.length;
        }
    }
}