Android Open Source - android_app Undo Bar Controller






From Project

Back to project page android_app.

License

The source code is released under:

Apache License

If you think the Android project android_app listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * ******************************************************************************
 *   Copyright (c) 2013 Roman Nurik, 2013-2014 Gabriele Mariotti.
 */*  w w  w  .j a  v  a2 s  .  c o m*/
 *   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 it.gmariotti.cardslib.library.view.listener;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.widget.TextView;

import it.gmariotti.cardslib.library.R;
import it.gmariotti.cardslib.library.internal.CardArrayAdapter;

/**
 * It is based on Roman Nurik code.
 * See this link for original code:
 * https://code.google.com/p/romannurik-code/source/browse/#git%2Fmisc%2Fundobar
 *
 *
 */
public class UndoBarController {

    private View mBarView;
    private TextView mMessageView;
    private ViewPropertyAnimator mBarAnimator;
    private Handler mHideHandler = new Handler();

    private UndoListener mUndoListener;
    private UndoBarHideListener mUndoBarHideListener;

    // State objects
    private Parcelable mUndoToken;
    private CharSequence mUndoMessage;

    private UndoBarUIElements mUndoBarUIElements;

    /**
     * Interface to listen the undo controller actions
     */
    public interface UndoListener {
        /*
         *  Called when you undo the action
         */
        void onUndo(Parcelable undoToken);
    }

    /**
     * Interface to listen for when the Undo controller hides the Undo Bar,
     * after it times out from being shown for the currently dismissed mUndoToken.
     */
    public interface UndoBarHideListener {
        /**
         * Called when the UndoBar is hidden after being shown.
         * @param undoOccurred true if the user pressed the undo button
         *                     for the current mUndoToken.
         */
        void onUndoBarHide(boolean undoOccurred);
    }

    public UndoBarController(View undoBarView, UndoListener undoListener) {
        this (undoBarView,undoListener,null);
    }

    public UndoBarController(View undoBarView, UndoListener undoListener,UndoBarUIElements undoBarUIElements) {
        mBarView = undoBarView;
        mBarAnimator = mBarView.animate();
        mUndoListener = undoListener;

        if (undoBarUIElements==null)
            undoBarUIElements = new DefaultUndoBarUIElements();
        mUndoBarUIElements = undoBarUIElements;

        mMessageView = (TextView) mBarView.findViewById(mUndoBarUIElements.getUndoBarMessageId());
        mBarView.findViewById(mUndoBarUIElements.getUndoBarButtonId())
                .setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        hideUndoBar(false);
                        mUndoListener.onUndo(mUndoToken);
                        // Remove the reference to the undo token, since the undo has occurred.
                        mUndoToken = null;
                    }
                });

        setupAnimation();

        if (mUndoBarUIElements.isEnabledUndoBarSwipeAction() != UndoBarUIElements.SwipeDirectionEnabled.NONE){
            setupSwipeActionOnUndoBar();
        }

        hideUndoBar(true);
    }



    public void showUndoBar(boolean immediate, CharSequence message,
                            Parcelable undoToken, UndoBarHideListener undoBarHideListener) {

        // We're replacing the existing UndoBarHideListener, meaning that
        // the original object removal was not undone. So, execute
        // onUndoBarHide for the previous listener.
        if (mUndoBarHideListener != null) {
            mUndoBarHideListener.onUndoBarHide(mUndoToken == null);
        }


        mUndoToken = undoToken;
        mUndoMessage = message;
        mUndoBarHideListener = undoBarHideListener;
        mMessageView.setText(mUndoMessage);

        mHideHandler.removeCallbacks(mHideRunnable);
        mHideHandler.postDelayed(mHideRunnable,
                mBarView.getResources().getInteger(R.integer.list_card_undobar_hide_delay));

        mBarView.setVisibility(View.VISIBLE);
        if (immediate) {
            mBarView.setAlpha(1);
        } else {

            if (mUndoBarUIElements.getAnimationType() == UndoBarUIElements.AnimationType.ALPHA) {

                mBarAnimator.cancel();
                mBarAnimator
                        .alpha(1)
                        .setDuration(
                                mBarView.getResources()
                                        .getInteger(android.R.integer.config_shortAnimTime))
                        .setListener(null);
            } else if (mUndoBarUIElements.getAnimationType() == UndoBarUIElements.AnimationType.TOPBOTTOM){

                mBarAnimator.cancel();
                mBarAnimator
                        .alpha(1)
                        .translationY(0)
                        .setDuration(
                                mBarView.getResources()
                                        .getInteger(android.R.integer.config_mediumAnimTime))
                        .setListener(null);

            }
        }
    }

    public void hideUndoBar(boolean immediate) {
        mHideHandler.removeCallbacks(mHideRunnable);
        if (immediate) {
            mBarView.setVisibility(View.GONE);
            mBarView.setAlpha(0);
            mUndoMessage = null;
            if (mUndoBarHideListener != null) {
                // The undo has occurred only if mUndoToken was set to null.
                mUndoBarHideListener.onUndoBarHide(mUndoToken == null);
            }
            mUndoBarHideListener = null;
            mUndoToken = null;
        } else {
            mBarAnimator.cancel();

            if (mUndoBarUIElements.getAnimationType() == UndoBarUIElements.AnimationType.ALPHA) {
                mBarAnimator
                        .alpha(0)
                        .setDuration(mBarView.getResources()
                                .getInteger(android.R.integer.config_shortAnimTime))
                        .setListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationEnd(Animator animation) {
                                mBarView.setVisibility(View.GONE);
                                mUndoMessage = null;
                                if (mUndoBarHideListener != null) {
                                    // The undo has occurred only if mUndoToken was set to null.
                                    mUndoBarHideListener.onUndoBarHide(mUndoToken == null);
                                }
                                mUndoBarHideListener = null;
                                mUndoToken = null;
                            }
                        });
            } else if (mUndoBarUIElements.getAnimationType() == UndoBarUIElements.AnimationType.TOPBOTTOM){
                mBarAnimator
                        .alpha(0)
                        .translationY(+mBarView.getHeight())
                        .setDuration(mBarView.getResources()
                                .getInteger(android.R.integer.config_shortAnimTime))
                        .setListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationEnd(Animator animation) {
                                mBarView.setVisibility(View.GONE);
                                mUndoMessage = null;
                                if (mUndoBarHideListener != null) {
                                    // The undo has occurred only if mUndoToken was set to null.
                                    mUndoBarHideListener.onUndoBarHide(mUndoToken == null);
                                }
                                mUndoBarHideListener = null;
                                mUndoToken = null;
                            }
                        });
            }
        }
    }

    public void onSaveInstanceState(Bundle outState) {
        outState.putCharSequence("undo_message", mUndoMessage);
        outState.putParcelable("undo_token", mUndoToken);
    }

    public void onRestoreInstanceState(Bundle savedInstanceState) {
        if (savedInstanceState != null) {
            mUndoMessage = savedInstanceState.getCharSequence("undo_message");
            mUndoToken = savedInstanceState.getParcelable("undo_token");

            if (mUndoToken != null || !TextUtils.isEmpty(mUndoMessage)) {
                showUndoBar(true, mUndoMessage, mUndoToken, mUndoBarHideListener);
            }
        }
    }

    private Runnable mHideRunnable = new Runnable() {
        @Override
        public void run() {
            hideUndoBar(false);
        }
    };

    public Parcelable getUndoToken(){
        return mUndoToken;
    }

    private void setupAnimation(){
        if (mUndoBarUIElements.getAnimationType() == UndoBarUIElements.AnimationType.TOPBOTTOM) {
            mBarView.setTranslationY(mBarView.getHeight());
        }
    }

    private void setupSwipeActionOnUndoBar() {
        if (mBarView != null) {

            if (mUndoBarUIElements.isEnabledUndoBarSwipeAction() == UndoBarUIElements.SwipeDirectionEnabled.LEFTRIGHT) {

                mBarView.setOnTouchListener(new SwipeDismissTouchListener(mBarView, null,
                        new SwipeDismissTouchListener.DismissCallbacks() {
                            @Override
                            public boolean canDismiss(Object token) {
                                return mUndoBarUIElements.isEnabledUndoBarSwipeAction() != UndoBarUIElements.SwipeDirectionEnabled.NONE;
                            }

                            @Override
                            public void onDismiss(View view, Object token) {
                                hideUndoBar(true);
                                mUndoListener.onUndo(mUndoToken);
                                // Remove the reference to the undo token, since the undo has occurred.
                                mUndoToken = null;
                            }
                        }));
            } else if (mUndoBarUIElements.isEnabledUndoBarSwipeAction() == UndoBarUIElements.SwipeDirectionEnabled.TOPBOTTOM) {

                mBarView.setOnTouchListener(new SwipeDismissTopBottomTouchListener(mBarView, null,
                        new SwipeDismissTopBottomTouchListener.DismissCallbacks() {
                            @Override
                            public boolean canDismiss(Object token) {
                                return mUndoBarUIElements.isEnabledUndoBarSwipeAction() != UndoBarUIElements.SwipeDirectionEnabled.NONE;
                            }

                            @Override
                            public void onDismiss(View view, Object token) {
                                hideUndoBar(true);
                                mUndoListener.onUndo(mUndoToken);
                                // Remove the reference to the undo token, since the undo has occurred.
                                mUndoToken = null;
                            }
                        }));
            }
        }

    }

    // -------------------------------------------------------------
    //  Undo Custom Bar
    // -------------------------------------------------------------

    /**
     * Interface to set the ui elements in undo bar
     */
    public interface UndoBarUIElements{

        /**
         * UndoBar id
         * @return
         */
        public int getUndoBarId();

        /**
         * TextView Id which displays message
         *
         * @return
         */
        public int getUndoBarMessageId();

        /**
         * UndoButton Id
         *
         * @return
         */
        public int getUndoBarButtonId();

        /**
         * UndoMessage.
         * Implement this method to customize the undo message dynamically.
         * </p>
         * You can't find the cards with these positions in your arrayAdapter because the cards are removed.
         * You have to/can use your id itemIds, to identify your cards.
         *
         * @param cardArrayAdapter  array Adapter
         * @param itemIds           ids of items
         * @param itemPositions     position of removed items
         * @return
         */
        public String getMessageUndo(CardArrayAdapter cardArrayAdapter,String[] itemIds,int[] itemPositions);

        /**
         * Define the swipe action to remove the undobar.
         * @return
         */
        public SwipeDirectionEnabled isEnabledUndoBarSwipeAction();

        /**
         * Define the animation type for the undobar when it appears.
         * @return
         */
        public AnimationType getAnimationType();


        /**
         * Enum to define the animation type of the undobar.<p/>
         * Use the {@link AnimationType#ALPHA} for an alpha animation, or {@link AnimationType#TOPBOTTOM} for a translation from bottom to top.
         */
        public enum AnimationType {
            ALPHA(0),
            TOPBOTTOM(1);

            private final int mValue;

            private AnimationType(int value) {
                mValue = value;
            }

            public int getValue() {
                return mValue;
            }
        }

        /**
         *  Enum to define the direction of the swipe action.
         *  <p/>
         *  You can use {@link SwipeDirectionEnabled#NONE}  to disable the swipe action or  {@link SwipeDirectionEnabled#LEFTRIGHT} to enable an action in left-right direction
         *  or {@link SwipeDirectionEnabled#TOPBOTTOM} to define a swipe action from top to bottom.
         */
        public enum SwipeDirectionEnabled {
            NONE(0),
            LEFTRIGHT(1),
            TOPBOTTOM(2);

            private final int mValue;

            private SwipeDirectionEnabled(int value) {
                mValue = value;
            }

            public int getValue() {
                return mValue;
            }
        }

    }

    /**
     * Default UndoBar
     *
     * You can provide a custom UndoBar.
     * This UndoBar has to contains these elements:
     * <ul>
     *    <li>A TextView</li>
     *    <li>A Button</li>
     *    <li>A root element with an id attribute </li>
     * </ul>
     *
     *  You should use the same Ids provided in the default layout list_card_undo_message,
     *  but if you have to use different ids you can use the CardArrayAdapter.setUndoBarUIElements.
     *
     *  Example:
     *  <code>
     *      mCardArrayAdapter.setUndoBarUIElements(new UndoBarController.DefaultUndoBarUIElements(){
     *
     *          //Override methods to customize the elements
     *      }
     *  </code>
     * It is very important to set the UndoBarUIElements before to call the setEnableUndo(true);
     *
     */
    public static class DefaultUndoBarUIElements implements UndoBarUIElements {

        public DefaultUndoBarUIElements(){};

        @Override
        public int getUndoBarId() {
            return R.id.list_card_undobar;
        }

        @Override
        public int getUndoBarMessageId() {
            return R.id.list_card_undobar_message;
        }

        @Override
        public int getUndoBarButtonId() {
            return R.id.list_card_undobar_button;
        }

        @Override
        public String getMessageUndo(CardArrayAdapter cardArrayAdapter, String[] itemIds, int[] itemPositions) {
            if (cardArrayAdapter!=null && cardArrayAdapter.getContext()!=null) {
                Resources res = cardArrayAdapter.getContext().getResources();
                if (res!=null)
                    return res.getQuantityString(R.plurals.list_card_undo_items, itemPositions.length, itemPositions.length);
            }
            return null;
        }

        @Override
        public SwipeDirectionEnabled isEnabledUndoBarSwipeAction() {
            return SwipeDirectionEnabled.NONE;
        }

        @Override
        public AnimationType getAnimationType() {
            return AnimationType.ALPHA;
        }

    };


    /**
     * Sets UndoBar UI Elements
     *
     * @return
     */
    public UndoBarUIElements getUndoBarUIElements() {
        return mUndoBarUIElements;
    }

    /**
     * Returns UndoBar UI Elements
     * @param undoBarUIElements
     */
    public void setUndoBarUIElements(UndoBarUIElements undoBarUIElements) {
        this.mUndoBarUIElements = undoBarUIElements;
    }
}




Java Source Code List

TabAdapterPackage.GridViewCustomAdapter.java
TabAdapterPackage.ImageAdapterDiscount.java
TabAdapterPackage.ImageAdapter.java
TabAdapterPackage.ListContactAdapter.java
com.capricorn.ArcLayout.java
com.capricorn.ArcMenu.java
com.capricorn.RayLayout.java
com.capricorn.RayMenu.java
com.capricorn.RotateAndTranslateAnimation.java
com.example.t_danbubbletea.MainActivity.java
com.example.t_danbubbletea.MySelections.java
com.example.t_danbubbletea.SplashScreen.java
it.gmariotti.cardslib.library.Constants.java
it.gmariotti.cardslib.library.internal.BaseGroupExpandableCard.java
it.gmariotti.cardslib.library.internal.CardArrayAdapter.java
it.gmariotti.cardslib.library.internal.CardArrayMultiChoiceAdapter.java
it.gmariotti.cardslib.library.internal.CardCursorAdapter.java
it.gmariotti.cardslib.library.internal.CardCursorMultiChoiceAdapter.java
it.gmariotti.cardslib.library.internal.CardExpand.java
it.gmariotti.cardslib.library.internal.CardExpandableListAdapter.java
it.gmariotti.cardslib.library.internal.CardGridArrayAdapter.java
it.gmariotti.cardslib.library.internal.CardGridArrayMultiChoiceAdapter.java
it.gmariotti.cardslib.library.internal.CardGridCursorAdapter.java
it.gmariotti.cardslib.library.internal.CardHeader.java
it.gmariotti.cardslib.library.internal.CardThumbnail.java
it.gmariotti.cardslib.library.internal.Card.java
it.gmariotti.cardslib.library.internal.ViewToClickToExpand.java
it.gmariotti.cardslib.library.internal.base.BaseCardArrayAdapter.java
it.gmariotti.cardslib.library.internal.base.BaseCardCursorAdapter.java
it.gmariotti.cardslib.library.internal.base.BaseCard.java
it.gmariotti.cardslib.library.internal.base.CardUIInferface.java
it.gmariotti.cardslib.library.internal.dismissanimation.BaseDismissAnimation.java
it.gmariotti.cardslib.library.internal.dismissanimation.SwipeDismissAnimation.java
it.gmariotti.cardslib.library.internal.multichoice.DefaultOptionMultiChoice.java
it.gmariotti.cardslib.library.internal.multichoice.MultiChoiceAdapterHelperBase.java
it.gmariotti.cardslib.library.internal.multichoice.MultiChoiceAdapter.java
it.gmariotti.cardslib.library.internal.multichoice.OptionMultiChoice.java
it.gmariotti.cardslib.library.internal.overflowanimation.BaseCardOverlayAnimation.java
it.gmariotti.cardslib.library.internal.overflowanimation.BaseOverflowAnimation.java
it.gmariotti.cardslib.library.internal.overflowanimation.TwoCardOverlayAnimation.java
it.gmariotti.cardslib.library.prototypes.CardSection.java
it.gmariotti.cardslib.library.prototypes.CardWithList.java
it.gmariotti.cardslib.library.prototypes.LinearListView.java
it.gmariotti.cardslib.library.prototypes.SectionedCardAdapter.java
it.gmariotti.cardslib.library.prototypes.SwipeDismissListItemViewTouchListener.java
it.gmariotti.cardslib.library.utils.BitmapUtils.java
it.gmariotti.cardslib.library.utils.CacheUtil.java
it.gmariotti.cardslib.library.view.BaseCardView.java
it.gmariotti.cardslib.library.view.CardExpandableListView.java
it.gmariotti.cardslib.library.view.CardGridView.java
it.gmariotti.cardslib.library.view.CardListView.java
it.gmariotti.cardslib.library.view.CardView.java
it.gmariotti.cardslib.library.view.ForegroundLinearLayout.java
it.gmariotti.cardslib.library.view.base.CardViewInterface.java
it.gmariotti.cardslib.library.view.component.CardHeaderView.java
it.gmariotti.cardslib.library.view.component.CardShadowView.java
it.gmariotti.cardslib.library.view.component.CardThumbnailView.java
it.gmariotti.cardslib.library.view.listener.SwipeDismissListViewTouchListener.java
it.gmariotti.cardslib.library.view.listener.SwipeDismissTopBottomTouchListener.java
it.gmariotti.cardslib.library.view.listener.SwipeDismissTouchListener.java
it.gmariotti.cardslib.library.view.listener.SwipeDismissViewTouchListener.java
it.gmariotti.cardslib.library.view.listener.SwipeOnScrollListener.java
it.gmariotti.cardslib.library.view.listener.UndoBarController.java
it.gmariotti.cardslib.library.view.listener.UndoCard.java
it.gmariotti.cardslib.library.view.listener.dismiss.AbstractDismissableManager.java
it.gmariotti.cardslib.library.view.listener.dismiss.DefaultDismissableManager.java
it.gmariotti.cardslib.library.view.listener.dismiss.Dismissable.java
models.AboutUsAndIngredientsCard.java
models.ApiConnectorPromotions.java
models.ApiConnector.java
models.CardDiscountAndCheckoutFormat.java
models.CommentsFragment.java
models.ContactListCard.java
models.ContactListLayout.java
models.ContactListObject.java
models.DatabaseTeaInfo.java
models.DiscountFragment.java
models.HomeFragment.java
models.IngredientsFragment.java
models.InternetConnectivityCheck.java
models.MyCheckOut.java
models.MySQLiteHelper.java
models.ResideMenuItem.java
models.ResideMenu.java
models.TeaData.java
models.TeaTypeSelection.java
models.TeaViewFragment.java
models.TouchDisableView.java
models.aboutUsFragment.java
models.newArrivalFragment.java