转载请声明出处,谢谢!http://www.cnblogs.com/linguanh/
先上效果图,给大家个直观效果,后上实现代码:
-> ->->
ok,现在简单说下我上面的图片被做了什么操作,长按“休闲场所”,然后代码实现 震动,告诉用户,现在可以移动了,然后我把它和“海滨沿岸” 互换位置,注意此时的 图片是 半透明的,这些都是自定义特效,可以任意改。
代码来了:
这里我先给出,布局文件不含(ViewPager),这个根据个人修改的。
1 28 117 11814 18 81 8224 4930 37 4847 56 8062 69 7978 87 93 11699 106 115 125 131 138 147 148 149 150 151 156 162 168 175 184 185 186 191 198 206 213 222 223 224 232 238 245 254 255 256 257 265 271 278 287 288 289 290 291 292
这里再给出,里面的动画xml,可能有读者会需要到
1 23 11 23
java代码:
使用前需要知道,由于我是把这个页面 装载 在 viewPager 里面的,它是一个 fragment,本身 viewPager 有 onTouchEvent 事件,即可以左右侧滑,所以,当我在 这个页面里,长按图片试图拖动它的时候,就会造成 viewPager 和 子页面 长按滑动 冲突问题,嗯,是的。不过我已经把这个问题解决了,方法请见我的另外一篇博文链接http://www.cnblogs.com/linguanh/p/4540099.html
代码里面一些必要的注释,我已详细给出,相信能帮助大家理解。
1 package com.LGH.weixin; 2 3 import android.app.Activity; 4 import android.content.Context; 5 import android.content.Intent; 6 import android.content.SharedPreferences; 7 import android.graphics.Bitmap; 8 import android.graphics.drawable.Drawable; 9 import android.os.Bundle; 10 import android.support.v4.app.Fragment; 11 import android.util.DisplayMetrics; 12 import android.util.Log; 13 import android.view.Gravity; 14 import android.view.LayoutInflater; 15 import android.view.MenuItem; 16 import android.view.MotionEvent; 17 import android.view.View; 18 import android.view.View.OnClickListener; 19 import android.view.View.OnLongClickListener; 20 import android.view.View.OnTouchListener; 21 import android.view.ViewGroup; 22 import android.view.WindowManager; 23 import android.view.animation.Animation; 24 import android.view.animation.AnimationUtils; 25 import android.widget.ImageView; 26 import android.widget.RelativeLayout; 27 import android.widget.TextView; 28 import android.widget.Toast; 29 30 /** 31 * Created by Administrator on 2015/5/25. 32 */ 33 public class apartFragment extends Fragment implements OnTouchListener, OnClickListener, OnLongClickListener, Animation.AnimationListener{ 34 35 View main; 36 View mainActivity;//为了改变 主页面的viewPager 而设置 37 38 myViewPager temp; 39 Activity myActivity = new Activity(); 40 //MainActivity in_order_to_forbid_viewPager_slip = new MainActivity(); 41 42 private WindowManager windowManager; 43 private WindowManager.LayoutParams windowParams; 44 private View animationView; //当前单次点击播放动画的 view 45 46 public static int displayWidth; //屏幕宽度 47 public static int displayHeight; //屏幕高度 48 49 // 标志长按控件动作是否激活 50 private boolean isMove = false; 51 private boolean isAnimotionFinish = false; 52 53 private ImageView dragImageView; // 被拖动控件的preview 54 private int fromPoint = -1;//记录被拖动的View 55 private int toPoint = -1;//记录停止拖动时被碰撞的View 56 private Drawable temp_img;//缓存被拖动控件的ImageView的内容 57 private Drawable temp_view_img;//缓存被拖动控件的 View的内容 58 private Drawable temp_view_img_topoint;//缓存被拖动控件 经过 的 View的内容 59 private int[] relativeLayout_bgs = //最终只能通过它来解决 在拖动小图经过大图过程中,经过的大图被失真的问题 60 new int[]{R.drawable.one,R.drawable.two,R.drawable.three,R.drawable.four,R.drawable.backg,R.drawable.five,R.drawable.six,R.drawable.seven}; 61 62 private String temp_str;//缓存被拖动控件的TextView的内容 63 64 //移动的位置 65 private int dragPointX; 66 private int dragPointY; 67 //当前位置距离边界的位置 68 private int dragOffsetX; 69 private int dragOffsetY; 70 private int x, y; 71 //用于循环碰撞的数组 72 private View[] views = new View[8]; 73 private TextView[] tvs = new TextView[8]; 74 private ImageView[] ivs = new ImageView[8]; 75 //用来显示经纬度、发包数 76 private TextView bottom_bar_up, bottom_bar_down; 77 //用于记录碰撞的面积 78 //图标出现和消失的过度动画 79 private Animation flash; 80 // private Animation disappear; 81 private Animation blink; 82 private Animation original; 83 /* 84 * 用于记录所有View的坐标的二位数组 85 * points[0][0]用于记录左上角的X 86 * points[0][1]用于记录左上角的Y 87 * points[0][2]用于记录右下角的X 88 * points[0][3]用于记录右下角的Y 89 */ 90 private int[][] points = new int[8][4]; 91 92 @Override 93 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 94 main = inflater.inflate(R.layout.apart_center,container,false); 95 mainActivity = inflater.inflate(R.layout.activity_main,container,false); 96 97 myActivity = getActivity(); 98 99 //temp = (myViewPager) mainActivity.findViewById(R.id.vp);100 //temp = in_order_to_forbid_viewPager_slip.getVP();101 //temp.requestDisallowInterceptTouchEvent(true);102 //temp.setStopViewPagerSlip(false);103 104 initView(main);//初始化页面105 106 for(int i = 0; i < views.length; i++){107 views[i].setOnClickListener(this);//绑定点击(短按)监听器108 views[i].setOnLongClickListener(this);//绑定长按监听器109 views[i].setOnTouchListener(this);//绑定触摸监听器110 }111 flash = AnimationUtils.loadAnimation(getActivity(), R.anim.flash); //自定义缩放动画112 //disappear = AnimationUtils.loadAnimation(this, R.anim.disappear);113 blink = AnimationUtils.loadAnimation(getActivity(), R.anim.blink);114 original = AnimationUtils.loadAnimation(getActivity(), R.anim.original);115 116 return main;117 118 }119 120 121 122 //触摸监听器123 124 @Override125 public boolean onTouch(View v, MotionEvent event) {126 // TODO Auto-generated method stub127 x = (int) event.getX();128 y = (int) event.getY();129 switch(event.getAction()){130 case MotionEvent.ACTION_DOWN:131 if(points[0][0] == 0){132 initPoints();133 }134 break;135 case MotionEvent.ACTION_MOVE:136 137 if(isMove){138 if(dragImageView == null){139 140 dragPointX = x;141 dragPointY = y;142 dragOffsetX = (int)event.getRawX() - x;143 dragOffsetY = (int)event.getRawY() - y;144 //移动细节的 logcat 记录145 Log.v("getX", String.valueOf(x) + "=====" + String.valueOf(event.getX()));146 Log.v("getY", String.valueOf(y) + "=====" + String.valueOf(event.getY()));147 Log.v("getLeft", String.valueOf(v.getLeft()) + "=====" + String.valueOf(event.getX()-v.getLeft()));148 Log.v("getgetTop", String.valueOf(v.getTop()) + "=====" + String.valueOf(event.getY()-v.getTop()));149 Log.v("getRawX", String.valueOf(event.getRawX()) + "=====" + String.valueOf(event.getRawX() - event.getX()));150 Log.v("getRawY", String.valueOf(event.getRawY()) + "=====" + String.valueOf(event.getRawY() - event.getY()));151 152 v.destroyDrawingCache();153 v.setDrawingCacheEnabled(true);154 v.setDrawingCacheBackgroundColor(0x000000);155 Bitmap bm = Bitmap.createBitmap(v.getDrawingCache(true));156 Bitmap bitmap = Bitmap.createBitmap(bm, 8, 8, bm.getWidth()-8, bm.getHeight()-8);157 startDrag(bitmap, x, y); //实时生成 拖动效果,参数一是 当前图片,x y为目标标158 // v.startAnimation(blink);159 v.setVisibility(View.INVISIBLE);//隐藏当前被长按的控件160 Log.v("OnTouch>>>>", "===隐藏!!!");161 }else{162 onDrag(x, y);163 hide();164 Log.v("OnTouch>>>>", "===动了!!!");165 }166 }else{167 Log.v("OnTouch>>>>", "===不移动");168 }169 break;170 case MotionEvent.ACTION_UP:171 //if(!isMove){ //172 173 //}174 isMove = false;175 stopDrag();176 // fromPoint = -1;177 // toPoint = -1;178 show();179 exchange();180 181 182 break;183 }184 return false;185 }186 /**187 * 长按监听器188 */189 @Override190 public boolean onLongClick(View v) {191 // TODO Auto-generated method stub192 Log.v("onLongClick>>>>>", "LongClick");193 for(int i = 0; i < views.length; i ++){194 if(v.equals(views[i])){195 fromPoint = i;196 isMove = true;197 getZhenDong.Vibrate(getActivity(), 100);//震动提醒198 199 //temp.requestDisallowInterceptTouchEvent(true); //这个阻止申请的函数必须放在 onTouchListener 里面200 // 在 该 fragment 长按,先去掉 viewPager 的侧滑,防止冲突201 // requestDisallowInterceptTouchEvent(true); 在主页面可以实现,在这里还是不行,妈的202 main.getParent().requestDisallowInterceptTouchEvent(true); //终于!!!,这样可以203 204 //temp.setStopViewPagerSlip(false);//这样也是不行,fuck the dog !205 206 temp_img = ivs[i].getDrawable();//初始化被拖动的View的 ImageView的缓存207 temp_view_img = views[i].getBackground();208 temp_str = tvs[i].getText().toString();//初始化被拖动的View的TextView的缓存209 210 return true;211 }212 }213 return true;214 }215 /**216 * 短按监听器217 */218 @Override219 public void onClick(View v) {220 // TODO Auto-generated method stub221 animationView = v;222 Animation temp = AnimationUtils.loadAnimation(getActivity(), R.anim.flash);223 v.startAnimation(temp); //设置单点 时播放缩放动画224 for(int i = 0; i < views.length; i++){225 views[i].setOnClickListener(null);//一次点击后,移除所有的监听事件226 }227 temp.setAnimationListener(this);228 //跳转 操作 放置 动画 播放完毕的 监听里面,实现 播放完 动画 再 跳转229 230 }231 @Override232 public void onAnimationStart(Animation animation) {233 if (isAnimotionFinish) {234 isAnimotionFinish = false;235 }236 }237 238 @Override239 public void onAnimationEnd(Animation animation) {240 isAnimotionFinish = true;241 for (int i = 0; i < views.length; i++) {242 views[i].setOnClickListener(this);//恢复监听243 }244 Toast.makeText(getActivity(), "finish animation", Toast.LENGTH_LONG).show();245 for (int i = 0; i < views.length; i++) {246 Intent readToJump = new Intent(myActivity,infoMain.class);247 startActivity(readToJump);248 }249 }250 251 @Override252 public void onAnimationRepeat(Animation animation) {253 254 }255 256 /**257 * 初始化页面所有控件258 */259 private void initView(View view){260 261 //获取屏幕分辨率262 DisplayMetrics displayMetrics = new DisplayMetrics();263 myActivity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);264 displayWidth = displayMetrics.widthPixels;265 displayHeight = displayMetrics.heightPixels;266 //-------------下面的 ImageView 已被我 废弃,大家可以 根据自己需求,使用它 -------------267 268 views[0] = (RelativeLayout) view.findViewById(R.id.rl1);269 tvs[0] = (TextView) view.findViewById(R.id.tv1);270 ivs[0] = (ImageView) view.findViewById(R.id.img1);271 272 views[1] = (RelativeLayout) view.findViewById(R.id.rl2);273 tvs[1] = (TextView) view.findViewById(R.id.tv2);274 ivs[1] = (ImageView) view.findViewById(R.id.img2);275 276 views[2] = (RelativeLayout) view.findViewById(R.id.rl3);277 tvs[2] = (TextView) view.findViewById(R.id.tv3);278 ivs[2] = (ImageView) view.findViewById(R.id.img3);279 280 views[3] = (RelativeLayout) view.findViewById(R.id.rl4);281 tvs[3] = (TextView) view.findViewById(R.id.tv4);282 ivs[3] = (ImageView) view.findViewById(R.id.img4);283 284 views[4] = (RelativeLayout) view.findViewById(R.id.rl5);285 tvs[4] = (TextView) view.findViewById(R.id.tv5);286 ivs[4] = (ImageView) view.findViewById(R.id.img5);287 288 views[5] = (RelativeLayout) view.findViewById(R.id.rl7);//1/2大小的relativelayout289 tvs[5] = (TextView) view.findViewById(R.id.tv7);290 ivs[5] = (ImageView) view.findViewById(R.id.img7);291 292 views[6] = (RelativeLayout) view.findViewById(R.id.rl8);//1/4大小的relativelayout293 tvs[6] = (TextView) view.findViewById(R.id.tv8);294 ivs[6] = (ImageView) view.findViewById(R.id.img8);295 296 views[7] = (RelativeLayout) view.findViewById(R.id.rl9);//1/4大小的relativelayout297 tvs[7] = (TextView) view.findViewById(R.id.tv9);298 ivs[7] = (ImageView) view.findViewById(R.id.img9);299 300 //bottom_bar_up = (TextView)main.findViewById(R.id.bottom_bar_up);301 //bottom_bar_down = (TextView)main.findViewById(R.id.bottom_bar_down);302 303 int[] power = {0, 1, 2, 3, 4, 5, 6, 7};304 for(int i = 0; i < power.length; i++){305 switch (power[i]){306 case 7:307 tvs[i].setText(getText(R.string.folder));308 break;309 case 6:310 tvs[i].setText(getText(R.string.person_info));311 break;312 case 5:313 tvs[i].setText(getText(R.string.system_info));314 break;315 case 4:316 tvs[i].setText(getText(R.string.hidden_danger_report));317 break;318 case 3:319 tvs[i].setText(getText(R.string.open));320 break;321 case 2:322 tvs[i].setText(getText(R.string.qr_code));323 break;324 case 1:325 tvs[i].setText(getText(R.string.work_order));326 break;327 case 0:328 tvs[i].setText(getText(R.string.routing_inspection));329 break;330 }331 332 333 }334 }335 /**336 * 生成被拖动控件的preView337 */338 private void startDrag(Bitmap bm, int x, int y)339 {340 Log.v("startDrag>>>>>>", "startDrag");341 stopDrag();342 windowParams = new WindowManager.LayoutParams();343 windowParams.gravity = Gravity.TOP | Gravity.LEFT;344 345 //左上角相对于屏幕的坐标346 windowParams.x = x - dragPointX + dragOffsetX;347 windowParams.y = y - dragPointY + dragOffsetY - 40;348 349 windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;350 windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;351 windowParams.alpha = 0.5f;352 353 ImageView iv = new ImageView(myActivity);354 iv.setImageBitmap(bm);355 windowManager = (WindowManager) myActivity.getSystemService(Context.WINDOW_SERVICE);356 windowManager.addView(iv, windowParams);357 358 dragImageView = iv;359 }360 361 /**362 * 停止绘制,清空preView363 */364 private void stopDrag()365 {366 if (dragImageView != null)367 {368 windowManager.removeView(dragImageView);369 dragImageView = null;370 Log.v("StopDrag>>>>>>>", "disappear");371 }372 }373 374 /**375 * 拖动(Move)过程中不断调整preView的位置,以呈现拖动的效果376 */377 private void onDrag(int x, int y) {378 Log.v("onDrag>>>>>>", "onDrag");379 if (dragImageView != null) {380 windowParams.alpha = 0.5f;381 382 windowParams.x = x - dragPointX + dragOffsetX;383 windowParams.y = y - dragPointY + dragOffsetY - 40;384 385 Log.v("x", String.valueOf(x));386 Log.v("y", String.valueOf(y));387 Log.v("windowParams.x", String.valueOf(windowParams.x));388 Log.v("windowParams.y", String.valueOf(windowParams.y));389 windowManager.updateViewLayout(dragImageView, windowParams);390 }391 }392 393 /**394 * 返回参数View的相对屏幕的绝对坐标值395 * point[0]用于记录左上角的X396 * point[1]用于记录左上角的Y397 * point[2]用于记录右下角的X398 * point[3]用于记录右下角的Y399 */400 private int[] getPoint(View v){401 int point[] = new int[4];402 v.getLocationOnScreen(point);403 point[2] = point[0] + v.getWidth();404 point[3] = point[1] + v.getHeight();405 for(int i = 0; i < point.length; i++){406 System.out.println("point[" + i + "]::::::" + point[i]);407 }408 409 return point;410 }411 /**412 * 返回被拖动View的中心的坐标413 */414 private int[] getCentroPoint(View v){415 int point[] = new int[2];416 if(v != null){417 point = new int[2];418 v.getLocationOnScreen(point);419 point[0] = point[0] + v.getWidth()/2;420 point[1] = point[1] + v.getHeight()/2;421 for(int i = 0; i < point.length; i++){422 System.out.println("point[" + i + "]::::::" + point[i]);423 }424 }425 return point;426 }427 428 /**429 * 判断被拖动的View的中心点在哪个View内部,就把哪个View隐藏430 */431 private void hide(){432 int point[] = getCentroPoint(dragImageView);433 for(int i = 0; i < views.length; i++){434 if(point[0] > points[i][0] && point[1] > points[i][1] && point[0] < points[i][2] && point[1] < points[i][3]){435 if(views[i].isShown()){436 toPoint = i;437 //temp_view_img_topoint = views[i].getBackground();438 439 onExchange();//将被拖拽的View的原始位置的数据设置为被覆盖的View的数据440 441 views[i].setVisibility(View.INVISIBLE);442 }443 // if(views[i].getAnimation() == null){444 // views[i].startAnimation(blink);445 // toPoint = i;446 // }447 }else{448 // if(views[i].getAnimation() != null && !views[i].getAnimation().equals(original)){449 // views[i].startAnimation(original);450 // }451 // views[i].clearAnimation();452 // views[i].invalidate();453 // toPoint = -1;454 if(toPoint == i){455 toPoint = -1;456 onExchange();//将被拖拽的View的原始位置的数据恢复初始数据457 }458 if(!views[i].isShown()){459 //Toast.makeText(this,i+"--",Toast.LENGTH_LONG).show();460 views[i].setVisibility(View.VISIBLE);461 //views[i].setBackground(temp_view_img_topoint);462 }463 }464 }465 //temp.requestDisallowInterceptTouchEvent(false); //恢复 viewPager 的可侧滑466 }467 /**468 * 拖动结束,将所有的View都显示出来469 */470 private void show(){471 for(int i = 0; i < views.length; i++){472 if(!views[i].isShown()){473 // toPoint = i;474 views[i].setVisibility(View.VISIBLE);475 views[i].startAnimation(flash);476 }477 views[i].setVisibility(View.VISIBLE);478 // if(views[i].getAnimation() != null && !views[i].getAnimation().equals(flash)){479 // views[i].startAnimation(flash);480 // }481 }482 }483 /**484 * 初始化所有View的坐标并存放到8行4列的二维数组point[8][4]485 */486 private void initPoints(){487 for(int i = 0; i < points.length; i++){488 points[i] = getPoint(views[i]);489 }490 }491 /**492 * 拖拽结束,将fromView和toView的内容进行交换493 * @return 交换返回true,不交换返回false494 */495 private boolean exchange(){496 if(fromPoint != -1 && toPoint != -1 && fromPoint != toPoint ){497 tvs[fromPoint].setText(tvs[toPoint].getText());498 //ivs[fromPoint].setImageDrawable(ivs[toPoint].getDrawable());499 views[fromPoint].setBackground(views[toPoint].getBackground());500 501 tvs[toPoint].setText(temp_str);502 //ivs[toPoint].setImageDrawable(temp_img);503 views[toPoint].setBackground(temp_view_img);504 505 views[fromPoint].startAnimation(flash);506 // temp = toPoint;507 fromPoint = -1;508 toPoint = -1;509 return true;510 }else{511 fromPoint = -1;512 toPoint = -1;513 return false;514 }515 516 }517 /**518 * 用于正在被拖动View的原始位置的内容的实时交换519 */520 private void onExchange(){521 if(fromPoint != -1 && toPoint != -1 && fromPoint != toPoint ){522 523 //将被拖拽的View的原始位置的数据, 设置为, 被覆盖的View的数据524 //Toast.makeText(this,fromPoint+"--"+toPoint,Toast.LENGTH_LONG).show();525 tvs[fromPoint].setText(tvs[toPoint].getText());526 //ivs[fromPoint].setImageDrawable(ivs[toPoint].getDrawable());527 //views[fromPoint].setBackgroundResource(views[fromPoint].getDrawable(R.drawable.two));528 529 // 不适用 getBackground() 传入,会造成大图失真530 views[fromPoint].setBackground(getResources().getDrawable(relativeLayout_bgs[toPoint]));//实现拖曳过程中的实时互换531 //views[toPoint].setBackground(views[fromPoint].getBackground());532 533 views[fromPoint].startAnimation(blink);534 535 }else{536 //Toast.makeText(this,fromPoint+"--"+toPoint,Toast.LENGTH_LONG).show();537 //将被拖拽的View的原始位置的数据恢复初始数据538 tvs[fromPoint].setText(temp_str);539 //ivs[fromPoint].setImageDrawable(temp_img);540 views[fromPoint].setBackground(temp_view_img);541 }542 }543 /**544 * 用来显示更新bottom_bar中的数据545 */546 private void updateBottomBar(int sendPackageNo, int rate, double longitude, double dimension){547 //在这里可以设置 footer 文本548 }549 550 551 552 @Override553 public boolean onOptionsItemSelected(MenuItem item) {554 SharedPreferences preferences = myActivity.getSharedPreferences("system_config", myActivity.MODE_PRIVATE);555 boolean isChanged = preferences.getBoolean("theme_value", true);556 SharedPreferences.Editor editor = preferences.edit();557 switch (item.getItemId()) {558 case R.id.menu_settings: {559 560 if (isChanged) {561 isChanged = false;562 } else {563 isChanged = true;564 }565 editor.putBoolean("theme_value", isChanged);566 editor.commit();567 break;568 }569 }570 return super.onOptionsItemSelected(item);571 }572 573 574 }
打完收工,有问题请留言。