QuickAction.java 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /* ownCloud Android client application
  2. * Copyright (C) 2011 Bartek Przybylski
  3. * Copyright (C) 2012-2013 ownCloud Inc.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2,
  7. * as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. */
  18. package com.owncloud.android.ui;
  19. import android.content.Context;
  20. import android.graphics.Rect;
  21. import android.graphics.drawable.Drawable;
  22. import android.widget.ImageView;
  23. import android.widget.TextView;
  24. import android.widget.LinearLayout;
  25. import android.widget.ScrollView;
  26. import android.view.Gravity;
  27. import android.view.LayoutInflater;
  28. import android.view.View;
  29. import android.view.View.OnClickListener;
  30. import android.view.ViewGroup.LayoutParams;
  31. import android.view.ViewGroup;
  32. import java.util.ArrayList;
  33. import com.owncloud.android.R;
  34. /**
  35. * Popup window, shows action list as icon and text like the one in Gallery3D
  36. * app.
  37. *
  38. * @author Lorensius. W. T
  39. */
  40. public class QuickAction extends CustomPopup {
  41. private final View root;
  42. private final ImageView mArrowUp;
  43. private final ImageView mArrowDown;
  44. private final LayoutInflater inflater;
  45. private final Context context;
  46. protected static final int ANIM_GROW_FROM_LEFT = 1;
  47. protected static final int ANIM_GROW_FROM_RIGHT = 2;
  48. protected static final int ANIM_GROW_FROM_CENTER = 3;
  49. protected static final int ANIM_REFLECT = 4;
  50. protected static final int ANIM_AUTO = 5;
  51. private int animStyle;
  52. private ViewGroup mTrack;
  53. private ScrollView scroller;
  54. private ArrayList<ActionItem> actionList;
  55. /**
  56. * Constructor
  57. *
  58. * @param anchor {@link View} on where the popup window should be displayed
  59. */
  60. public QuickAction(View anchor) {
  61. super(anchor);
  62. actionList = new ArrayList<ActionItem>();
  63. context = anchor.getContext();
  64. inflater = (LayoutInflater) context
  65. .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  66. root = (ViewGroup) inflater.inflate(R.layout.popup, null);
  67. mArrowDown = (ImageView) root.findViewById(R.id.arrow_down);
  68. mArrowUp = (ImageView) root.findViewById(R.id.arrow_up);
  69. setContentView(root);
  70. mTrack = (ViewGroup) root.findViewById(R.id.tracks);
  71. scroller = (ScrollView) root.findViewById(R.id.scroller);
  72. animStyle = ANIM_AUTO;
  73. }
  74. /**
  75. * Set animation style
  76. *
  77. * @param animStyle animation style, default is set to ANIM_AUTO
  78. */
  79. public void setAnimStyle(int animStyle) {
  80. this.animStyle = animStyle;
  81. }
  82. /**
  83. * Add action item
  84. *
  85. * @param action {@link ActionItem} object
  86. */
  87. public void addActionItem(ActionItem action) {
  88. actionList.add(action);
  89. }
  90. /**
  91. * Show popup window. Popup is automatically positioned, on top or bottom of
  92. * anchor view.
  93. *
  94. */
  95. public void show() {
  96. preShow();
  97. int xPos, yPos;
  98. int[] location = new int[2];
  99. mAnchor.getLocationOnScreen(location);
  100. Rect anchorRect = new Rect(location[0], location[1], location[0]
  101. + mAnchor.getWidth(), location[1] + mAnchor.getHeight());
  102. createActionList();
  103. root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
  104. LayoutParams.WRAP_CONTENT));
  105. root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
  106. int rootHeight = root.getMeasuredHeight();
  107. int rootWidth = root.getMeasuredWidth();
  108. int screenWidth = mWManager.getDefaultDisplay().getWidth();
  109. int screenHeight = mWManager.getDefaultDisplay().getHeight();
  110. // automatically get X coord of popup (top left)
  111. if ((anchorRect.left + rootWidth) > screenWidth) {
  112. xPos = anchorRect.left - (rootWidth - mAnchor.getWidth());
  113. } else {
  114. if (mAnchor.getWidth() > rootWidth) {
  115. xPos = anchorRect.centerX() - (rootWidth / 2);
  116. } else {
  117. xPos = anchorRect.left;
  118. }
  119. }
  120. int dyTop = anchorRect.top;
  121. int dyBottom = screenHeight - anchorRect.bottom;
  122. boolean onTop = (dyTop > dyBottom) ? true : false;
  123. if (onTop) {
  124. if (rootHeight > dyTop) {
  125. yPos = 15;
  126. LayoutParams l = scroller.getLayoutParams();
  127. l.height = dyTop - mAnchor.getHeight();
  128. } else {
  129. yPos = anchorRect.top - rootHeight;
  130. }
  131. } else {
  132. yPos = anchorRect.bottom;
  133. if (rootHeight > dyBottom) {
  134. LayoutParams l = scroller.getLayoutParams();
  135. l.height = dyBottom;
  136. }
  137. }
  138. showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up),
  139. anchorRect.centerX() - xPos);
  140. setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);
  141. mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xPos, yPos);
  142. }
  143. /**
  144. * Set animation style
  145. *
  146. * @param screenWidth screen width
  147. * @param requestedX distance from left edge
  148. * @param onTop flag to indicate where the popup should be displayed. Set
  149. * TRUE if displayed on top of anchor view and vice versa
  150. */
  151. private void setAnimationStyle(int screenWidth, int requestedX,
  152. boolean onTop) {
  153. int arrowPos = requestedX - mArrowUp.getMeasuredWidth() / 2;
  154. switch (animStyle) {
  155. case ANIM_GROW_FROM_LEFT:
  156. mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left
  157. : R.style.Animations_PopDownMenu_Left);
  158. break;
  159. case ANIM_GROW_FROM_RIGHT:
  160. mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right
  161. : R.style.Animations_PopDownMenu_Right);
  162. break;
  163. case ANIM_GROW_FROM_CENTER:
  164. mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center
  165. : R.style.Animations_PopDownMenu_Center);
  166. break;
  167. case ANIM_REFLECT:
  168. mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect
  169. : R.style.Animations_PopDownMenu_Reflect);
  170. break;
  171. case ANIM_AUTO:
  172. if (arrowPos <= screenWidth / 4) {
  173. mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left
  174. : R.style.Animations_PopDownMenu_Left);
  175. } else if (arrowPos > screenWidth / 4
  176. && arrowPos < 3 * (screenWidth / 4)) {
  177. mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center
  178. : R.style.Animations_PopDownMenu_Center);
  179. } else {
  180. mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right
  181. : R.style.Animations_PopDownMenu_Right);
  182. }
  183. break;
  184. }
  185. }
  186. /**
  187. * Create action list
  188. */
  189. private void createActionList() {
  190. View view;
  191. String title;
  192. Drawable icon;
  193. OnClickListener listener;
  194. for (int i = 0; i < actionList.size(); i++) {
  195. title = actionList.get(i).getTitle();
  196. icon = actionList.get(i).getIcon();
  197. listener = actionList.get(i).getOnClickListerner();
  198. view = getActionItem(title, icon, listener);
  199. view.setFocusable(true);
  200. view.setClickable(true);
  201. mTrack.addView(view);
  202. }
  203. }
  204. /**
  205. * Get action item {@link View}
  206. *
  207. * @param title action item title
  208. * @param icon {@link Drawable} action item icon
  209. * @param listener {@link View.OnClickListener} action item listener
  210. * @return action item {@link View}
  211. */
  212. private View getActionItem(String title, Drawable icon,
  213. OnClickListener listener) {
  214. LinearLayout container = (LinearLayout) inflater.inflate(
  215. R.layout.action_item, null);
  216. ImageView img = (ImageView) container.findViewById(R.id.icon);
  217. TextView text = (TextView) container.findViewById(R.id.title);
  218. if (icon != null) {
  219. img.setImageDrawable(icon);
  220. }
  221. if (title != null) {
  222. text.setText(title);
  223. }
  224. if (listener != null) {
  225. container.setOnClickListener(listener);
  226. }
  227. return container;
  228. }
  229. /**
  230. * Show arrow
  231. *
  232. * @param whichArrow arrow type resource id
  233. * @param requestedX distance from left screen
  234. */
  235. private void showArrow(int whichArrow, int requestedX) {
  236. final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp
  237. : mArrowDown;
  238. final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown
  239. : mArrowUp;
  240. final int arrowWidth = mArrowUp.getMeasuredWidth();
  241. showArrow.setVisibility(View.VISIBLE);
  242. ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams) showArrow
  243. .getLayoutParams();
  244. param.leftMargin = requestedX - arrowWidth / 2;
  245. hideArrow.setVisibility(View.INVISIBLE);
  246. }
  247. }