Android Open Source - Resonos-Android-Framework Quick Action3 D






From Project

Back to project page Resonos-Android-Framework.

License

The source code is released under:

Apache License

If you think the Android project Resonos-Android-Framework 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

package com.resonos.apps.library.widget;
/*  w  ww.ja va2 s . c om*/
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;

import com.resonos.app.library.R;
import com.resonos.apps.library.Action;
import com.resonos.apps.library.App;
import com.resonos.apps.library.widget.ToolBarButton.OnPressButtonListener;

/**
 * Popup window, shows action list as icon and text like the one in Gallery3D app.
 * 
 * With a few modifications by Chris Newhouse to allow a variety of methods of showing QuickActions.
 * 
 * @author Lorensius. W. T
 */
public class QuickAction3D extends PopupWindows3D {
  
  // constants
  protected static final int ANIM_GROW_FROM_LEFT = 1;
  protected static final int ANIM_GROW_FROM_RIGHT = 2;
  protected static final int ANIM_GROW_FROM_CENTER = 3;
  public static final int ANIM_REFLECT = 4;
  protected static final int ANIM_AUTO = 5;
  
  /** On Honeycomb and ICS, popup windows seem to be limited to 480 pixels. */
  public static final int MAX_WIDTH = 460;
  
  // objects
  private View mRootView;
  private ImageView mArrowUp;
  private ImageView mArrowDown;
  private LayoutInflater inflater;
  private ViewGroup mTrack;
  private ScrollView mScroller;
  private OnActionItemClickListener mListener;
    private OnDismissListener mDismissListener;
  
  // vars
  private int mChildPos;
  private int mAnimStyle;
    private boolean bBackHit = true;
  
  // context
  private Context cx;
  
  /**
   * Constructor.
   * 
   * @param context Context
   */
  public QuickAction3D(Context context) {
    super(context);
    cx = context;
    
    inflater     = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    
    setRootViewId(R.layout.popup);
     
    mAnimStyle    = ANIM_AUTO;
    mChildPos    = 0;
  }

  /**
   * Set root view.
   * 
   * @param id Layout resource id
   */
  public void setRootViewId(int id) {
    mRootView  = (ViewGroup) inflater.inflate(id, null);
    mTrack     = (ViewGroup) mRootView.findViewById(R.id.tracks);

    mArrowDown   = (ImageView) mRootView.findViewById(R.id.arrow_down);
    mArrowUp   = (ImageView) mRootView.findViewById(R.id.arrow_up);

    mScroller  = (ScrollView) mRootView.findViewById(R.id.scroller);
    
    setContentView(mRootView);
  }
  
  /**
   * Set animation style
   * 
   * @param animStyle animation style, default is set to ANIM_AUTO
   */
  public void setAnimStyle(int animStyle) {
    this.mAnimStyle = animStyle;
  }
  
  /**
   * Set listener for action item clicked.
   * 
   * @param listener Listener
   */
  public void setOnActionItemClickListener(OnActionItemClickListener listener) {
    mListener = listener;
  }
  
  /**
   * Add action item
   * 
   * @param action  {@link Action}
   */
  public void addActionItem(Action action) {
    ToolBarButton tbb = (ToolBarButton)inflater.inflate(R.layout.action_item, null);
    tbb.setup(action, false);
    
    final int id = action.id;
    final Enum<?> tag = action.tag;
    
    tbb.setPressListener(new OnPressButtonListener() {
      @Override
      public void onButtonPressed(ToolBarButton tbb) {
        if (mListener != null)
          mListener.onItemClick(id, tag);
        aboutToDismiss();
        dismiss();
      }
    });
    
    tbb.setFocusable(true);
    tbb.setClickable(true);
    tbb.setGravity(Gravity.LEFT);
    
    LayoutParams lp = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, (int)(0.5f + 40 * App.DENSITY));
    
    mTrack.addView(tbb, mChildPos, lp);
    
    mChildPos++;
  }
  
    public interface OnDismissListener {
        public void onDismiss(boolean backButtonHit);
    }
  
  public void addInfo(int imgDrawable, int strText, OnDismissListener l) {
    if (imgDrawable == 0)
      addInfo(null, strText, l);
    else {
      Drawable icon = cx.getResources().getDrawable(imgDrawable);
      icon.setBounds(0, 0, Math.round(40*App.DENSITY), Math.round(40*App.DENSITY));
      addInfo(icon, strText, l);
    }
  }
  
  public void addInfo(int imgDrawable, String strText, OnDismissListener l) {
    if (imgDrawable == 0)
      addInfo(null, strText, l);
    else {
      Drawable icon = cx.getResources().getDrawable(imgDrawable);
      icon.setBounds(0, 0, Math.round(40*App.DENSITY), Math.round(40*App.DENSITY));
      addInfo(icon, strText, l);
    }
  }
  
  public void addInfo(Drawable icon, int strText, OnDismissListener l) {
    String title   = cx.getString(strText);
    addInfo(icon, title, l);
  }
  
  public void addInfo(Drawable icon, String title, OnDismissListener l) {
    TextView tv = new TextView(cx);
    tv.setBackgroundColor(0);
    tv.setPadding(Math.round(4*App.DENSITY), 0, Math.round(4*App.DENSITY), 0);
    tv.setTextSize(14);
    tv.setTextColor(0xFFFFFFFF);
    tv.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

    tv.setGravity(Gravity.CENTER);
    if (icon == null) {
      //
    } else {
      tv.setCompoundDrawablePadding(Math.round(10*App.DENSITY));
      tv.setCompoundDrawables(icon, null, null, null);
    }
    
    if (title != null)
      tv.setText(title);
    
    tv.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        aboutToDismiss();
        dismiss();
      }
    });
    mTrack.setOnTouchListener(new OnTouchListener() {
      private boolean mDismissed = false;
      @Override
      public boolean onTouch(View v, MotionEvent event) {
        if (!mDismissed) {
          aboutToDismiss();
          dismiss();
          mDismissed = true;
        }
        return true;
      }
    });
    
    mDismissListener = l;
    mWindow.setOnDismissListener(new android.widget.PopupWindow.OnDismissListener() {
      public void onDismiss() {
        if (mDismissListener != null)
          mDismissListener.onDismiss(bBackHit);
      }
    });
    
    tv.setClickable(true);
    tv.setFocusable(true);
       
    mTrack.addView(tv, mChildPos);
    
    mChildPos++;
  }

  @Override
  protected void aboutToDismiss() {
    bBackHit = false;
  }
  
  @Override
  protected void preShow() {
    super.preShow();
    
    mRootView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    mRootView.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    if (mRootView.getMeasuredWidth() > MAX_WIDTH) {
      mWindow.setWidth(QuickAction3D.MAX_WIDTH);
      mRootView.measure(MAX_WIDTH, LayoutParams.WRAP_CONTENT);
    }
  }
  
  /**
   * Show popup window. Popup is automatically positioned,
   * on top or bottom of anchor view, with arrow pointing at it.
   * @param anchor : The parent view of the popup.
   */
  public void show (View anchor) {
    preShow();
    
    int xPos, yPos;
    int[] location     = new int[2];
    anchor.getLocationOnScreen(location);
    Rect anchorRect   = new Rect(location[0], location[1], location[0] + anchor.getWidth(), location[1] 
                      + anchor.getHeight());

    int screenWidth = App.SCREEN_WIDTH;
    int screenHeight = App.SCREEN_HEIGHT;
  
    int rootHeight     = Math.min(screenHeight, mRootView.getMeasuredHeight());
    int rootWidth    = Math.min(MAX_WIDTH, Math.min(screenWidth, mRootView.getMeasuredWidth()));
    
    //automatically get X coord of popup (top left)
    if ((anchorRect.left + rootWidth) > screenWidth) {
      xPos = screenWidth/2 - rootWidth/2; // anchorRect.left - (rootWidth-anchor.getWidth());
    } else {
      if (anchor.getWidth() > rootWidth) {
        xPos = anchorRect.centerX() - (rootWidth/2);
      } else {
        xPos = anchorRect.left;
      }
    }
    if ((xPos + rootWidth) < anchorRect.right)
      xPos = anchorRect.right - rootWidth;
    
    int dyTop      = anchorRect.top;
    int dyBottom    = screenHeight - anchorRect.bottom;

    boolean onTop    = (dyTop > dyBottom) ? true : false;

    if (onTop) {
      if (rootHeight > dyTop) {
        yPos       = 15;
        LayoutParams l   = mScroller.getLayoutParams();
        l.height    = dyTop - anchor.getHeight();
      } else {
        yPos = anchorRect.top - rootHeight;
      }
    } else {
      yPos = anchorRect.bottom;
      
      if (rootHeight > dyBottom) { 
        LayoutParams l   = mScroller.getLayoutParams();
        l.height    = dyBottom;
      }
    }
//    Log.v("QuickAction3D", "show() | screen: " + screenWidth + "x"+ screenHeight
//        +", root: "+mRootView.getMeasuredWidth()+"x"+mRootView.getMeasuredHeight()+", pos: "+xPos+", "+yPos
//        +", act width: " + mRootView.getWidth() + "x"+mRootView.getHeight());
    
    showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up), anchorRect.centerX()-xPos);
    
    setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);
    
    try {
      mWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, xPos, yPos);
    } catch (Exception ex) {
      // don't crash if we try to show a tooltip after finish()
    }
  }
  
  /**
   * Show popup window with no arrow. Popup is automatically centered.
   * @param parent : The parent view of the popup.
   * @param high : Move the popup to the top of the screen if true.
   */
  public void showCentered(View parent, boolean high) {
    preShow();
    
    int xPos, yPos;

    int screenWidth = App.SCREEN_WIDTH;
    int screenHeight = App.SCREEN_HEIGHT;
  
    int rootHeight     = Math.min(screenHeight, mRootView.getMeasuredHeight());
    int rootWidth    = Math.min(MAX_WIDTH, Math.min(screenWidth, mRootView.getMeasuredWidth()));
    
    //automatically get X coord of popup (top left)
    xPos = screenWidth/2 - (rootWidth/2);
    yPos = high ? Math.round(24*parent.getContext().getResources().getDisplayMetrics().density)
        : (screenHeight/2 - (rootHeight/2));

//    Log.v("QuickAction3D", "showCentered() | screen: " + screenWidth + "x"+ screenHeight
//        +", root: "+mRootView.getMeasuredWidth()+"x"+mRootView.getMeasuredHeight()+", pos: "+xPos+", "+yPos
//        +", act width: " + mRootView.getWidth() + "x"+mRootView.getHeight());
    
    setAnimationStyle(screenWidth, screenWidth/2, true);

    mArrowUp.setVisibility(View.GONE);
    mArrowDown.setVisibility(View.GONE);
    
    try {
      mWindow.showAtLocation(parent, Gravity.NO_GRAVITY, xPos, yPos);
    } catch (Exception ex) {
      // don't crash if we try to show a tooltip after finish()
    }
  }
  
  /**
   * Show popup window. Popup is positioned with arrow pointing at a given coordinate
   * @param parent : The parent view of the popup.
   * @param x : X coordinate
   * @param y : Y coordinate
   */
  public void showAt (View parent, int x, int y) {
    preShow();
    
    int xPos, yPos;

    int screenWidth = App.SCREEN_WIDTH;
    int screenHeight = App.SCREEN_HEIGHT;
  
    int rootHeight     = Math.min(screenHeight, mRootView.getMeasuredHeight());
    int rootWidth    = Math.min(MAX_WIDTH, Math.min(screenWidth, mRootView.getMeasuredWidth()));
    
    //automatically get X coord of popup (top left)
    if ((x + rootWidth/2) > screenWidth) {
      xPos = screenWidth - rootWidth;
    } else if (x < rootWidth/2) {
      xPos =  0;
    } else {
      xPos = x - rootWidth/2;
    }
    
    int dyTop      = y;
    int dyBottom    = screenHeight - y;

    boolean onTop    = (dyTop > dyBottom) ? true : false;

    if (onTop) {
      if (rootHeight > dyTop) {
        yPos       = 15;
        LayoutParams l   = mScroller.getLayoutParams();
        l.height    = dyTop - 0;
      } else {
        yPos = y - rootHeight;
      }
    } else {
      yPos = y;
      
      if (rootHeight > dyBottom) { 
        LayoutParams l   = mScroller.getLayoutParams();
        l.height    = dyBottom;
      }
    }
    
    Log.v("QuickAction3D", "showAt("+x+","+y+") | result location: " + xPos+","+yPos+" |  screen: " + screenWidth + "x"+ screenHeight
        +", root: "+mRootView.getMeasuredWidth()+"x"+mRootView.getMeasuredHeight()+", pos: "+xPos+", "+yPos
        +", act width: " + mRootView.getWidth() + "x"+mRootView.getHeight());
    
    showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up), x-xPos);
    
    setAnimationStyle(screenWidth, x, onTop);
    
    try {
      mWindow.showAtLocation(parent, Gravity.NO_GRAVITY, xPos, yPos);
    } catch (Exception ex) {
      // don't crash if we try to show a tooltip after finish()
    }
  }
  
  /**
   * Set animation style
   * 
   * @param screenWidth screen width
   * @param requestedX distance from left edge
   * @param onTop flag to indicate where the popup should be displayed. Set TRUE if displayed on top of anchor view
   *       and vice versa
   */
  private void setAnimationStyle(int screenWidth, int requestedX, boolean onTop) {
    int arrowPos = requestedX - mArrowUp.getMeasuredWidth()/2;

    switch (mAnimStyle) {
    case ANIM_GROW_FROM_LEFT:
      mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);
      break;
          
    case ANIM_GROW_FROM_RIGHT:
      mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);
      break;
          
    case ANIM_GROW_FROM_CENTER:
      mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);
    break;
      
    case ANIM_REFLECT:
      mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect : R.style.Animations_PopDownMenu_Reflect);
    break;
    
    case ANIM_AUTO:
      if (arrowPos <= screenWidth/4) {
        mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);
      } else if (arrowPos > screenWidth/4 && arrowPos < 3 * (screenWidth/4)) {
        mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);
      } else {
        mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);
      }
          
      break;
    }
  }
  
  /**
   * Show arrow
   * 
   * @param whichArrow arrow type resource id
   * @param requestedX distance from left screen
   */
  private void showArrow(int whichArrow, int requestedX) {
        final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp : mArrowDown;
        final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown : mArrowUp;

        final int arrowWidth = mArrowUp.getMeasuredWidth();

        showArrow.setVisibility(View.VISIBLE);
        
        ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams)showArrow.getLayoutParams();
       
        param.leftMargin = requestedX - arrowWidth / 2;
        
        hideArrow.setVisibility(View.INVISIBLE);
    }
  
  /**
   * Listener for item click
   *
   */
  public interface OnActionItemClickListener {
    public abstract void onItemClick(int pos, Enum<?> tag);
  }
}




Java Source Code List

com.resonos.apps.library.Action.java
com.resonos.apps.library.AlertFragment.java
com.resonos.apps.library.App.java
com.resonos.apps.library.BaseFragment.java
com.resonos.apps.library.FragmentBaseActivity.java
com.resonos.apps.library.file.AltAndroidFileHandle.java
com.resonos.apps.library.file.AltAndroidFiles.java
com.resonos.apps.library.file.AltFileHandle.java
com.resonos.apps.library.file.FileCache.java
com.resonos.apps.library.media.AudioVisualizer.java
com.resonos.apps.library.media.BitmapMemoryCache.java
com.resonos.apps.library.media.HueColorFilter.java
com.resonos.apps.library.media.ImageLoader.java
com.resonos.apps.library.media.MediaScannerNotifier.java
com.resonos.apps.library.model.Coord.java
com.resonos.apps.library.model.ImmutableCoord.java
com.resonos.apps.library.tabviewpager.CustomViewPager.java
com.resonos.apps.library.tabviewpager.PageIndicator.java
com.resonos.apps.library.tabviewpager.TabPageIndicator.java
com.resonos.apps.library.tabviewpager.TabViewPagerAdapter.java
com.resonos.apps.library.tabviewpager.TabViewPagerFragment.java
com.resonos.apps.library.tabviewpager.TitleProvider.java
com.resonos.apps.library.util.AppUtils.java
com.resonos.apps.library.util.ErrorReporter.java
com.resonos.apps.library.util.LifecycleTaskQueue.java
com.resonos.apps.library.util.M.java
com.resonos.apps.library.util.NetworkClient.java
com.resonos.apps.library.util.NetworkRequest.java
com.resonos.apps.library.util.ParameterList.java
com.resonos.apps.library.util.SensorReader.java
com.resonos.apps.library.util.TouchViewWorker.java
com.resonos.apps.library.util.ViewServer.java
com.resonos.apps.library.widget.DashboardLayout.java
com.resonos.apps.library.widget.FormBuilder.java
com.resonos.apps.library.widget.FormElement.java
com.resonos.apps.library.widget.ListFormBuilder.java
com.resonos.apps.library.widget.PopupWindows3D.java
com.resonos.apps.library.widget.QuickAction3D.java
com.resonos.apps.library.widget.RangeSeekBar.java
com.resonos.apps.library.widget.SeekBar.java
com.resonos.apps.library.widget.ToolBarButton.java
com.resonos.apps.library.widget.ToolBar.java