模拟Launcher中SliderView的滑动操作以及可随意拖动图片的实现
2012-10-15 11:16
459 查看
上一篇文章中我们了解了一下ADW_Launcher的托盘中SliderView的滑动,我们详细分析了SliderView滑动的过程。文章地址:ADW_Launcher的托盘
——SliderView研究。今天,我们就来模拟一下ADW_Launcher中SliderView的实现以及可随意拖动图片的实现(这里我们给出两种方式)。相信如果看过上一篇文章,制作这个效果是很简单的。不多说了,直接贴出效果图:
先说一下文件的目录结构。总共涉及到四个类。MainActivity完成跳转,负责跳转到MyViewActivity。在MainActivity的点击事件中给相应的intent设置extra,值为需要给MyViewActivity设置的布局文件。在MyViewActivity使用LayoutInflater来填充这个布局文件,然后生成对应的view展示出来即可。MySliderView继承自ImageView,该类重写了onTouchEvent方法,对MySliderView的滑动事件做了处理。MyDragView也继承自ImageView,同样重写onTouchEvent方法,实现图片水平滑动,竖直滑动以及随意滑动。sliding_target_bottom.xml是一个动画文件,表示MySliderView下方滚动的箭头。tray_collapse.xml和tray.xml是图片选择器,对应的图片为格子和主页。drag.xml表示的是
可随意拖动的图片 部分的布局,里面放了一个MyDragView;slider.xml表示的是滑动托盘的布局,里面放了一个MySliderView。文件目录结构的截图如下:
一:模拟一下ADW_Launcher中SliderView的实现
下面就对MySliderView.java类做一个简单的说明。更详细的分析请看我的这边文章:ADW_Launcher的托盘 ——SliderView研究。里面有对SliderView代码的详细分析。
1、moveHandle()方法 我们只对竖直方向的滑动做处理。
2、dispatchTriggerEvent()方法。我们知道,在ADW_Launcher中,当用户滑动到SliderView到一定位置的时候,程序将执行该方法。这里,我们只是模拟,此处我们的操作是隐藏当前的控件并且给用户一个提示即可。
3、dispatchClickedEvent()方法。在ADW_Launcher中,用户点击SliderView将执行该方法,我们通过下面的代码来模拟。更换SliderView的图片,并且设置显示的文本信息。文本信息对应的TextView的控件的定义在createTargets()方法中。我们知道这个方法的作用是第一次点击SliderView的时候创建滑动的箭头。
createTargets()方法如下:它将创建往下滑动的箭头,这点是与ADW_Launcher中不同的地方,具体的代码请看DEMO中源代码。
dispatchClickedEvent()方法如下:
二:可随意拖动图片的实现
这个效果涉及到的类为 MyDragView.java。我们在它的onTouchEvent中设置ACTION_MOVE的事件处理。onTouchEvent()方法如下:
1、moveHandler()方法是用第一种滑动方式:记录控件开始的位置,没滑动一次都会产生一个偏移,使用原始位置的mLeft(距离父控件左边的距离),mTop,mRight,mBottom 加上各个方向上的偏移量得到新的mLeft,mTop,mRight,mBottom 值,然后调用view的layout方法,使用这四个值去绘制view。
3、moveHandler3()方法只处理水平方向的滑动:它的原理是,不管竖直方向有没有产生偏移,始终使用原始位置的mTop和mBottom值绘制view。这样出来的效果就竖直方向无法移动了。
4、moveHandler4()方法只处理竖直方向的滑动:它的原理是,不管水平方向有没有产生偏移,始终使用原始位置的mLeft和mRight值绘制view。这样出来的效果就是水平方法无法移动了。
至此,我们就成功模拟了ADW_Launcher的托盘中SliderView的滑动并且是实现了可随意滑动的图片的效果。本来这部分内容应该是放在这篇文章(ADW_Launcher的托盘
——SliderView研究)中的,但是由于上篇文章内容过长,因此就单独移出来。好了,这部分内容就说到这里,有不懂的地方可以回帖一起讨论,不足的地方请指正,一同进步,谢谢。
DEMO下载地址:
http://download.csdn.net/detail/yanbin1079415046/4647851
——SliderView研究。今天,我们就来模拟一下ADW_Launcher中SliderView的实现以及可随意拖动图片的实现(这里我们给出两种方式)。相信如果看过上一篇文章,制作这个效果是很简单的。不多说了,直接贴出效果图:
先说一下文件的目录结构。总共涉及到四个类。MainActivity完成跳转,负责跳转到MyViewActivity。在MainActivity的点击事件中给相应的intent设置extra,值为需要给MyViewActivity设置的布局文件。在MyViewActivity使用LayoutInflater来填充这个布局文件,然后生成对应的view展示出来即可。MySliderView继承自ImageView,该类重写了onTouchEvent方法,对MySliderView的滑动事件做了处理。MyDragView也继承自ImageView,同样重写onTouchEvent方法,实现图片水平滑动,竖直滑动以及随意滑动。sliding_target_bottom.xml是一个动画文件,表示MySliderView下方滚动的箭头。tray_collapse.xml和tray.xml是图片选择器,对应的图片为格子和主页。drag.xml表示的是
可随意拖动的图片 部分的布局,里面放了一个MyDragView;slider.xml表示的是滑动托盘的布局,里面放了一个MySliderView。文件目录结构的截图如下:
一:模拟一下ADW_Launcher中SliderView的实现
下面就对MySliderView.java类做一个简单的说明。更详细的分析请看我的这边文章:ADW_Launcher的托盘 ——SliderView研究。里面有对SliderView代码的详细分析。
1、moveHandle()方法 我们只对竖直方向的滑动做处理。
/** * 处理移动 * @param x 左右滑动事件我们忽略 * @param y * offsetTopAndBottom()是很关键的代码,作用是将当前view的mTop和mBottom的值重新设置,当调用 * v.invalidate(rect);这句代码时将使用这个mTop和mBottom去重绘view(通过getTop()和getBottom()可以得到这两个值) */ private void moveHandle(float x, float y) { int deltaY=0; boolean moved=false; //如果触电的位置大于 托盘图片高度的一半时就可以滑动了(可以再模拟器上,将鼠标置于托盘的最顶端进行测试【要拖动一定的距离才可以滑动】) deltaY = (int) y- (getHeight() / 2); if((deltaY<0 && getTop()>mLimitRect.top) || (deltaY>0 && getBottom()<mLimitRect.bottom)){ //每次滑动之后,y值在变,每变一次就产生一个新的mTop和mBottom,然后再invalidate,也就实现了滑动的效果。 offsetTopAndBottom(deltaY); moved=true; } if(moved){ Rect rect=new Rect(getLeft() , getTop()-deltaY, getRight(), getBottom()-deltaY); ViewGroup v=(ViewGroup)getParent(); v.invalidate(rect); } }
2、dispatchTriggerEvent()方法。我们知道,在ADW_Launcher中,当用户滑动到SliderView到一定位置的时候,程序将执行该方法。这里,我们只是模拟,此处我们的操作是隐藏当前的控件并且给用户一个提示即可。
/** * 模拟进入MiniLauncher,我们这里仅仅是托盘消失 */ private void dispatchTriggerEvent(int whichHandle) { performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); this.setVisibility(View.GONE); if(tv != null){ tv.setText("进入到了MiniLauncher"); } Toast.makeText(mContext, "托盘消失,进入MiniLauncher方式", 0).show(); }
3、dispatchClickedEvent()方法。在ADW_Launcher中,用户点击SliderView将执行该方法,我们通过下面的代码来模拟。更换SliderView的图片,并且设置显示的文本信息。文本信息对应的TextView的控件的定义在createTargets()方法中。我们知道这个方法的作用是第一次点击SliderView的时候创建滑动的箭头。
createTargets()方法如下:它将创建往下滑动的箭头,这点是与ADW_Launcher中不同的地方,具体的代码请看DEMO中源代码。
private void createTargets(){ mTargets=new ArrayList<ImageView>(); LinearLayout p=(LinearLayout)getParent(); LinearLayout.LayoutParams lp=(LinearLayout.LayoutParams)getLayoutParams(); final int horizontalGravity = Gravity.CENTER_HORIZONTAL; Starter starter=new Starter();//创建动画 //我们只做往下的滑动箭头 if(mSlideDirections == DIRECTIONS){ ImageView v2 =new ImageView(getContext()); if(v2.getBackground()==null){ v2.setBackgroundResource(R.drawable.sliding_target_bottom); } AnimationDrawable frameAnimation = (AnimationDrawable) v2.getBackground(); starter.addAnimation(frameAnimation); v2.setTag(DIRECTIONS); //mTargets表示 动画箭头的区域 mTargets.add(v2); lp=new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); lp.gravity=horizontalGravity; lp.topMargin=getBottom()+mTargetDistance; p.addView(v2, lp); //托盘到箭头滑动动画的距离 frameAnimation.getIntrinsicHeight()得到的是动画的高度 mLimitRect.bottom=getBottom()+mTargetDistance * 3+frameAnimation.getIntrinsicHeight()+securityMargin; //增加一个TextView tv = new TextView(getContext()); tv.setText("现在处于桌面"); tv.setTextSize(25); lp=new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); lp.gravity = horizontalGravity; lp.topMargin = 50; p.addView(tv,lp); } //将动画加入到消息队列 post(starter); }
dispatchClickedEvent()方法如下:
/** * 模拟点击,用户执行的是点击或者拖动托盘位置未达到进入MiniLauncher。 */ private void dispatchClickedEvent() { if(isTray){ this.setBackgroundResource(R.drawable.tray_collapse); if(tv != null){ tv.setText("现在处于应用程序列表页面"); } isTray = false; }else{ this.setBackgroundResource(R.drawable.tray); if(tv != null){ tv.setText("现在处于桌面"); } isTray = true; } }
二:可随意拖动图片的实现
这个效果涉及到的类为 MyDragView.java。我们在它的onTouchEvent中设置ACTION_MOVE的事件处理。onTouchEvent()方法如下:
@Override public boolean onTouchEvent(MotionEvent event) { int flag = event.getAction(); int currentX = (int) event.getX(); int currentY = (int) event.getY(); System.out.println("currentX==" + currentX + ",currentY==" + currentY); switch (flag) { case MotionEvent.ACTION_DOWN: preX = currentX; preY = currentY; break; case MotionEvent.ACTION_MOVE: moveHandler(currentX,currentY);//第一种方式 // moveHandler2(currentX,currentY);//第二种方式 // moveHandler3(currentX,currentY);//水平滑动 // moveHandler4(currentX,currentY);//竖直滑动 break; case MotionEvent.ACTION_CANCEL: break; case MotionEvent.ACTION_UP: break; } return true; }
1、moveHandler()方法是用第一种滑动方式:记录控件开始的位置,没滑动一次都会产生一个偏移,使用原始位置的mLeft(距离父控件左边的距离),mTop,mRight,mBottom 加上各个方向上的偏移量得到新的mLeft,mTop,mRight,mBottom 值,然后调用view的layout方法,使用这四个值去绘制view。
/** * 第一种移动方式 重新layout * @param x * @param y */ private void moveHandler(int x,int y){ int gapX = x - preX; int gapY = y - preY; int left = getLeft() + gapX; int top = getTop() + gapY; int right = getRight() + gapX; int bottom = getBottom() + gapY; if(left < 0){ left = 0; right = getWidth(); } if(top < 0){ top = 0; bottom = getHeight(); } if(right > w){ left = w - getWidth(); right = w; } if(bottom > h){ top = h - getHeight(); bottom = top + getHeight(); } this.layout(left, top, right, bottom); }2、moveHandler2()方法是第二种滑动方式:每次滑动产生偏移后,将各个方向的偏移通过offsetLeftAndRight()和offsetTopAndBottom()方法重新设置mLeft,mTop,mRight,mBottom 的值。然后得到父控件,让父控件调用invalidate()方法去重绘我们的子控件。
/** * 第二种移动方式 让父控件重绘需要重绘的部分 * @param x * @param y */ private void moveHandler2(int x,int y){ System.out.println("y==" + y + ",preY==" + preY + ",h==" + getHeight()); int gapX = x - preX; int gapY = y - preY; int left = getLeft() + gapX; int top = getTop() + gapY; int right = getRight() + gapX; int bottom = getBottom() + gapY; if(left < 0 || right > w){ gapX = 0; } offsetLeftAndRight(gapX); if(top < 0 || bottom > h){ gapY = 0; } offsetTopAndBottom(gapY); // Rect实际上只是保证了一个固定大小的矩形区域而已。offsetLeftAndRight()代码会去改变 //button的mLeft,mTop,mRight,mBottom等值.从而实现button的重绘。 Rect rect=new Rect(getLeft()-gapX , getTop()-gapY, getRight()-gapX, getBottom()-gapY); //如果你要调用invalidate方法,需要调用父控件的invalidate方法。如果你仅仅调用当前view的invalidate //方法,上一个位置的view并不会被清除。 ViewGroup v=(ViewGroup)getParent(); v.invalidate(rect); }
3、moveHandler3()方法只处理水平方向的滑动:它的原理是,不管竖直方向有没有产生偏移,始终使用原始位置的mTop和mBottom值绘制view。这样出来的效果就竖直方向无法移动了。
/** * 只能在水平方法移动 * @param x * @param y */ private void moveHandler3(int x,int y){ int gapX = x - preX; int left = getLeft() + gapX; int right = getRight() + gapX; if(left < 0 || right > w){ gapX = 0; } offsetLeftAndRight(gapX); // Rect实际上只是保证了一个固定大小的矩形区域而已。offsetLeftAndRight()代码会去改变 //button的mLeft,mTop,mRight,mBottom等值.从而实现button的重绘。 Rect rect=new Rect(getLeft()-gapX , getTop(), getRight()-gapX, getBottom()); ViewGroup v=(ViewGroup)getParent(); v.invalidate(rect); }
4、moveHandler4()方法只处理竖直方向的滑动:它的原理是,不管水平方向有没有产生偏移,始终使用原始位置的mLeft和mRight值绘制view。这样出来的效果就是水平方法无法移动了。
/** * 只能在竖直方法移动 * @param x * @param y */ private void moveHandler4(int x,int y){ System.out.println("y==" + y + ",preY==" + preY + ",h==" + getHeight()); int gapY = y - preY; // System.out.println("gapY==" + gapY); int top = getTop() + gapY; int bottom = getBottom() + gapY; if(top < 0){ top = 0; bottom = getHeight(); } if(bottom > h){ top = h - getHeight(); bottom = top + getHeight(); } this.layout(getLeft(), top, getRight(), bottom); }
至此,我们就成功模拟了ADW_Launcher的托盘中SliderView的滑动并且是实现了可随意滑动的图片的效果。本来这部分内容应该是放在这篇文章(ADW_Launcher的托盘
——SliderView研究)中的,但是由于上篇文章内容过长,因此就单独移出来。好了,这部分内容就说到这里,有不懂的地方可以回帖一起讨论,不足的地方请指正,一同进步,谢谢。
DEMO下载地址:
http://download.csdn.net/detail/yanbin1079415046/4647851
相关文章推荐
- 【Android】Glide结合Recyclerview(也适用于Listview)实现列表滑动的时候图片不加载,滑动停止的时候加载(已修正Listview部分以及排版)
- UIScrollView+UIPageControl+NSTimer实现图片的自动滑动以及用户可手动切换,UIPageControl可点击
- andorid---通过Viewpager实现图片滑动以及缩放
- UIScrollView+UIPageControl+NSTimer实现图片的自动滑动以及用户可手动切换,UIPageControl可点击
- UIScrollView+UIPageControl+NSTimer实现图片的自动滑动以及用户可手动切换,UIPageControl可点击
- UIScrollView+UIPageControl+NSTimer实现图片的自动滑动以及用户可手动切换,UIPageControl可点击
- Glide结合Recyclerview(也适用于Listview)实现列表滑动的时候图片不加载,滑动停止的时候加载(已修正Listview部分以及排版)
- UIScrollView+UIPageControl+NSTimer实现图片的自动滑动以及用户可手动切换,UIPageControl可点击
- Android使用ViewPager实现导航页根据情况禁止滑动以及点击切换
- Android实现ImageView图片缩放和拖动
- Android 使用ViewPager实现左右循环滑动图片
- Android实现点击WebView界面中图片滑动浏览与保存图片功能
- Android深入浅出系列之实例应用—简单的手指拖动图片,图片滑来滑去显示应用Gallery和BaseAdapter以及ImageView的使用
- Android 使用ViewPager实现左右循环滑动图片
- android viewPager 实现图片无限循环滑动并带有进度的自定义布局
- android viewpager 滑动分页以及禁止划屏 (模拟新浪)
- Android实现对imageview的拖动以及缩放
- UIScrollView+横置UICollectionView实现滑动返回(以及每页都可滑动返回)
- Android:使用ViewPager实现左右滑动切换图片(图上有点点)
- 使用ViewPager实现高仿launcher拖动效果