com.hybris.mobile.app.commerce.fragment.CatalogMenuFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.hybris.mobile.app.commerce.fragment.CatalogMenuFragment.java

Source

/**
 * ****************************************************************************
 * [y] hybris Platform
 * <p/>
 * Copyright (c) 2000-2015 hybris AG
 * All rights reserved.
 * <p/>
 * This software is the confidential and proprietary information of hybris
 * ("Confidential Information"). You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the
 * license agreement you entered into with hybris.
 * ****************************************************************************
 */
package com.hybris.mobile.app.commerce.fragment;

import android.app.Activity;
import android.app.Fragment;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.ViewFlipper;

import com.hybris.mobile.app.commerce.CommerceApplication;
import com.hybris.mobile.app.commerce.R;
import com.hybris.mobile.app.commerce.adapter.CatalogAdapter;
import com.hybris.mobile.app.commerce.utils.UIUtils;
import com.hybris.mobile.lib.commerce.data.catalog.CategoryHierarchy;
import com.hybris.mobile.lib.commerce.data.error.ErrorList;
import com.hybris.mobile.lib.commerce.query.QueryCatalog;
import com.hybris.mobile.lib.commerce.response.ResponseReceiver;
import com.hybris.mobile.lib.http.listener.OnRequestListener;
import com.hybris.mobile.lib.http.response.Response;
import com.hybris.mobile.lib.http.utils.RequestUtils;

import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Fragment for the catalog menu
 */
public class CatalogMenuFragment extends Fragment implements ResponseReceiver<CategoryHierarchy> {
    private static final String TAG = CatalogMenuFragment.class.getCanonicalName();

    private String mCatalogRequestId = RequestUtils.generateUniqueRequestId();

    private static final String SAVED_INSTANCE_CATEGORY = "SAVED_INSTANCE_CATEGORY";
    private static final String SAVED_INSTANCE_OPEN_BY_DEFAULT = "SAVED_INSTANCE_OPEN_BY_DEFAULT";
    private OnCategorySelectedListener mActivity;
    private ViewFlipper mCatalogMenuViewFlipper;
    private DrawerLayout mCatalogMenuDrawerLayout;
    private boolean mOpenByDefault = true;
    private String mCurrentCategoryId;
    private CategoryHierarchy mDefaultCategory;

    /**
     * Interface for activity communication
     */
    public interface OnCategorySelectedListener {
        /**
         * Method for callback
         *
         * @param category
         */
        void onCategorySelected(CategoryHierarchy category);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // Make sure that the activity implements the callback interface
        try {
            mActivity = (OnCategorySelectedListener) activity;
        } catch (ClassCastException e) {
            Log.e(TAG, e.getLocalizedMessage());
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_catalog_menu, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        // Restore the current category
        if (savedInstanceState != null) {
            if (savedInstanceState.containsKey(SAVED_INSTANCE_CATEGORY)) {
                mCurrentCategoryId = savedInstanceState.getString(SAVED_INSTANCE_CATEGORY);
            }

            if (savedInstanceState.containsKey(SAVED_INSTANCE_OPEN_BY_DEFAULT)) {
                mOpenByDefault = savedInstanceState.getBoolean(SAVED_INSTANCE_OPEN_BY_DEFAULT);
            }
        }

        mCatalogMenuViewFlipper = (ViewFlipper) getActivity().findViewById(R.id.catalog_menu_fragment);

        // The catalog menu does not add any overlay on the screen
        mCatalogMenuDrawerLayout = ((DrawerLayout) getActivity().findViewById(R.id.catalog_menu_drawer));
        mCatalogMenuDrawerLayout.setScrimColor(Color.TRANSPARENT);

        // Call the API to get the catalog list
        QueryCatalog queryCatalog = new QueryCatalog();
        queryCatalog.setCatalogId(CommerceApplication.getContentServiceHelper().getConfiguration().getCatalogId());
        queryCatalog.setCatalogVersionId(
                CommerceApplication.getContentServiceHelper().getConfiguration().getCatalogVersionId());
        queryCatalog.setCatalogCategoryId(
                CommerceApplication.getContentServiceHelper().getConfiguration().getCatalogIdMainCategory());

        CommerceApplication.getContentServiceHelper().getCatalogCategory(this, mCatalogRequestId, queryCatalog,
                true, null, new OnRequestListener() {

                    @Override
                    public void beforeRequest() {
                        UIUtils.showLoadingActionBar(getActivity(), true);
                    }

                    @Override
                    public void afterRequestBeforeResponse() {

                    }

                    @Override
                    public void afterRequest(boolean isDataSynced) {
                        UIUtils.showLoadingActionBar(getActivity(), false);
                    }
                });

    }

    /**
     * On search request we trigger the select of the default category
     */
    public void onSearchRequest() {
        mActivity.onCategorySelected(mDefaultCategory);
    }

    @Override
    public void onResponse(Response<CategoryHierarchy> response) {
        mDefaultCategory = response.getData();

        if (mDefaultCategory != null) {
            // Update the catalog content with the main category
            mActivity.onCategorySelected(mDefaultCategory);

            // Setting the parent for each category of the catalog
            for (CategoryHierarchy category : mDefaultCategory.getSubcategories()) {
                category.setParent(mDefaultCategory);
            }

            // Init the list view with the catalog
            initListViewCatalog((ListView) getView().findViewById(R.id.catalog_menu_list_category),
                    mDefaultCategory.getSubcategories());

            // We come from a previous state
            if (StringUtils.isNotBlank(mCurrentCategoryId)) {

                // Finding the previous category in the list
                List<Integer> indexesCategories = new ArrayList<>();
                findCategory(mCurrentCategoryId, mDefaultCategory.getSubcategories(), indexesCategories);

                // Building the child views of each category
                List<CategoryHierarchy> nextSubCategories = mDefaultCategory.getSubcategories();
                for (Integer currentIndex : indexesCategories) {
                    final CategoryHierarchy currentCategory = nextSubCategories.get(currentIndex);
                    nextSubCategories = currentCategory.getSubcategories();

                    buildChildrenView(currentCategory, false, false);

                    mCatalogMenuViewFlipper.setInAnimation(null);
                    mCatalogMenuViewFlipper.setOutAnimation(null);
                    mCatalogMenuViewFlipper.setDisplayedChild(mCatalogMenuViewFlipper.getChildCount() - 1);
                }
            }

            // Open the catalog menu
            if (mOpenByDefault) {
                mCatalogMenuDrawerLayout.openDrawer(mCatalogMenuDrawerLayout.getChildAt(1));
            }
        }

    }

    @Override
    public void onError(Response<ErrorList> response) {
        UIUtils.showError(response, getActivity());
    }

    /**
     * Disable the open by default behavior
     */
    public void disableDefaultOpening() {
        mOpenByDefault = false;
    }

    /**
     * Init the catalog list view with a list of categories
     *
     * @param listView
     * @param categories
     */
    private void initListViewCatalog(ListView listView, List<CategoryHierarchy> categories) {
        if (categories != null) {
            // On click listener for the different categories
            listView.setOnItemClickListener(new CategoryClickListener(categories));

            // Updating the list view
            listView.setAdapter(new CatalogAdapter(getActivity(), categories));
        }
    }

    /**
     * Listener to switch from one category to her subcategories
     */
    private class CategoryClickListener implements OnItemClickListener {

        private List<CategoryHierarchy> categories;

        public CategoryClickListener(List<CategoryHierarchy> catalogs) {
            this.categories = catalogs;
        }

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            final CategoryHierarchy currentCategory = categories.get(position);
            mCurrentCategoryId = currentCategory.getId();

            // We handle_anchor the case of subcategories switching
            if (currentCategory.getSubcategories() != null && !currentCategory.getSubcategories().isEmpty()) {
                buildChildrenView(currentCategory, false, true);
            } else {
                // Close the catalog menu
                mCatalogMenuDrawerLayout.closeDrawer(mCatalogMenuDrawerLayout.getChildAt(1));

                // Updating the content view
                updateContentView(currentCategory, true);
            }

        }

    }

    /**
     * Add a child view to the view flipper
     *
     * @param parent
     * @param showCatalogMenuLogo
     */
    private void buildChildrenView(final CategoryHierarchy parent, boolean showCatalogMenuLogo, boolean showNext) {
        // Layout for the view
        final View view = getActivity().getLayoutInflater().inflate(R.layout.include_catalog_menu_categories,
                mCatalogMenuViewFlipper, false);

        TextView textViewTopCategoryName = (TextView) view.findViewById(R.id.catalog_menu_top_category_name);
        RelativeLayout relativeLayoutTopCategory = (RelativeLayout) view
                .findViewById(R.id.catalog_menu_top_category);
        ListView listViewCategories = (ListView) view.findViewById(R.id.catalog_menu_list_category);

        // We set to visible the top category name
        relativeLayoutTopCategory.setVisibility(View.VISIBLE);

        // Setting the top category name
        textViewTopCategoryName.setText(parent.getName());
        textViewTopCategoryName.setVisibility(View.VISIBLE);
        textViewTopCategoryName.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (parent.getParent() != null) {
                    mCurrentCategoryId = parent.getParent().getId();
                } else {
                    mCurrentCategoryId = null;
                }

                // On click of the top category, we go back to the top view
                mCatalogMenuViewFlipper.setInAnimation(getActivity(), R.anim.translate_left_to_origin);
                mCatalogMenuViewFlipper.setOutAnimation(getActivity(), R.anim.translate_origin_to_right);
                mCatalogMenuViewFlipper.showPrevious();

                // And we remove the view we just came by
                mCatalogMenuViewFlipper.removeViewAt(mCatalogMenuViewFlipper.getChildCount() - 1);

                // We display the catalog logo if we are on the top view
                if (mCatalogMenuViewFlipper.getChildCount() == 1) {
                    showCatalogMenuLogo(view, true);
                }

                // Updating the content view
                updateContentView(parent.getParent(), false);

            }
        });

        // Setting the list for the sub categories
        initListViewCatalog(listViewCategories, parent.getSubcategories());

        // Show the subcategories
        mCatalogMenuViewFlipper.addView(view);

        if (showNext) {
            mCatalogMenuViewFlipper.setInAnimation(getActivity(), R.anim.translate_right_to_origin);
            mCatalogMenuViewFlipper.setOutAnimation(getActivity(), R.anim.translate_origin_to_left);
            mCatalogMenuViewFlipper.showNext();

            // Updating the content view once the ViewFlipper has finished his animation
            updateContentView(parent, false);
        }

        // Hidding the catalog logo on subcategories
        showCatalogMenuLogo(view, showCatalogMenuLogo);

    }

    /**
     * Show/Hide the catalog logo
     *
     * @param view
     * @param show
     */
    private void showCatalogMenuLogo(View view, boolean show) {
        view.findViewById(R.id.catalog_menu_logo).setVisibility(show ? View.VISIBLE : View.GONE);
    }

    /**
     * This method update the content view once the viewflipper (for subcategories) or the drawer (for a leaf) has
     * finished his animation (prevent the lag if the results arrive from persistence during the animation)
     *
     * @param category
     * @param isLeaf
     */
    private void updateContentView(final CategoryHierarchy category, boolean isLeaf) {
        // For a leaf we update the content view after once the drawer is closed
        if (isLeaf)

        {
            mCatalogMenuDrawerLayout.setDrawerListener(new DrawerListener() {

                @Override
                public void onDrawerStateChanged(int arg0) {
                }

                @Override
                public void onDrawerSlide(View arg0, float arg1) {
                }

                @Override
                public void onDrawerOpened(View arg0) {
                }

                @Override
                public void onDrawerClosed(View arg0) {
                    // Updating the content view
                    mActivity.onCategorySelected(category);

                    // We remove the listener
                    mCatalogMenuDrawerLayout.setDrawerListener(null);
                }
            });
        }
        // For subcategories we wait for the end of the ViewFlipper animation
        else {
            if (mCatalogMenuViewFlipper.getInAnimation() != null) {
                mCatalogMenuViewFlipper.getInAnimation().setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationEnd(Animation animation) {
                        // We update the content
                        mActivity.onCategorySelected(category);
                    }

                    @Override
                    public void onAnimationStart(Animation animation) {
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {
                    }
                });
            } else {
                // We update the content
                mActivity.onCategorySelected(category);
            }

        }

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        outState.putString(SAVED_INSTANCE_CATEGORY, mCurrentCategoryId);
        mOpenByDefault = mCatalogMenuDrawerLayout.isDrawerOpen(mCatalogMenuDrawerLayout.getChildAt(1));
        outState.putBoolean(SAVED_INSTANCE_OPEN_BY_DEFAULT, mOpenByDefault);
        super.onSaveInstanceState(outState);
    }

    /**
     * Find a category in the list and save in a tab the path to get there (int positions)
     *
     * @param categoryIdToFind
     * @param categories
     * @param indexesCategories
     * @return
     */
    public CategoryHierarchy findCategory(String categoryIdToFind, List<CategoryHierarchy> categories,
            List<Integer> indexesCategories) {

        CategoryHierarchy category = null;
        boolean categoryFound = false;

        if (categories != null && !categories.isEmpty()) {
            Iterator<CategoryHierarchy> iterator = categories.iterator();
            int i = 0;

            // We continue until we find the category
            while (!categoryFound && iterator.hasNext()) {
                indexesCategories.add(i);
                CategoryHierarchy currentCategory = iterator.next();

                // Category found
                if (currentCategory.getId().equals(categoryIdToFind)) {
                    categoryFound = true;
                    category = currentCategory;
                }
                // We go through the sub-categories
                else if (currentCategory.getSubcategories() != null) {
                    category = findCategory(categoryIdToFind, currentCategory.getSubcategories(),
                            indexesCategories);

                    if (category != null) {
                        return category;
                    }
                    // Category not found, we remove the index from the path
                    else {
                        indexesCategories.remove(indexesCategories.size() - 1);
                    }

                }
                // Else we remove the index from the path
                else {
                    indexesCategories.remove(indexesCategories.size() - 1);
                }

                i++;

            }

        }

        return category;

    }

    @Override
    public void onStop() {
        super.onStop();
        CommerceApplication.getContentServiceHelper().cancel(mCatalogRequestId);
    }

}