android 超简单的拖动按钮 悬浮按钮 吸附按钮
第一种
第二种
第一种实现方法
xml布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/startBtn" android:layout_width="35dp" android:layout_height="35dp" android:layout_centerInParent="true" android:background="@drawable/addstock" /> </RelativeLayout>
DisplayMetrics dm = getResources().getDisplayMetrics(); screenWidth = dm.widthPixels; screenHeight = dm.heightPixels; // Toast.makeText(getActivity(), screenWidth + "==" + screenHeight + "=" // + vHeight, 0).show(); // 拖动的按钮 btn = (Button) view.findViewById(R.id.startBtn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if (bool) { LatestNetDataPackage lnPackage = new LatestNetDataPackage(R.string.COMMAND_LATESTNET, fundKind, sortType, requestType, curPage, FUND_COUNT, 0); dataPackage = lnPackage; NetWorkTaskManager.addRequestToRequestCache(lnPackage, HListViewFragment.this, HListViewFragment.this, getActivity()); btn.setBackgroundResource(R.drawable.deletestock); bool = false; } else { LatestNetDataPackage lnPackage = new LatestNetDataPackage(R.string.COMMAND_LATESTNET, fundKind, sortType, requestType, curPage, FUND_COUNT, 1); dataPackage = lnPackage; NetWorkTaskManager.addRequestToRequestCache(lnPackage, HListViewFragment.this, HListViewFragment.this, getActivity()); btn.setBackgroundResource(R.drawable.addstock); bool = true; } } }); btn.setOnTouchListener(new OnTouchListener() { int lastX, lastY; // 记录移动的最后的位置 private int btnHeight; public boolean onTouch(View v, MotionEvent event) { // 获取Action int ea = event.getAction(); switch (ea) { case MotionEvent.ACTION_DOWN: // 按下 lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); screenWidth = view.getWidth(); screenHeight = view.getHeight(); btnHeight = btn.getHeight(); // Toast.makeText(getActivity(), "ACTION_DOWN:" + lastX + ", // " + lastY, 0).show(); break; case MotionEvent.ACTION_MOVE: // 移动 // 移动中动态设置位置 int dx = (int) event.getRawX() - lastX; int dy = (int) event.getRawY() - lastY; int left = v.getLeft() + dx; int top = v.getTop() + dy; int right = v.getRight() + dx; int bottom = v.getBottom() + dy; if (left < 0) { left = 0; right = left + v.getWidth(); } if (right > screenWidth) { right = screenWidth; left = right - v.getWidth(); } if (top < 0) { top = 0; bottom = top + v.getHeight(); } if (bottom > screenHeight) { bottom = screenHeight; top = bottom - v.getHeight(); } v.layout(left, top, right, bottom); // Toast.makeText(getActivity(), "position:" + left + ", " + // top + ", " + right + ", " + bottom, 0) // .show(); // 将当前的位置再次设置 lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); break; case MotionEvent.ACTION_UP: // 抬起 // 向四周吸附 // int dx1 = (int) event.getRawX() - lastX; // int dy1 = (int) event.getRawY() - lastY; // int left1 = v.getLeft() + dx1; // int top1 = v.getTop() + dy1; // int right1 = v.getRight() + dx1; // int bottom1 = v.getBottom() + dy1; // if (left1 < (screenWidth / 2)) { // if (top1 < 100) { // v.layout(left1, 0, right1, btnHeight); // } else if (bottom1 > (screenHeight - 200)) { // v.layout(left1, (screenHeight - btnHeight), right1, screenHeight); // } else { // v.layout(0, top1, btnHeight, bottom1); // } // } else { // if (top1 < 100) { // v.layout(left1, 0, right1, btnHeight); // } else if (bottom1 > (screenHeight - 200)) { // v.layout(left1, (screenHeight - btnHeight), right1, screenHeight); // } else { // v.layout((screenWidth - btnHeight), top1, screenWidth, bottom1); // } // } // break; } return false; } });view指的是布局
第二种实现方法
xml布局
<com.ui.view.DragFrameLayout android:id="@+id/becausefloat" android:layout_width="fill_parent" android:layout_height="0.0dp" android:layout_gravity="center_vertical" android:layout_weight="1" > <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <ImageView android:id="@+id/dragImg" android:layout_width="35dp" android:layout_height="35dp" android:background="@drawable/deletestock" /> </com.ui.view.DragFrameLayout>
package com.ui.view; import com.ui.R; import android.content.Context; import android.graphics.Rect; import android.location.Location; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.widget.FrameLayout; public class DragFrameLayout extends FrameLayout { private View view; private int width, heigh; private int screenWid, screenHei; private boolean isClickDrag = false; private boolean isTouchDrag = false; private float startX, startY; private CheckClick checkClick = new CheckClick(); private DragImageClickListener dragImageListener; public DragImageClickListener getDragImageListener() { return dragImageListener; } public void setDragImageListener(DragImageClickListener dragImageListener) { this.dragImageListener = dragImageListener; } public interface DragImageClickListener { public abstract void onClick(); } private class CheckClick implements Runnable { @Override public void run() { // TODO Auto-generated method stub isClickDrag = false; Log.i("drag", "=====checkTap===="); } } public DragFrameLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } public DragFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public void dragInit(View view) { screenWid = getWidth(); screenHei = getHeight(); width = view.getWidth(); heigh = view.getHeight(); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // TODO Auto-generated method stub switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: float x = ev.getX(); float y = ev.getY(); Rect frame = new Rect(); if (view == null) { view = findViewById(R.id.dragImg); dragInit(view); } view.getHitRect(frame); if (frame.contains((int) (x), (int) (y))) { isTouchDrag = true; startX = x; startY = y; return true; } break; } return false; } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub float x = event.getX(); float y = event.getY(); Rect frame = new Rect(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: view.getHitRect(frame); if (frame.contains((int) (x), (int) (y))) { startX = x; startY = y; isTouchDrag = true; isClickDrag = true; postDelayed(checkClick, ViewConfiguration.getTapTimeout()); } break; case MotionEvent.ACTION_MOVE: float distanX = Math.abs(x - startX); float distanY = Math.abs(y - startY); if (Math.sqrt(distanY * distanY + distanX * distanX) > 10) { isClickDrag = false; } move(x, y); break; case MotionEvent.ACTION_CANCEL: isClickDrag = false; isTouchDrag = false; break; case MotionEvent.ACTION_UP: if (isClickDrag == true) { dragImageListener.onClick(); removeCallbacks(checkClick); } isClickDrag = false; isTouchDrag = false; // 这段是把控件吸附四周 // if (x > width && x < screenWid - width && y > heigh // && y < screenHei - heigh) { // int minType = minDIstance(x, y); // Log.i("tags", screenHei + "==mintype=" + minType); // switch (minType) { // case LEFT: // x = width; // break; // case RIGHT: // x = screenWid - width; // break; // case TOP: // y = heigh; // break; // case BOTTOM: // y = screenHei - heigh; // break; // default: // break; // } // move(x, y); // } break; case MotionEvent.ACTION_OUTSIDE: isClickDrag = false; isTouchDrag = false; break; } return true; } private final static int LEFT = 1; private final static int RIGHT = 2; private final static int TOP = 3; private final static int BOTTOM = 4; private int minDIstance(float x, float y) { Log.i("tags", "x=" + x + "==y=" + y); boolean left, top; if (x <= (screenWid - x)) { left = true; } else { left = false; } if (y <= (screenHei - y)) { top = true; } else { top = false; } if(left&&top){ if(x<=y){ return LEFT; }else{ return TOP; } } if(left&&(!top)){ if(x<=(screenHei-y)){ return LEFT; }else{ return BOTTOM; } } if((!left)&top){ if((screenWid-x)<= y){ return RIGHT; }else{ return TOP; } } if((!left)&(!top)){ if((screenWid-x)<= (screenHei-y)){ return RIGHT; }else{ return BOTTOM; } } return 0; } private void move(float x, float y) { int left = (int) (x - width / 2); int top = (int) (y - heigh / 2); if (left <= 0) left = 0; if (top <= 0) top = 0; if (left > screenWid - width) left = screenWid - width; if (top > screenHei - heigh) top = screenHei - heigh; FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view .getLayoutParams(); params.setMargins(left, top, (screenWid - left - width), (screenHei - top - heigh)); view.setLayoutParams(params); requestLayout(); } public double getDistance(double lat1, double lon1, double lat2, double lon2) { float[] results = new float[1]; Location.distanceBetween(lat1, lon1, lat2, lon2, results); return results[0]; } }
dragImg = (ImageView)findViewById(R.id.dragImg); frameLayout = (DragFrameLayout)findViewById(R.id.becausefloat); frameLayout.setDragImageListener(new DragImageClickListener() { private boolean isDaix; @Override public void onClick() { // TODO Auto-generated method stub if (isDaix) { dragImg.setBackgroundResource(R.drawable.deletestock); isDaix = false; } else { dragImg.setBackgroundResource(R.drawable.addstock); isDaix = true; } Toast.makeText(MainActivity.this, "点击", Toast.LENGTH_LONG).show(); } });