package com.crazy.floatwindow.view;
import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import com.crazy.floatwindow.R;
public class CircleMenuLayout extends ViewGroup {
private int mRadius;
/**
* 该容器内child item的默认尺寸
*/
private static final float RADIO_DEFAULT_CHILD_DIMENSION = 1 / 4f;
/**
* 菜单的中心child的默认尺寸
*/
private float RADIO_DEFAULT_CENTERITEM_DIMENSION = 1 / 3f;
/**
* 该容器的内边距,无视padding属性,如需边距请用该变量
*/
private static final float RADIO_PADDING_LAYOUT = 1 / 12f;
/**
* 当每秒移动角度达到该值时,认为是快速移动
*/
private static final int FLINGABLE_VALUE = 300;
/**
* 如果移动角度达到该值,则屏蔽点击
*/
private static final int NOCLICK_VALUE = 3;
/**
* 当每秒移动角度达到该值时,认为是快速移动
*/
private int mFlingableValue = FLINGABLE_VALUE;
/**
* 该容器的内边距,无视padding属性,如需边距请用该变量
*/
private float mPadding;
/**
* 布局时的开始角度
*/
private double mStartAngle = 0;
/**
* 菜单项的文本
*/
private String[] mItemTexts;
/**
* 菜单项的图标
*/
private int[] mItemImgs;
/**
* 菜单的个数
*/
private int mMenuItemCount;
/**
* 检测按下到抬起时旋转的角度
*/
private float mTmpAngle;
/**
* 检测按下到抬起时使用的时间
*/
private long mDownTime;
/**
* 判断是否正在自动滚动
*/
private boolean isFling;
private int mMenuItemLayoutId = R.layout.circle_menu_item;
public CircleMenuLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// 无视padding
setPadding(0, 0, 0, 0);
}
/**
* 设置布局的宽高,并策略menu item宽高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int resWidth = 0;
int resHeight = 0;
/**
* 根据传入的参数,分别获取测量模式和测量值
*/
int width = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
/**
* 如果宽或者高的测量模式非精确值
*/
if (widthMode != MeasureSpec.EXACTLY
|| heightMode != MeasureSpec.EXACTLY) {
// 主要设置为背景图的高度
resWidth = getSuggestedMinimumWidth();
// 如果未设置背景图片,则设置为屏幕宽高的默认值
resWidth = resWidth == 0 ? getDefaultWidth() : resWidth;
resHeight = getSuggestedMinimumHeight();
// 如果未设置背景图片,则设置为屏幕宽高的默认值
resHeight = resHeight == 0 ? getDefaultWidth() : resHeight;
} else {
// 如果都设置为精确值,则直接取小值;
resWidth = resHeight = Math.min(width, height);
}
setMeasuredDimension(resWidth, resHeight);
// 获得半径
mRadius = Math.max(getMeasuredWidth(), getMeasuredHeight());
// menu item数量
final int count = getChildCount();
// menu item尺寸
int childSize = (int) (mRadius * RADIO_DEFAULT_CHILD_DIMENSION);
// menu item测量模式
int childMode = MeasureSpec.EXACTLY;
// 迭代测量
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
// 计算menu item的尺寸;以及和设置好的模式,去对item进行测量
int makeMeasureSpec = -1;
if (child.getId() == R.id.id_circle_menu_item_center) {
makeMeasureSpec = MeasureSpec.makeMeasureSpec(
(int) (mRadius * RADIO_DEFAULT_CENTERITEM_DIMENSION),
childMode);
} else {
makeMeasureSpec = MeasureSpec.makeMeasureSpec(childSize,
childMode);
}
child.measure(makeMeasureSpec, makeMeasureSpec);
}
mPadding = RADIO_PADDING_LAYOUT * mRadius;
}
/**
* MenuItem的点击事件接口
*
*
*/
public interface OnMenuItemClickListener {
void itemClick(View view, int pos);
void itemCenterClick(View view);
}
/**
* MenuItem的点击事件接口
*/
private OnMenuItemClickListener mOnMenuItemClickListener;
/**
* 设置MenuItem的点击事件接口
*
* @param mOnMenuItemClickListener
*/
public void setOnMenuItemClickListener(
OnMenuItemClickListener mOnMenuItemClickListener) {
this.mOnMenuItemClickListener = mOnMenuItemClickListener;
}
/**
* 设置menu item的位置
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int layoutRadius = mRadius;
// Laying out the child views
final int childCount = getChildCount();
int left, top;
// menu item 的尺寸
int cWidth = (int) (layoutRadius * RADIO_DEFAULT_CHILD_DIMENSION);
// 根据menu item的个数,计算角度
float angleDelay = 360 / (getChildCount() - 1);
// 遍历去设置menuitem的位置
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
if (child.getId() == R.id.id_circle_menu_item_center)
continue;
if (child.getVisibility() == GONE) {
continue;
}
mStartAngle %= 360;
// 计算,中心点到menu item中心的距离
float tmp = layoutRadius / 2f - cWidth / 2 - mPadding;
// tmp cosa 即menu item中心点的横坐标
left = layoutRadius
/ 2
+ (int) Math.round(tmp
* Math.cos(Math.toRadians(mStartAngle)) - 1 / 2f
* cWidth);
// tmp sina 即menu item的纵坐标
top = layoutRadius
/ 2
+ (int) Math.round(tmp
* Math.sin(Math.toRadians(mStartAngle)) - 1 / 2f
* cWidth);
child.layout(left, top, left + cWidth, top + cWidth);
// 叠加尺寸
mStartAngle += angleDelay;
}
// 找到中心的view,如果存在设置onclick事件
View cView = findViewById(R.id.id_circle_menu_item_center);
if (cView != null) {
cView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mOnMenuItemClickListener != null) {
mOnMenuItemClickListener.itemCenterClick(v);
}
}
});
// 设置center item位置
int cl = layoutRadius / 2 - cView.getMeasuredWidth() / 2;
int cr = cl + cView.getMeasuredWidth();
cView.layout(cl, cl, cr, cr);
}
}
/**
* 记录上一次的x,y坐标
*/
private float mLastX;
private float mLastY;
/**
* 自动滚动的Runnable
*/
private AutoFlingRunnable mFlingRunnable;
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
// Log.e("TAG", "x = " + x + " , y = " + y);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastX = x;
mLastY = y;
mDownTime = System.currentTimeMillis();
mTmpAngle = 0;
// 如果当前已经在快速滚动
if (isFling) {
// 移除快速滚动的回调
removeCallbacks(mFlingRunnable);
isFling = false;
return true;
}
break;
case MotionEvent.ACTION_MOVE:
/**
* 获得开始的角度
*/
float start = getAngle(mLastX, mLastY);
/**
* 获得当前的角度
*/
float end = getAngle(x, y);
// Log.e("TAG", "start = " + start + " , end =" + end);
// 如果是一、四象限,则直接end-start,角度值都是正值
if (getQuadrant(x, y) == 1 || getQuadrant(x, y) == 4) {
mStartAngle += end - start;
mTmpAngle += end - start;
} else
// 二、三象限,色角度
没有合适的资源?快使用搜索试试~ 我知道了~
Android悬浮窗Demo源码-悬浮球转盘、悬浮加速小火箭效果、悬浮视频图片播放
共161个文件
xml:53个
png:45个
java:22个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
5星 · 超过95%的资源 11 下载量 140 浏览量
2023-09-11
15:50:57
上传
评论 1
收藏 1.68MB ZIP 举报
温馨提示
悬浮窗是一种比较常见的需求,就是把需要展示的内容界面缩小成一个悬浮窗,然后用户可以在其他界面上处理事情。 源码实现了三种比较常用的悬浮框效果 1.悬浮球转盘效果 2.悬浮加速小火箭效果 3.悬浮播放视频图片效果 具体实现思路和效果图可以参考博文 https://blog.csdn.net/daokedream/article/details/132740710
资源推荐
资源详情
资源评论
收起资源包目录
Android悬浮窗Demo源码-悬浮球转盘、悬浮加速小火箭效果、悬浮视频图片播放 (161个子文件)
gradlew.bat 2KB
gradlew.bat 2KB
gradlew.bat 2KB
.gitignore 240B
.gitignore 240B
.gitignore 240B
.gitignore 50B
.gitignore 50B
.gitignore 50B
.gitignore 6B
.gitignore 6B
.gitignore 6B
build.gradle 1KB
build.gradle 1KB
build.gradle 1KB
build.gradle 637B
build.gradle 637B
build.gradle 637B
settings.gradle 50B
settings.gradle 50B
settings.gradle 49B
gradlew 5KB
gradlew 5KB
gradlew 5KB
gradle-wrapper.jar 53KB
gradle-wrapper.jar 53KB
gradle-wrapper.jar 53KB
CircleMenuLayout.java 13KB
MyWindowManager.java 9KB
AssistMenuWindowManager.java 7KB
FloatWindowSmallView.java 7KB
FloatingVideoService.java 5KB
FloatingImageDisplayService.java 5KB
AssistTouchViewLayout.java 4KB
FloatWindowService.java 4KB
FloatWindowMenuView.java 3KB
MainActivity.java 3KB
FloatingButtonService.java 3KB
FloatWindowService.java 3KB
MainActivity.java 2KB
MainActivity.java 2KB
FloatWindowBigView.java 2KB
RocketLauncher.java 1KB
ExampleInstrumentedTest.java 805B
ExampleInstrumentedTest.java 787B
ExampleInstrumentedTest.java 781B
ExampleUnitTest.java 410B
ExampleUnitTest.java 398B
ExampleUnitTest.java 394B
image_04.jpg 292KB
image_02.jpg 214KB
image_03.jpg 139KB
image_05.jpg 100KB
image_01.jpg 68KB
bg.png 189KB
launcher_bg_hold.png 105KB
launcher_bg_fire.png 102KB
circle_bg.png 38KB
ic_launcher_round.png 16KB
ic_launcher_round.png 16KB
ic_launcher_round.png 12KB
ic_launcher_round.png 12KB
ic_launcher.png 10KB
rocket.png 10KB
home_mbank_1_clicked.png 10KB
home_mbank_4_clicked.png 9KB
ic_launcher.png 8KB
ic_launcher.png 7KB
home_mbank_2_clicked.png 7KB
ic_launcher_round.png 7KB
ic_launcher_round.png 7KB
ic_launcher_round.png 7KB
turnplate_mask_unlogin_normal.png 7KB
home_mbank_3_clicked.png 7KB
home_mbank_6_clicked.png 6KB
home_mbank_5_clicked.png 6KB
ic_launcher_round.png 5KB
ic_launcher_round.png 5KB
ic_launcher.png 5KB
bg_big.png 4KB
bg_big.png 4KB
home_mbank_1_normal.png 4KB
ic_launcher.png 4KB
ic_launcher.png 4KB
home_mbank_4_normal.png 3KB
ic_launcher_round.png 3KB
ic_launcher_round.png 3KB
home_mbank_2_normal.png 3KB
home_mbank_3_normal.png 3KB
ic_launcher.png 3KB
home_mbank_6_normal.png 2KB
center.png 2KB
home_mbank_5_normal.png 2KB
ic_launcher.png 1KB
touch_ic.png 1KB
ic_launcher.png 1KB
ic_launcher.png 1KB
ic_launcher.png 1KB
bg_small.png 458B
proguard-rules.pro 770B
共 161 条
- 1
- 2
Crazy程序猿2020
- 粉丝: 520
- 资源: 31
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
前往页