Wednesday, March 6, 2013

Android QuickActionDemo

QuickAction is an enthusiast feature in android to provide a popup window where user can choose an action immediately.


Download the source code from  QuickActionDemo

for this purpose make a project with name QuickActionDemo and have a main activity with name MainActivity .java



package com.jitesh.quickactiondemo;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TableRow;
import android.widget.Toast;

/**
 * Simple demo Activity
 *
 * @author jitesh
 *
 */
public class MainActivity extends Activity {
private Button likemenuButton;
private Button likequickactionButton;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.demo_layout);

this.likemenuButton = (Button) this.findViewById(R.id.likemenu);
this.likemenuButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DemoPopupWindow dw = new DemoPopupWindow(v);
dw.showLikePopDownMenu();
}
});

this.likequickactionButton = (Button) this
.findViewById(R.id.likequickaction);
this.likequickactionButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
DemoPopupWindow dw = new DemoPopupWindow(v);
dw.showLikeQuickAction(0, 30);
}
});

}

/**
* Extends {@link BetterPopupWindow}
* <p>
* Overrides onCreate to create the view and register the button listeners
*
* @author qbert
*
*/
private static class DemoPopupWindow extends BetterPopupWindow implements
OnClickListener {
public DemoPopupWindow(View anchor) {
super(anchor);
}

@Override
protected void onCreate() {
// inflate layout
LayoutInflater inflater = (LayoutInflater) this.anchor.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

ViewGroup root = (ViewGroup) inflater.inflate(
R.layout.popup_grid_layout, null);

// setup button events
for (int i = 0, icount = root.getChildCount(); i < icount; i++) {
View v = root.getChildAt(i);

if (v instanceof TableRow) {
TableRow row = (TableRow) v;

for (int j = 0, jcount = row.getChildCount(); j < jcount; j++) {
View item = row.getChildAt(j);
if (item instanceof Button) {
Button b = (Button) item;
b.setOnClickListener(this);
}
}
}
}

// set the inflated view as what we want to display
this.setContentView(root);
}

@Override
public void onClick(View v) {
// we'll just display a simple toast on a button click
Button b = (Button) v;
Toast.makeText(this.anchor.getContext(), b.getText(),
Toast.LENGTH_SHORT).show();
this.dismiss();
}
}
}


make a BetterPopupWindow.java as follows

package com.jitesh.quickactiondemo;

import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.PopupWindow;

/**
 * This class does most of the work of wrapping the {@link PopupWindow} so it's simpler to use.
 * 
 * @author jitesh
 * 
 */
public class BetterPopupWindow {
        protected final View anchor;
        private final PopupWindow window;
        private View root;
        private Drawable background = null;
        private final WindowManager windowManager;

        /**
         * Create a BetterPopupWindow
         * 
         * @param anchor
         *            the view that the BetterPopupWindow will be displaying 'from'
         */
        public BetterPopupWindow(View anchor) {
                this.anchor = anchor;
                this.window = new PopupWindow(anchor.getContext());

                // when a touch even happens outside of the window
                // make the window go away
                this.window.setTouchInterceptor(new OnTouchListener() {
                        @Override
                        public boolean onTouch(View v, MotionEvent event) {
                                if(event.getAction() == MotionEvent.ACTION_OUTSIDE) {
                                        BetterPopupWindow.this.window.dismiss();
                                        return true;
                                }
                                return false;
                        }
                });

                this.windowManager = (WindowManager) this.anchor.getContext().getSystemService(Context.WINDOW_SERVICE);
                onCreate();
        }

        /**
         * Anything you want to have happen when created. Probably should create a view and setup the event listeners on
         * child views.
         */
        protected void onCreate() {}

        /**
         * In case there is stuff to do right before displaying.
         */
        protected void onShow() {}

        private void preShow() {
                if(this.root == null) {
                        throw new IllegalStateException("setContentView was not called with a view to display.");
                }
                onShow();

                if(this.background == null) {
                        this.window.setBackgroundDrawable(new BitmapDrawable());
                } else {
                        this.window.setBackgroundDrawable(this.background);
                }

                // if using PopupWindow#setBackgroundDrawable this is the only values of the width and hight that make it work
                // otherwise you need to set the background of the root viewgroup
                // and set the popupwindow background to an empty BitmapDrawable
                this.window.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
                this.window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
                this.window.setTouchable(true);
                this.window.setFocusable(true);
                this.window.setOutsideTouchable(true);

                this.window.setContentView(this.root);
        }

        public void setBackgroundDrawable(Drawable background) {
                this.background = background;
        }

        /**
         * Sets the content view. Probably should be called from {@link onCreate}
         * 
         * @param root
         *            the view the popup will display
         */
        public void setContentView(View root) {
                this.root = root;
                this.window.setContentView(root);
        }

        /**
         * Will inflate and set the view from a resource id
         * 
         * @param layoutResID
         */
        public void setContentView(int layoutResID) {
                LayoutInflater inflator =
                                (LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                this.setContentView(inflator.inflate(layoutResID, null));
        }

        /**
         * If you want to do anything when {@link dismiss} is called
         * 
         * @param listener
         */
        public void setOnDismissListener(PopupWindow.OnDismissListener listener) {
                this.window.setOnDismissListener(listener);
        }

        /**
         * Displays like a popdown menu from the anchor view
         */
        public void showLikePopDownMenu() {
                this.showLikePopDownMenu(0, 0);
        }

        /**
         * Displays like a popdown menu from the anchor view.
         * 
         * @param xOffset
         *            offset in X direction
         * @param yOffset
         *            offset in Y direction
         */
        public void showLikePopDownMenu(int xOffset, int yOffset) {
                this.preShow();

                this.window.setAnimationStyle(R.style.Animations_PopDownMenu);

                this.window.showAsDropDown(this.anchor, xOffset, yOffset);
        }

        /**
         * Displays like a QuickAction from the anchor view.
         */
        public void showLikeQuickAction() {
                this.showLikeQuickAction(0, 0);
        }

        /**
         * Displays like a QuickAction from the anchor view.
         * 
         * @param xOffset
         *            offset in the X direction
         * @param yOffset
         *            offset in the Y direction
         */
        public void showLikeQuickAction(int xOffset, int yOffset) {
                this.preShow();

                this.window.setAnimationStyle(R.style.Animations_GrowFromBottom);

                int[] location = new int[2];
                this.anchor.getLocationOnScreen(location);

                Rect anchorRect =
                                new Rect(location[0], location[1], location[0] + this.anchor.getWidth(), location[1]
                                        + this.anchor.getHeight());

                this.root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

                int rootWidth = this.root.getMeasuredWidth();
                int rootHeight = this.root.getMeasuredHeight();

                int screenWidth = this.windowManager.getDefaultDisplay().getWidth();
                int screenHeight = this.windowManager.getDefaultDisplay().getHeight();

                int xPos = ((screenWidth - rootWidth) / 2) + xOffset;
                int yPos = anchorRect.top - rootHeight + yOffset;

                // display on bottom
                if(rootHeight > anchorRect.top) {
                        yPos = anchorRect.bottom + yOffset;
                        this.window.setAnimationStyle(R.style.Animations_GrowFromTop);
                }

                this.window.showAtLocation(this.anchor, Gravity.NO_GRAVITY, xPos, yPos);
        }

        public void dismiss() {
                this.window.dismiss();
        }
}

demo_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
>
        <Button
                android:id="@+id/likemenu"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="30dp"
                android:text="Button" />
        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
        >
        </TextView>
        <Button
                android:id="@+id/likequickaction"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:padding="30dp"
                android:text="Button" />
</LinearLayout>

popup_grid_layout.xml


<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@android:drawable/alert_light_frame" >

    <TableRow>

        <Button
            android:id="@+id/one"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:minHeight="80dp"
            android:minWidth="80dp"
            android:text="One" />

        <Button
            android:id="@+id/two"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:minHeight="80dp"
            android:minWidth="80dp"
            android:text="Two" />

        <Button
            android:id="@+id/three"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:minHeight="80dp"
            android:minWidth="80dp"
            android:text="Three" />
    </TableRow>

    <TableRow>

        <Button
            android:id="@+id/four"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:minHeight="80dp"
            android:text="Four" />

        <Button
            android:id="@+id/five"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:minHeight="80dp"
            android:text="Five" />

        <Button
            android:id="@+id/six"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:minHeight="80dp"
            android:text="Six" />
    </TableRow>

</TableLayout>




grow_from_bottom.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
        <scale
                android:fromXScale="0.3" android:toXScale="1.0"
                android:fromYScale="0.3" android:toYScale="1.0"
                android:pivotX="50%" android:pivotY="100%"
                android:duration="@android:integer/config_shortAnimTime"
        />
        <alpha
                android:interpolator="@android:anim/decelerate_interpolator"
                android:fromAlpha="0.0" android:toAlpha="1.0"
                android:duration="@android:integer/config_shortAnimTime"
        />
</set>




grow_from_top.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
        <scale
                android:fromXScale="0.3" android:toXScale="1.0"
                android:fromYScale="0.3" android:toYScale="1.0"
                android:pivotX="50%" android:pivotY="0%"
                android:duration="@android:integer/config_shortAnimTime"
        />
        <alpha
                android:interpolator="@android:anim/decelerate_interpolator"
                android:fromAlpha="0.0" android:toAlpha="1.0"
                android:duration="@android:integer/config_shortAnimTime"
        />
</set>


grow_from_topleft_to_bottomright.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
        <scale
                android:fromXScale="0.3" android:toXScale="1.0"
                android:fromYScale="0.3" android:toYScale="1.0"
                android:pivotX="0%" android:pivotY="0%"
                android:duration="@android:integer/config_shortAnimTime"
        />
        <alpha
                android:interpolator="@android:anim/decelerate_interpolator"
                android:fromAlpha="0.0" android:toAlpha="1.0"
                android:duration="@android:integer/config_shortAnimTime"
        />
</set>


shrink_from_bottom.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
        <scale
                android:fromXScale="1.0" android:toXScale="0.3"
                android:fromYScale="1.0" android:toYScale="0.3"
                android:pivotX="50%" android:pivotY="0%"
                android:duration="@android:integer/config_shortAnimTime"
        />
        <alpha
                android:interpolator="@android:anim/accelerate_interpolator"
                android:fromAlpha="1.0" android:toAlpha="0.0"
                android:duration="@android:integer/config_shortAnimTime"
        />
</set>


shrink_from_bottomright_to_topleft.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
        <scale
                android:fromXScale="1.0" android:toXScale="0.3"
                android:fromYScale="1.0" android:toYScale="0.3"
                android:pivotX="0%" android:pivotY="0%"
                android:duration="@android:integer/config_shortAnimTime"
        />
        <alpha
                android:interpolator="@android:anim/accelerate_interpolator"
                android:fromAlpha="1.0" android:toAlpha="0.0"
                android:duration="@android:integer/config_shortAnimTime"
        />
</set>


shrink_from_top.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
        <scale
                android:fromXScale="1.0" android:toXScale="0.3"
                android:fromYScale="1.0" android:toYScale="0.3"
                android:pivotX="50%" android:pivotY="100%"
                android:duration="@android:integer/config_shortAnimTime"
        />
        <alpha
                android:interpolator="@android:anim/accelerate_interpolator"
                android:fromAlpha="1.0" android:toAlpha="0.0"
                android:duration="@android:integer/config_shortAnimTime"
        />
</set>





No comments:

Post a Comment