QuickAction.java 9.7 KB

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