android 超简单的拖动按钮 悬浮按钮 吸附按钮

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>

Activity调用

		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>

自定义控件 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];
	}

}

Activity调用方法

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();
			}
		});



  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Android全局拖动悬浮按钮是一种在应用界面上悬浮按钮,用户可以通过拖动按钮的方式,在任意界面使用其提供的功能。这种悬浮按钮通常会呈现在屏幕的某个固定位置,如屏幕右下角。 使用全局拖动悬浮按钮可以为用户提供方便和快捷的操作方式。用户只需通过轻触按钮即可快速打开某个应用或执行某个功能,而不需要返回主界面或搜索相应的功能选项。这样可以大大提高用户的操作效率和体验。 开发这一功能的关键在于如何实现悬浮按钮在全局范围内的拖动和点击事件。一种常用的方法是通过在Android系统的WindowManager中创建一个可拖动的View,并设置其触摸事件监听器来实现。在触摸事件监听器中,我们可以处理按钮拖动、点击、长按等各种事件。 为了使全局拖动悬浮按钮更好地融入应用界面,我们可以对其进行自定义设置。例如,可以自定义按钮的形状、颜色、动画效果等,以适配不同的应用主题和风格。 需要注意的是,在设计和使用全局拖动悬浮按钮时,我们要遵循用户界面设计的基本原则,避免对用户的正常操作造成干扰和困扰。同时,也要考虑到移动设备的屏幕尺寸和分辨率的差异,以确保全局拖动悬浮按钮在不同设备上都能够正常显示和操作。 总而言之,Android全局拖动悬浮按钮是一种方便用户操作的功能,通过简单轻松的拖动和点击,用户可以快速访问应用的各种功能。开发者可以根据应用的需求和用户体验考虑,来设计和实现这一功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值