第一种

  

第二种

  

第一种实现方法

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

android 超简单的拖动按钮 悬浮按钮 吸附按钮 浮动按钮的更多相关文章

  1. Android 超简单的拖动按钮 悬浮按钮 吸附按钮

    第一种    第二种    第一种实现方法 xml布局 <RelativeLayout xmlns:android="http://schemas.android.com/apk/re ...

  2. Android超简单气泡效果

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680最近有用到水下气泡上升效果,因此在网上查了一下资料,结果还真找到了 ...

  3. Android | 超简单集成HMS ML Kit实现最大脸微笑抓拍

    前言   如果大家对HMS ML Kit 人脸检测功能有所了解,相信已经动手调用我们提供的接口编写自己的APP啦.目前就有小伙伴在调用接口的过程中反馈,不太清楚HMS ML Kit 文档中的MLMax ...

  4. Android 浮动按钮+上滑隐藏按钮+下滑显示按钮

    1.效果演示 1.1.关注这个红色的浮动按钮 . 可以看到,上滑的时候浮动按钮消失,因为用户迫切想知道下面的东西,而不是回到顶部. 当下滑的时候,用户想回到原来的位置,就可以点击浮动按钮,快速回到顶部 ...

  5. android 拖拽图片&拖动浮动按钮到处跑

    来自老外: 拖拽图片效果 方法一: 布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLa ...

  6. Android 浮动按钮的伸缩效果

    在做项目时想增加点动感,于是就有如下效果: 实现起来也很简单,通过属性动画和recyclerview 滑动结合就很好实现了. 通过给recycleview添加一个滑动监听:通过滚动的差值来处理动画 m ...

  7. 打造支持apk下载和html5缓存的 IIS(配合一个超简单的android APP使用)具体解释

    为什么要做这个看起来不靠谱的东西呢? 由于刚学android开发,还不能非常好的熟练控制android界面的编辑和操作,所以我的一个急着要的运用就改为html5版本号了,反正这个运用也是须要从serv ...

  8. 微信小程序添加悬浮在线客服会话按钮

    微信为小程序提供客服消息能力,小程序用户可以方便快捷地与小程序服务提供方进行沟通,并且已经做成了组件的形式,直接就可以调用.客服会话按钮,用于在页面上显示一个客服会话按钮,用户点击该按钮后会进入客服会 ...

  9. 【Android自己定义View实战】之自己定义超简单SearchView搜索框

    [Android自己定义View实战]之自己定义超简单SearchView搜索框 这篇文章是对之前文章的翻新,至于为什么我要又一次改动这篇文章?原因例如以下 1.有人举报我抄袭,原文链接:http:/ ...

随机推荐

  1. js中的分页

    分页是前端经常会用到的一个非常实用的一个知识点,今天闲来没事,做了一个小demo,虽然样子,比较丑,哈哈哈,但是这是分页的核心思想都在,希望能给某个小伙伴一些启发.可直接复制在编辑器中运行. < ...

  2. Ubuntu系统---nvidia驱动下载之问题

                                                                             Ubuntu系统---nvidia驱动下载之问题 百度 ...

  3. Codeforces 1187 F - Expected Square Beauty

    F - Expected Square Beauty 思路:https://codeforces.com/blog/entry/68111 代码: #pragma GCC optimize(2) #p ...

  4. Python 类和对象(2)

    上文讲到 类 = 属性 + 方法 今天来讲一下方法里常见的一个特殊的方法: 名字叫 __init__ 的构造方法 1.特殊的方法 :__init__ 该方法在我们实例化类的时候,python就自动调用 ...

  5. C# 判断一个string型的时间格式是否正确

    在项目开发过程中,由于各种坑爹的需求,我们可能需要用户自己手动输入时间,不过这种功能一般都出现在自己家的后台里面,咳咳,言归正传.既然如此,那么这个时候我们就需要对用户手动输入的时间格式进行验证,方法 ...

  6. 8、Spring Boot 2.x 服务器部署

    1.8 服务器部署 完整源码: Spring-Boot-Demos 1.8.1 jar包提取出来maven打包(避免每次重复打相同的jar包),pom.xml配置如下: <build> & ...

  7. Razor传值到js

    1.Asp.net MVC 3 中Session与ViewBag传值到Js中 http://www.cnblogs.com/wintersun/archive/2012/06/04/2534975.h ...

  8. 【线性代数】6-7:SVD分解(Singular Value Decomposition-SVD)

    title: [线性代数]6-7:SVD分解(Singular Value Decomposition-SVD) categories: Mathematic Linear Algebra keywo ...

  9. Linux进程通信之mmap

    mmap()函数: void *mmap(void* addr,size_t length,int port,int flags,int fd,off_t offset); 返回:成功:返回创建的映射 ...

  10. 2019.6.28 校内测试 T2 【音乐会】二重变革

    看到这个题之后,一个很暴力很直接的想法就是贴上题目中的代码然后交上去走人,但是很显然这是会TLE+MLE的,想想谁会这么傻把主要代码给你QwQ~: 其实这段代码是想告诉你一件事:用序列中的大数减去小数 ...