PathButtonView 控件
来源:互联网 发布:淘宝账号简介怎么写 编辑:程序博客网 时间:2024/06/06 12:59
参考:鸿洋 ArcMenu 点此跳转
参考了鸿洋的动态添加按钮,在基础上增加了左右上下中间的按钮。
纯属练手。
效果图:
使用自定义属性,对外提供参数设置方法,点击监听。
动态添加按钮个数
private void init() { LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); for (int i = 0; i < count; i++) { ImageView view = new ImageView(getContext()); view.setScaleType(ScaleType.CENTER_INSIDE); view.setImageResource(res[i]); view.setBackgroundResource(R.drawable.bg_pathsons); view.setVisibility(View.GONE); view.setTag(i); addView(view, params); } LayoutInflater.from(getContext()).inflate(R.layout.listformat_pathbutton, this); home = (ImageView) findViewById(R.id.home); homeStart = ObjectAnimator.ofFloat(home, "rotation", 0f, 135f).setDuration(300); homeEnd = ObjectAnimator.ofFloat(home, "rotation", 135f, 0f).setDuration(300); home.setOnClickListener(this); }
核心部分,主按钮放置,卫星按钮摆放。
// 确定位置 @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if (changed) { cheakHomeLayout(); Log.d("Radius", "Radius= " + radius); if (mPosition == Position.LEFT_CENTER || mPosition == Position.RIGHT_CENTER || mPosition == Position.TOP_CENTER || mPosition == Position.BOTTOM_CENTER) { double angle = 0; if (mPosition == Position.TOP_CENTER || mPosition == Position.BOTTOM_CENTER) { angle = Math.PI / 2; } for (int i = 1; i < count + 1; i++) { View view = getChildAt(i - 1); int ml = (int) (Math.sin(Math.PI / (count + 1) * i + angle) * radius); int mt = (int) (Math.cos(Math.PI / (count + 1) * i + angle) * radius); int mWidth = view.getMeasuredWidth(); int mHeight = view.getMeasuredHeight(); if (mPosition == Position.LEFT_CENTER) { mt = getMeasuredHeight() / 2 - mHeight / 2 - mt; } else if (mPosition == Position.RIGHT_CENTER) { mt = getMeasuredHeight() / 2 - mHeight / 2 - mt; ml = getMeasuredWidth() - mWidth - ml; } else if (mPosition == Position.TOP_CENTER) { ml = getMeasuredWidth() / 2 - mWidth / 2 - ml; mt = -mt; } else if (mPosition == Position.BOTTOM_CENTER) { ml = getMeasuredWidth() / 2 - mWidth / 2 - ml; mt = getMeasuredHeight() - mHeight + mt; } Log.d("child", "Left= " + ml + "Top= " + mt); view.layout(ml, mt, ml + mWidth, mt + mHeight); } } else { for (int i = 0; i < count; i++) { View view = getChildAt(i); int mt = (int) (Math.sin(Math.PI / 2 / (count - 1) * i) * radius); int ml = (int) (Math.cos(Math.PI / 2 / (count - 1) * i) * radius); int mWidth = view.getMeasuredWidth(); int mHeight = view.getMeasuredHeight(); if (mPosition == Position.LEFT_BOTTOM || mPosition == Position.RIGHT_BOTTOM) { mt = getMeasuredHeight() - mHeight - mt; } if (mPosition == Position.RIGHT_TOP || mPosition == Position.RIGHT_BOTTOM) { ml = getMeasuredWidth() - mWidth - ml; } Log.d("child", "Left= " + ml + "Top= " + mt); view.layout(ml, mt, ml + mWidth, mt + mHeight); } } } } private int homeX = 0, homeY = 0;//主键坐标位置 private void cheakHomeLayout() { View v = getChildAt(getChildCount() - 1); v.setOnClickListener(this); int t = 0; int l = 0; int width = v.getMeasuredWidth(); int height = v.getMeasuredHeight(); switch (mPosition) { case LEFT_TOP: t = 0; l = 0; break; case LEFT_CENTER: t = getMeasuredHeight() / 2 - height / 2; l = 0; break; case LEFT_BOTTOM: t = getMeasuredHeight() - height; l = 0; break; case RIGHT_TOP: t = 0; l = getMeasuredWidth() - width; break; case RIGHT_CENTER: t = getMeasuredHeight() / 2 - height / 2; l = getMeasuredWidth() - width; break; case RIGHT_BOTTOM: t = getMeasuredHeight() - height; l = getMeasuredWidth() - width; break; case TOP_CENTER: t = 0; l = getMeasuredWidth() / 2 - width / 2; break; case BOTTOM_CENTER: t = getMeasuredHeight() - height; l = getMeasuredWidth() / 2 - width / 2; break; } Log.d("Home", "Left= " + l + "Top= " + t); homeX = l + width / 2; homeY = t + height+height/2; v.layout(l, t, l + width, t + height); }
点击事件,主键点击展开/收缩
@Override public void onClick(View v) { if (v.getId() == R.id.home) { homeAnim();//主键动画 toggleMenu(druation);//卫星按钮动画 changeState();//展开/收缩状态改变 } } private void homeAnim() { if (isOpened) //收缩动画 homeEnd.start(); else //展开动画 homeStart.start(); } private void toggleMenu(int druation) { int childCount = getChildCount(); double angle = 0; if (mPosition == Position.TOP_CENTER || mPosition == Position.BOTTOM_CENTER) { angle = Math.PI / 2; } for (int i = 0; i < childCount - 1; i++) { final View v = getChildAt(i); int ct = 0, cl = 0; int[] location = new int[2]; v.getLocationOnScreen(location); //获取卫星按钮与主按键位置的差值 cl = homeX - location[0] - v.getWidth() / 2; ct = homeY - location[1] - v.getHeight() / 2; v.setVisibility(View.VISIBLE); AnimationSet animSet = new AnimationSet(true); TranslateAnimation transAnim = null; AlphaAnimation alphaAnim = null; RotateAnimation rotateAnim = null; if (isOpened) { // 关闭 transAnim = new TranslateAnimation(0, cl, 0,ct); alphaAnim = new AlphaAnimation(1, 0); rotateAnim = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF,0.5f); v.setClickable(false); v.setFocusable(false); } else { // 打开 transAnim = new TranslateAnimation( cl, 0,ct, 0); alphaAnim = new AlphaAnimation(0, 1); rotateAnim = new RotateAnimation(-360, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f); v.setClickable(true); v.setFocusable(true); } transAnim.setStartOffset((i * 70)); animSet.addAnimation(rotateAnim); animSet.addAnimation(transAnim); animSet.addAnimation(alphaAnim); animSet.setDuration(druation); animSet.setFillAfter(true); final int index = i; //卫星按钮点击接口s v.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mOnMenuItemClickListener != null) mOnMenuItemClickListener.onClick(v, index); menuItemAnim(index);//点击后卫星按钮状态改变动画 homeAnim(); changeState(); Log.d("item", "第 "+ index +"按钮"); } }); animSet.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animation animation) { if (!isOpened) v.setVisibility(View.GONE); } }); v.startAnimation(animSet); } } //卫星按钮点击状态改变动画 private void menuItemAnim(int index) { for (int i = 0; i < getChildCount() - 1; i++) { View v = getChildAt(i); if (i == index) { v.startAnimation(scaleBigItem(400)); } else { v.startAnimation(scaleSmallItem(400)); } v.setClickable(false); v.setFocusable(false); } } //缩小 private Animation scaleSmallItem(int duration) { ScaleAnimation anim = new ScaleAnimation(1f, 0, 1f, 0, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f); anim.setDuration(duration); anim.setFillAfter(true); return anim; } //放大 private Animation scaleBigItem(int duration) { AnimationSet setAnim = new AnimationSet(true); ScaleAnimation anim = new ScaleAnimation(1f, 1.5f, 1f, 1.5f, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f); AlphaAnimation alphaAnim = new AlphaAnimation(1f, 0); setAnim.addAnimation(anim); setAnim.addAnimation(alphaAnim); setAnim.setDuration(duration); setAnim.setFillAfter(true); return setAnim; }
改变按钮状态 展开/收缩
对外提供状态查询
private void changeState() { isOpened = !isOpened; } public boolean isOpened() { return isOpened; }
卫星按钮点击接口
private OnMenuItemClickListener mOnMenuItemClickListener; public void setOnMenuItemClickListener(OnMenuItemClickListener mOnMenuItemClickListener) { this.mOnMenuItemClickListener = mOnMenuItemClickListener; } public interface OnMenuItemClickListener { void onClick(View view, int index); }
属性设置
private int count = 5;//默认卫星按钮个数 private int radius = 100;//默认半径 private Position mPosition = Position.RIGHT_BOTTOM; //默认卫星按钮图片资源 防止设置资源时脚标越界 private int[] res = new int[30] { R.drawable.home, R.drawable.download, R.drawable.setting, R.drawable.light,R.drawable.location }; //设置卫星按钮个数 public void setChildCount(int count) { this.count = count; } //设置半径 public void setRadius(int radius) { this.radius = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, radius*1f, getResources().getDisplayMetrics()); } //设置按钮位置 public void setPosition(Position mPosition) { this.mPosition = mPosition; } //设置卫星按钮图片资源 public void setRes(int[] res) { for (int i = 0; i < res.length; i++) { this.res[i] = res[i]; } } //位置 public enum Position { LEFT_TOP, LEFT_CENTER, LEFT_BOTTOM, RIGHT_TOP, RIGHT_CENTER,RIGHT_BOTTOM, TOP_CENTER, BOTTOM_CENTER; } //动画持续时间 private int = 600; public void setDruation(int druation) { this.druation = druation; }
Demo戳我下载
0 0
- PathButtonView 控件
- 控件
- 控件
- 控件
- 控件
- 控件
- 控件
- 控件
- 控件
- 控件
- 控件
- 控件
- 控件
- *****控件****
- 控件
- 控件
- 控件
- 控件
- 三种改进型排序算法-快速排序,堆排序,希尔排序
- 回调
- 函数指针的使用
- 数据结构与算法——插入排序以及C++函数模板实现
- 剑指offer-替换空格
- PathButtonView 控件
- VC++上位机编程学习总结2-属性页对话框
- STL 乱玩
- [ApiDemos] Activity CustomDialog
- 关于面向对象设计、uml、领域建模
- UIWebView 的知识总结
- 常见面试之机器学习算法思想简单梳理
- ArrayList API 学习小笔记
- Nodejs webSocket test