android一个转盘效果的容器viewgroup
来源:互联网 发布:js iso时间格式 编辑:程序博客网 时间:2024/05/17 02:03
最近看到建设银行的主页面里面有一个带旋转效果的,心血来潮,正好公司最近活比较少,就花时间自己写了一个先上一下效果图
* 转盘viewgroup,将会已转盘的形式排列所有子view,view之间间距一样,所以不要添加过多的view
* 支持长按删除
* 支持复位播放音效
图有点大,也不知道如何缩小,大家凑合看看
代码其实也比较简单,我就贴出来比较重要的代码让大家看看
首先当然是手势的处理,我是把一个圆圈用一个“X”型,给他分成四部分
private int checkArea(float x, float y){int locationInWindow[] = new int[2];getLocationInWindow(locationInWindow);int parentX = locationInWindow[0] + getWidth()/2;int parentY = locationInWindow[1] + getHeight()/2;double distance = Math.sqrt((parentX - x)*(parentX - x) + (parentY - y)*(parentY - y));//两个点之间的距离double disY = Math.abs(y - parentY);double radian = Math.asin(disY/distance);double angle = (radian / Math.PI) * 180;if(y <= parentY && x <= parentX){// 1,4象限if(angle < 45)return 4;elsereturn 1;}else if(y <= parentY && x >= parentX){ //1,2象限if(angle <=90 && angle >=45)return 1;elsereturn 2;}else if(y >= parentY && x >= parentX){//2,3象限if(angle <= 45)return 2;elsereturn 3;}else{// 3,4象限if(angle < 45)return 4;elsereturn 3;}}不同的象限所处理的手势也不一样,为了简单方便,1.3象限只处理x轴的滑动,2,4象限只处理y轴的滑动
case MotionEvent.ACTION_MOVE:area = checkArea(event.getRawX(), event.getRawY());float moveY = event.getRawY() - lastY;float moveX = event.getRawX() - lastX;switch (area) {case 1:turnClockwise(moveX);speed = moveX;break;case 2:turnClockwise(moveY);speed = moveY;break;case 3:turnClockwise(-moveX);speed = -moveX;break;case 4:turnClockwise(-moveY);speed = -moveY;break;}lastX = event.getRawX();lastY = event.getRawY();break;旋转函数
private void turnClockwise(float move){float angle = move / 5;for(int i=0 ; i<location.size() ; i++){location.get(i).setNumber((location.get(i).getNumber() + angle)%360);if(location.get(i).getNumber() >= -10 && location.get(i).getNumber() <= 10 ){//需要一个范围if(location.get(i).isFlag()){sound.onPlaySound();location.get(i).setFlag(false); //用于表示该图标已经播放完声音}}else{location.get(i).setFlag(true);}}requestLayout();//重新计算每个子view的位置//invalidate();}
还有遇到最大的问题就是touchevent的冲突,由于父控件处理了所有的touchevent,所以子控件没收到touchevent,于是就用了SimpleOnGestureListener来处理,再onTouchEvent函数里面将每一个touchevent都传到SimpleOnGestureListener里面,接着重写onSingleTapUp函数来处理单击事件即可,虽然这样也能够处理了,但是感觉效果还是不太好,如果来处理子空间的滑动动作呢?
private class MyGestureDetectorListener extends SimpleOnGestureListener{/** * down事件 */@Overridepublic boolean onDown(MotionEvent arg0) {return false;}/** * 滑动手势事件;Touch了滑动一点距离后,在ACTION_UP时才会触发 参数:e1 第1个ACTION_DOWN MotionEvent 并且只有一个;e2 最后一个ACTION_MOVE MotionEvent ;velocityX X轴上的移动速度,像素/秒 ;velocityY Y轴上的移动速度,像素/秒.触发条件:X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒 */@Overridepublic boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,float arg3) {return false;}/** * 长按事件;Touch了不移动一直Touch down时触发 */@Overridepublic void onLongPress(MotionEvent arg0) {viewIsBeingLongClick = getChildAt(checkClickChild(arg0.getX(), arg0.getY()));//initPopUpMenu(); ---1//showContextMenuForChild(viewIsBeingLongClick); ---2//menu.show();initPopUpWindow();window.showAsDropDown(viewIsBeingLongClick);}/** * 拖动事件。无论是用手拖动view,或者是以抛的动作滚动,都会多次触发,这个方法在ACTION_MOVE动作发生时就会触发 抛:手指触动屏幕后,稍微滑动后立即松开onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling 拖动onDown------》onScroll----》onScroll------》onFiling */@Overridepublic boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,float arg3) {return false;}/** * down事件发生而move或则up还没发生前触发该 事件;Touch了还没有滑动时触发(与onDown,onLongPress)比较onDown只要Touch down一定立刻触发。而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。所以Touchdown后一直不滑动按照onDown->onShowPress->onLongPress这个顺序触发。 */@Overridepublic void onShowPress(MotionEvent arg0) {}/** * 一次点击up事件;在touch down后又没有滑动(onScroll),又没有长按(onLongPress),然后Touchup时触发。 点击一下非常快的(不滑动)Touchup:onDown->onSingleTapUp->onSingleTapConfirmed 点击一下稍微慢点的(不滑动)Touchup:onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed */@Overridepublic boolean onSingleTapUp(MotionEvent arg0) {if(listener != null){int i = checkClickChild(arg0.getX(), arg0.getY());if( i != -1)listener.onClick((String) getChildAt(i).getTag());}return false;}}点我下载
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
最近又重写了一下,发现oninterceptouchevent函数直接返回true这种做法非常不合理,甚至说是错误的,因为这样一定会造成子控件接收不到touchevent,所以参照scrollview的解决方法又重写了一份,第一份就不删了,可以参考作为错误的方法
第二版本源码点我下载
1 0
- android一个转盘效果的容器viewgroup
- Android实现转盘效果
- android实现大转盘效果
- 利用Android自定义View实现转盘旋转的效果
- Android自定义View实现转盘旋转的效果
- Android 使用ViewGroup实现ViewPager的效果
- android的转盘
- Android中ViewGroup等容器控件的使用
- Android中ViewGroup等容器控件的使用
- Android中ViewGroup等容器控件的使用
- Android中ViewGroup等容器控件的使用
- Android自定义ViewGroup(四、打造自己的布局容器)
- Android记录9--实现转盘效果
- Android转盘按钮效果巧妙实现
- 自定义ViewGroup容器,实现自动换行的流式布局的效果
- android-使用ViewGroup实现左右滑动切换界面的效果
- Android动画效果,涉及View和VIewGroup的区别
- Android转盘菜单的实现
- Java探索之旅(12)——equals方法及其覆盖
- 怎样刷新memcached
- strtok函数和strtok_r函数
- WebCollector内核解析—如何设计一个爬虫
- eclipse 出现启动错误.....
- android一个转盘效果的容器viewgroup
- ecshop 中libs.xml作用
- 使用Apache FtpServer搭建FTP服务器(续)
- app会被拒绝的原因
- 11g RAC 修改PUBLIC-IP、VIP、PRIV-IP、SCAN-IP
- java学习好,看看的那个人
- Unity Windows选择图片并加载
- sql server DEFAULT约束的增加与删除
- 类型别名+auto类型说明符+decltype类型说明符