Android Path菜单的简单实现

  1. */

  2. private boolean bMenuShow;

  3. private static int  xOffset     = 15;

  4. private static int  yOffset     = -13;

  5. /**

  6. * 菜单的资源个数.

  7. */

  8. private int[] menuResIds = {R.drawable.composer_camera,R.drawable.composer_music,

  9. R.drawable.composer_sleep,R.drawable.composer_music,R.drawable.composer_place};

  10. public PathMenuView(Context context){

  11. super(context);

  12. setupViews();

  13. }

  14. public PathMenuView(Context context, AttributeSet attrs) {

  15. super(context, attrs);

  16. TypedArray a = context.obtainStyledAttributes(attrs,

  17. R.styleable.PathMenuView);

  18. position = a.getInt(R.styleable.PathMenuView_position,3);

  19. a.recycle();

  20. setupViews();

  21. }

  22. private void setupViews(){

  23. mContext = getContext();

  24. mHEIGHT = mContext.getResources().getDisplayMetrics().heightPixels;

  25. mWIDTH = mContext.getResources().getDisplayMetrics().widthPixels;

  26. mDensity = mContext.getResources().getDisplayMetrics().density;

  27. xOffset = (int) (10.667 * mDensity);

  28. yOffset = (int) (8.667 * mDensity);

  29. mHome = new ImageView(mContext);

  30. mHome.setImageResource(R.drawable.composer_button);

  31. mHome.setOnClickListener(listener);

  32. addView(mHome);

  33. LayoutParams mHomeparams = (FrameLayout.LayoutParams)mHome.getLayoutParams();

  34. mHomeparams.width = LayoutParams.WRAP_CONTENT;

  35. mHomeparams.height = LayoutParams.WRAP_CONTENT;

  36. switch (position) {

  37. case LEFT_TOP:

  38. mHomeparams.gravity = Gravity.LEFT | Gravity.TOP;

  39. for (int i = 0; i < menuResIds.length; i++) {

  40. int width_padding = mWIDTH / ((menuResIds.length - 1) * 2);

  41. int height_padding = mHEIGHT / ((menuResIds.length - 1) * 2);

  42. ImageView imageView = new ImageView(mContext);

  43. imageView.setImageResource(menuResIds[i]);

  44. addView(imageView);

  45. LayoutParams params = (FrameLayout.LayoutParams) imageView

  46. .getLayoutParams();

  47. params.width = LayoutParams.WRAP_CONTENT;

  48. params.height = LayoutParams.WRAP_CONTENT;

  49. params.leftMargin = mWIDTH / 2

  50. - ((menuResIds.length - i - 1) * width_padding);

  51. params.topMargin = mHEIGHT / 2 - i * height_padding;

  52. params.gravity = Gravity.LEFT | Gravity.TOP;

  53. imageView.setLayoutParams(params);

  54. }

  55. break;

  56. case RIGHT_TOP:

  57. mHomeparams.gravity = Gravity.RIGHT | Gravity.TOP;

  58. for (int i = 0; i < menuResIds.length; i++) {

  59. int width_padding = mWIDTH / ((menuResIds.length - 1) * 2);

  60. int height_padding = mHEIGHT / ((menuResIds.length - 1) * 2);

  61. ImageView imageView = new ImageView(mContext);

  62. imageView.setImageResource(menuResIds[i]);

  63. addView(imageView);

  64. LayoutParams params = (FrameLayout.LayoutParams) imageView

  65. .getLayoutParams();

  66. params.width = LayoutParams.WRAP_CONTENT;

  67. params.height = LayoutParams.WRAP_CONTENT;

  68. params.rightMargin = mWIDTH / 2

  69. - ((menuResIds.length - i - 1) * width_padding);

  70. params.topMargin = mHEIGHT / 2 - i * height_padding;

  71. params.gravity = Gravity.RIGHT | Gravity.TOP;

  72. imageView.setLayoutParams(params);

  73. }

  74. break;

  75. case RIGHT_BOTTOM:

  76. mHomeparams.gravity = Gravity.RIGHT | Gravity.BOTTOM;

  77. for (int i = 0; i < menuResIds.length; i++) {

  78. int width_padding = mWIDTH / ((menuResIds.length - 1) * 2);

  79. int height_padding = mHEIGHT / ((menuResIds.length - 1) * 2);

  80. ImageView imageView = new ImageView(mContext);

  81. imageView.setImageResource(menuResIds[i]);

  82. addView(imageView);

  83. LayoutParams params = (FrameLayout.LayoutParams) imageView

  84. .getLayoutParams();

  85. params.width = LayoutParams.WRAP_CONTENT;

  86. params.height = LayoutParams.WRAP_CONTENT;

  87. params.rightMargin = mWIDTH / 2

  88. - ((menuResIds.length - i - 1) * width_padding);

  89. params.bottomMargin = mHEIGHT / 2 - i * height_padding;

  90. params.gravity = Gravity.RIGHT | Gravity.BOTTOM;

  91. imageView.setLayoutParams(params);

  92. }

  93. break;

  94. case LEFT_BOTTOM:

  95. mHomeparams.gravity = Gravity.LEFT | Gravity.BOTTOM;

  96. for(int i = 0; i < menuResIds.length; i++){

  97. int width_padding = mWIDTH / ((menuResIds.length - 1) * 2);

  98. int height_padding = mHEIGHT / ((menuResIds.length -1) * 2);

  99. ImageView imageView = new ImageView(mContext);

  100. imageView.setImageResource(menuResIds[i]);

  101. addView(imageView);

  102. LayoutParams params = (FrameLayout.LayoutParams)imageView.getLayoutParams();

  103. params.width = LayoutParams.WRAP_CONTENT;

  104. params.height = LayoutParams.WRAP_CONTENT;

  105. params.leftMargin = mWIDTH / 2 - ((menuResIds.length - i - 1) * width_padding);

  106. params.bottomMargin = mHEIGHT / 2 - i * height_padding;

  107. params.gravity = Gravity.LEFT | Gravity.BOTTOM;

  108. imageView.setLayoutParams(params);

  109. }

  110. break;

  111. default:

  112. break;

  113. }

  114. mHome.setLayoutParams(mHomeparams);

  115. }

  116. private OnClickListener listener = new OnClickListener() {

  117. public void onClick(View v) {

  118. if (!bMenuShow) {

  119. startAnimationIn(PathMenuView.this, 300);

  120. } else {

  121. startAnimationOut(PathMenuView.this, 300);

  122. }

  123. bMenuShow = !bMenuShow;

  124. }

  125. };

  126. /**

  127. * 菜单隐藏动画.

  128. *

  129. * @param group

  130. * @param duration

  131. */

  132. private void startAnimationIn(ViewGroup group, int duration) {

  133. for (int i = 1; i < group.getChildCount(); i++) {

  134. ImageView imageview = (ImageView) group.getChildAt(i);

  135. imageview.setVisibility(0);

  136. MarginLayoutParams mlp = (MarginLayoutParams) imageview

  137. .getLayoutParams();

  138. Animation animation = null;

  139. switch (position) {

  140. case LEFT_TOP:

  141. animation = new TranslateAnimation(0F,-mlp.leftMargin+xOffset,0F,-mlp.topMargin + yOffset);

  142. break;

  143. case RIGHT_TOP:

  144. animation = new TranslateAnimation(mlp.rightMargin - xOffset,0F,-mlp.topMargin + yOffset,0F);

  145. break;

  146. case LEFT_BOTTOM:

  147. animation = new TranslateAnimation(0F, -mlp.leftMargin+ xOffset, 0F, -yOffset + mlp.bottomMargin);

  148. break;

  149. case RIGHT_BOTTOM:

  150. animation = new TranslateAnimation(mlp.rightMargin-xOffset,0F,-yOffset + mlp.bottomMargin, 0F);

  151. break;

  152. default:

  153. break;

  154. }

  155. animation.setFillAfter(true);

  156. animation.setDuration(duration);

  157. animation.setStartOffset((i * 100) / (-1 + group.getChildCount()));

  158. animation.setInterpolator(new OvershootInterpolator(2F));

  159. imageview.startAnimation(animation);

  160. }

  161. }

  162. /**

  163. * 菜单显示动画.

  164. *

  165. * @param group

  166. * @param duration

  167. */

  168. private void startAnimationOut(ViewGroup group,int duration){

  169. for (int i = 1; i < group.getChildCount(); i++) {

  170. final ImageView imageview = (ImageView) group

  171. .getChildAt(i);

  172. MarginLayoutParams mlp = (MarginLayoutParams) imageview.getLayoutParams();

  173. Animation animation = null;

  174. switch (position) {

  175. case LEFT_TOP:

  176. animation = new TranslateAnimation(-mlp.leftMargin+xOffset,0F,-mlp.topMargin + yOffset,0F);

  177. break;

  178. case RIGHT_TOP:

  179. animation = new TranslateAnimation(0F,mlp.rightMargin - xOffset,0F,-mlp.topMargin + yOffset);

  180. break;

  181. case LEFT_BOTTOM:

  182. animation = new TranslateAnimation(-mlp.leftMargin+xOffset,0F, -yOffset + mlp.bottomMargin,0F);

  183. break;

  184. case RIGHT_BOTTOM:

  185. animation = new TranslateAnimation(0F,mlp.rightMargin-xOffset, 0F,-yOffset + mlp.bottomMargin);

  186. break;

  187. default:

  188. break;

  189. }

  190. animation.setFillAfter(true);animation.setDuration(duration);

  191. animation.setStartOffset(((group.getChildCount()-i) * 100)

  192. / (-1 + group.getChildCount()));

  193. animation.setInterpolator(new AnticipateInterpolator(2F));

  194. imageview.startAnimation(animation);

  195. }

  196. }

  197. }

第四步:PathTestActivity.java以及用到的布局文件main.xml代码如下:

PathTestActivity.java(基本没修改代码)代码如下:

[java]  view plain copy

  1. package com.tutor.path;

  2. import android.app.Activity;

  3. import android.os.Bundle;

  4. public class PathTestActivity extends Activity {

  5. @Override

  6. public void onCreate(Bundle savedInstanceState) {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

上面分享的腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。

【Android思维脑图(技能树)】

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

【Android高级架构视频学习资源】

**Android部分精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

21年的高频面试题**,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。

【Android思维脑图(技能树)】

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

[外链图片转存中…(img-MLuQVFPj-1712134886774)]

【Android高级架构视频学习资源】

**Android部分精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
  • 23
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值