而滑动结束的回调是说.doc_第1页
而滑动结束的回调是说.doc_第2页
而滑动结束的回调是说.doc_第3页
而滑动结束的回调是说.doc_第4页
而滑动结束的回调是说.doc_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

而滑动结束的回调是说,当滑动结束后,滑动到中央的item view会触发一次回调,用户可以利用该回调来进行别的逻辑处理,与别的控件进行交互,比如:某个item view滑动到中央,触发回调,让别的TextView或者ImageView来具体显示该item项的具体信息。用法 只要在Activity中写上如下几行代码即可:SemicircleMenu mSemicircleMenu = (SemicircleMenu) findViewById(R.id.circlemenu); mSemicircleMenu.setMenuItemIconsAndTexts(mItemImgs, mItemTexts); mSemicircleMenu.setOnMenuItemClickListener(new SemicircleMenu.OnMenuItemClickListener() Override public void itemClick(View view, int pos) Toast.makeText(MainActivity.this, mItemTextspos, Toast.LENGTH_SHORT).show(); ); mSemicircleMenu.setOnCentralItemCallback(new SemicircleMenu.OnCentralItemCallback() Override public void centralItemOperate(int pos) imageView.setImageResource(mItemImgspos); ); 布局文件:(注意:clickable应该为true。)实现原理 其实关于测量、布局、甚至事件分发的实现原理在原文章都有很详细的说明了,有兴趣的读者可以先阅读原文,这里会作简要的说明,本文重点在于讲述位置修正即滑动结束回调的实现,本文所有代码均作了删减,读者可直接到GitHub处阅读源码。Part 1 设置itemView的内容及加载itemView /* * 每个Item之间相距的角度 */ private float mAngleDelay; /* * 设置菜单的文本信息 */ public void setMenuItemIconsAndTexts(int resIds,String texts) mItemIcons = resIds; mItemTexts = texts; if(resIds = null & texts = null) throw new IllegalArgumentException(菜单文本和图片必须设置其一); /初始化mMenuItemCount mMenuItemCount = resIds = null ? texts.length : resIds.length; if(resIds != null & texts != null) mMenuItemCount = Math.min(resIds.length,texts.length); /计算每个Item之间相差的度数,该值直接影响后面的布局、滑动 mAngleDelay = 360 / mMenuItemCount; addMenuItems(); private void addMenuItems() LayoutInflater mInflater = LayoutInflater.from(getContext(); /* * 初始化item view */ for(int i = 0; i mMenuItemCount; i+) final int j = i; View view = mInflater.inflate(R.layout.circle_menu_item,this,false); view.setTag(i); /为每个item view打上Tag ImageView iv = (ImageView) view.findViewById(R.id.id_circle_menu_item_image); TextView tv = (TextView) view.findViewById(R.id.id_circle_menu_item_text); /. addView(view); 从以上代码来看,暴露了setMenuItemIconsAndTexts方法,用户可以通过该方法为该控件设置不同的Item的图像及其文本信息。接着根据设置item的数量,来计算每个item之间应相隔多少度,即mAngleDelay值,例如,如果是6个Item,那么mAngleDelay值就是60度,以此类推。接着,在addMenuItem方法内,是不断加载Item View,并且添加至当前ViewGroup内。(注意:形如R.id.id_circle_menu_item_image的id是定义在values文件夹下的id文件内的)。Part 2 测量和布局 Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) /. /我们只需要半圆区域,因此把高度限制为一半 setMeasuredDimension(resWidth,resHeight /2); mRadius = Math.max(getMeasuredWidth(),getMeasuredHeight(); final int count = getChildCount(); int childSize = (int) (mRadius * DEFAULT_CHILD_DIMENSION); int childMode = MeasureSpec.EXACTLY; /遍历所有子View,对其进行测量 for(int i = 0; i = mFlingableValue & !isFling) mAutoFlingAngle = mTmpAngle; post(mFlingRunnable = new AutoFlingRunnable(anglePerSecond); return true; else if(Math.abs(anglePerSecond) NOCLICK_VALUE) return true; break; return super.dispatchTouchEvent(ev); 大体思路是这样的,当检测到ACTION_DOWN事件时,记录当前的触摸坐标,接着在ACTION_MOVE事件中,不断获取实时的触摸坐标,并计算角度,通过新的角度来累加到mStartAngle中,接着调用requestLayout()方法来重新布局大体思路是这样的,当检测到ACTION_DOWN事件时,记录当前的触摸坐标,接着在ACTION_MOVE事件中,不断获取实时的触摸坐标,并计算角度,通过新的角度来累加到mStartAngle中,接着调用requestLayout()方法来重新布局,这样便实现了该菜单跟随手指而转动的效果,这是最基础的。但如果是快速滑动呢?那么我们在ACTION_UP事件中,通过判断滑动的距离与从触摸到松开手指的时间的比值来判断是否是快速滑动。如果是快速滑动,那么启动一个Runnable来完成快速滚动的事件,其实这也很简单,在Runnable中不断调用requestLayout()就可以实现快速滚动的效果了,这些在原文章都有详细说明。Part 4 位置自动修正 但是,由于随手指滑动,或者快速滑动完毕后,其最后的滑动角度一般是一个随机的数值,这样就会造成item view出现在不应该出现的位置,比如正中央恰好没有item view出现,都出现了一定的偏移,这样对于菜单来说是非常不理想的,所以我们需要进行位置的矫正,使得每一个的滑动完成后,其Item View都能在正确的位置出现,而解决这个问题,我们可以从以下思路来解决:首先把总的滚动角度先算出来,那么这个总的滚动角度便直接决定了滚动完毕后各item的位置,既然我们不能影响其滚动过程,那么我们可以在滚动结束后,通过对总滚动角度进行一系列的判断来对最后的位置进行调整,并再一次requestLayout,使得位置得以矫正。 那么这个总的滚动角度是怎样与位置矫正联系起来的呢?在代码里面,总滚动角度用mTmpAngle或者mAutoFlingAngle来记录,我们可以先用它对mAngleDelay(该值上面提及,表示每个Item之间相隔的角度)求余,这样得出的结果是任一item的偏移量。举个例子:item view有6个,那么每个Item相隔60,我们转动了80,那么我们可以这样分解:先转了60,此时每个Item的位置一定是正确的,再转20,那么此时item就会留在不正确的位置了,我们所要做的就是对这个“20”进行处理,那么以30为分割线,没到30的,让itemview往回转到正确的位置;如果超过了30的,让Itemview转动到下一个位置,那么我们的问题便得以解决了。 下面的方法是计算还需要多少角度才能转到正确的位置的:/* * 获取位置矫正所需的角度 * param angle 对mAngleDelay求余后的角度 * return */ private float getCorrectAngle(float angle) if(angle 0 & angle mAngleDelay/2) mCorrectPositionFlag = true; return (mAngleDelay -angle); else if(angle 0 & Math.abs(angle) = mAngleDelay/2) mCorrectPositionFlag = true; return -angle; else if(angle mAngleDelay/2) mCorrectPositionFlag = true; return -(mAngleDelay -Math.abs(angle); return 0; 在获取到需要修正的角度后,我们可以直接通过Runnable来重新布局一下,把该值作为需要转动的角度即可。 如下所示:private class AutoFlingRunnable implements Runnable /. public void run() if(mCorrectPositionFlag) float angle = angelPerSecond; mStartAngle += angle; requestLayout(); mCorrectPositionFlag = false; else / 如果小于20,则停止,同时进行位置矫正 if (int) Math.abs(angelPerSecond) = 0; i-) final View child = getChildAt(i); if(x = child.getLeft() & x = child.getTop() & y = child.getBottom() return child; return null; 自定义控件:实现半圆滚动菜单效果(3)实现原理很简单,就是遍历所有的item View,来判断给定的x、y坐标在哪个Item View之内,提取到item View的实例后,我们再拿出该itemView的Tag(因为加载itemView的时候,给每个View都打上了不同的Tag),有了Tag,就实现原理很简单,就是遍历所有的item View,来判断给定的x、y坐标在哪个Item View之内,提取到item View的实例后,我们再拿出该itemView的Tag(因为加载itemView的时候,给每个View都打上了不同的Tag),有了Tag,就知道了是哪一个itemView滑动到了最中央的位置,最后再利用回调的实现方法,来实现交互式操作。 上面提到,在onLayout方法的最后有如下语句:/布局结束的时

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论