6.7.0 - Alpha3 - 文件管理器浮动按钮展开后点击菜单项时优化菜单收起时机
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
"http 模块相关方法支持不安全选项参数 (isInsecure/insecure), 用于忽略证书相关异常 _[`issue #417`](http://issues.autojs6.com/417)_",
|
||||
"android.graphics.Paint#setColor 支持正常解析 ColorInt/ColorHex/ColorName 等颜色参数",
|
||||
"内置模块相关方法实参类型的异常消息增加类型摘要信息",
|
||||
"文件管理器浮动按钮展开后点击菜单项时优化菜单收起时机",
|
||||
"崩溃报告页面支持双指缩放调整字体大小并添加常用功能按钮",
|
||||
"应用启动器图标支持自适应图标特性 _[`issue #405`](http://issues.autojs6.com/405)_"
|
||||
],
|
||||
@@ -782,7 +783,7 @@
|
||||
"主题色增加更多 Material Design Color (材料设计颜色) 选项",
|
||||
"文件管理器/任务面板等列表项图标适当轻量化并适配主题色",
|
||||
"主页搜索框的提示文本颜色适配夜间模式",
|
||||
"对话框/文本/Fab/AppBar/列表项等部件适配夜间模式",
|
||||
"对话框/文本/FAB/AppBar/列表项等部件适配夜间模式",
|
||||
"文档/设置/关于/主题色/布局分析等页面及浮动按钮菜单适配夜间模式",
|
||||
"页面布局尽可能兼容 RTL (Right-To-Left) 布局",
|
||||
"关于页面增加图标动画效果",
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -27,6 +27,7 @@ sync.ffs_db
|
||||
|
||||
/build/
|
||||
/libs/**/build/
|
||||
/modules/**/build/
|
||||
/captures/
|
||||
/release/
|
||||
/releases/
|
||||
|
||||
@@ -2,9 +2,11 @@ package org.autojs.autojs.ui.main;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
@@ -26,10 +28,6 @@ import org.autojs.autojs6.R;
|
||||
*/
|
||||
public class FloatingActionMenu extends FrameLayout implements View.OnClickListener {
|
||||
|
||||
public interface OnFloatingActionButtonClickListener {
|
||||
void onClick(FloatingActionButton button, int pos);
|
||||
}
|
||||
|
||||
private static final int[] ICONS = {
|
||||
R.drawable.ic_floating_action_menu_dir,
|
||||
R.drawable.ic_floating_action_menu_file,
|
||||
@@ -42,16 +40,16 @@ public class FloatingActionMenu extends FrameLayout implements View.OnClickListe
|
||||
R.string.text_import,
|
||||
R.string.text_project};
|
||||
|
||||
private View mOverlay = null;
|
||||
private static final int ANIMATION_INTERVAL = 30;
|
||||
private static final int ANIMATION_DURATION = 250;
|
||||
|
||||
private final Interpolator mInterpolator = new FastOutSlowInInterpolator();
|
||||
private final PublishSubject<Boolean> mState = PublishSubject.create();
|
||||
|
||||
private View mOverlay = null;
|
||||
private FloatingActionButton[] mFabs;
|
||||
private View[] mFabContainers;
|
||||
private boolean mExpanded = false;
|
||||
private boolean mShouldCheckExpanded = true;
|
||||
private final int mInterval = 30;
|
||||
private final int mDuration = 250;
|
||||
private final Interpolator mInterpolator = new FastOutSlowInInterpolator();
|
||||
private final PublishSubject<Boolean> mState = PublishSubject.create();
|
||||
private OnFloatingActionButtonClickListener mOnFloatingActionButtonClickListener;
|
||||
|
||||
public FloatingActionMenu(@NonNull Context context) {
|
||||
@@ -69,16 +67,12 @@ public class FloatingActionMenu extends FrameLayout implements View.OnClickListe
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
buildFabs(ICONS, LABELS);
|
||||
}
|
||||
|
||||
public boolean isExpanded() {
|
||||
return mExpanded;
|
||||
}
|
||||
|
||||
public boolean shouldCheckExpanded() {
|
||||
return mShouldCheckExpanded;
|
||||
public PublishSubject<Boolean> getState() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
public void expand() {
|
||||
@@ -86,38 +80,19 @@ public class FloatingActionMenu extends FrameLayout implements View.OnClickListe
|
||||
setVisibility(VISIBLE);
|
||||
int h = mFabs[0].getHeight();
|
||||
for (int i = 0; i < mFabContainers.length; i++) {
|
||||
animateY(mFabContainers[i], -(h + mInterval) * (i + 1), null);
|
||||
animateY(mFabContainers[i], -(h + ANIMATION_INTERVAL) * (i + 1), null);
|
||||
rotate(mFabs[i]);
|
||||
}
|
||||
mExpanded = true;
|
||||
mState.onNext(true);
|
||||
}
|
||||
|
||||
private void rotate(FloatingActionButton fab) {
|
||||
fab.setRotation(0);
|
||||
fab.animate()
|
||||
.rotation(360)
|
||||
.setDuration(mDuration)
|
||||
.setInterpolator(mInterpolator)
|
||||
.start();
|
||||
}
|
||||
|
||||
private void animateY(View view, float y, Animator.AnimatorListener l) {
|
||||
view.animate()
|
||||
.translationY(y)
|
||||
.setDuration(mDuration)
|
||||
.setInterpolator(mInterpolator)
|
||||
.setListener(l)
|
||||
.start();
|
||||
}
|
||||
|
||||
public void collapse() {
|
||||
hideOverlay();
|
||||
animateY(mFabContainers[0], 0, new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
setVisibility(INVISIBLE);
|
||||
mShouldCheckExpanded = true;
|
||||
}
|
||||
});
|
||||
for (int i = 1; i < mFabContainers.length; i++) {
|
||||
@@ -128,6 +103,51 @@ public class FloatingActionMenu extends FrameLayout implements View.OnClickListe
|
||||
mState.onNext(false);
|
||||
}
|
||||
|
||||
public void setOnFloatingActionButtonClickListener(OnFloatingActionButtonClickListener listener) {
|
||||
mOnFloatingActionButtonClickListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
if (heightMode == MeasureSpec.EXACTLY) {
|
||||
return;
|
||||
}
|
||||
int h = mFabContainers[0].getMeasuredHeight();
|
||||
setMeasuredDimension(getMeasuredWidth(), (h + ANIMATION_INTERVAL) * mFabs.length + h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
collapse();
|
||||
if (mOnFloatingActionButtonClickListener != null) {
|
||||
mOnFloatingActionButtonClickListener.onClick((FloatingActionButton) v, (int) v.getTag());
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
buildFabs(ICONS, LABELS);
|
||||
}
|
||||
|
||||
private void rotate(FloatingActionButton fab) {
|
||||
fab.setRotation(0);
|
||||
fab.animate()
|
||||
.rotation(360)
|
||||
.setDuration(ANIMATION_DURATION)
|
||||
.setInterpolator(mInterpolator)
|
||||
.start();
|
||||
}
|
||||
|
||||
private void animateY(View view, float y, Animator.AnimatorListener l) {
|
||||
view.animate()
|
||||
.translationY(y)
|
||||
.setDuration(ANIMATION_DURATION)
|
||||
.setInterpolator(mInterpolator)
|
||||
.setListener(l)
|
||||
.start();
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private void buildFabs(int[] icons, int[] labels) {
|
||||
if (icons.length != labels.length) {
|
||||
@@ -149,51 +169,33 @@ public class FloatingActionMenu extends FrameLayout implements View.OnClickListe
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
// Call super.onMeasure to measure children and width
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
if (heightMode == MeasureSpec.EXACTLY) {
|
||||
private void showOverlay() {
|
||||
if (mOverlay != null) {
|
||||
if (mOverlay.getVisibility() != VISIBLE) {
|
||||
mOverlay.setVisibility(View.VISIBLE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
int h = mFabContainers[0].getMeasuredHeight();
|
||||
setMeasuredDimension(getMeasuredWidth(), (h + mInterval) * mFabs.length + h);
|
||||
}
|
||||
|
||||
public PublishSubject<Boolean> getState() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// collapse();
|
||||
if (mOnFloatingActionButtonClickListener != null) {
|
||||
mOnFloatingActionButtonClickListener.onClick((FloatingActionButton) v, (int) v.getTag());
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnFloatingActionButtonClickListener(OnFloatingActionButtonClickListener onFloatingActionButtonClickListener) {
|
||||
mOnFloatingActionButtonClickListener = onFloatingActionButtonClickListener;
|
||||
}
|
||||
|
||||
private void showOverlay() {
|
||||
if (mOverlay != null && mOverlay.getVisibility() == VISIBLE) return;
|
||||
|
||||
Context context = getContext();
|
||||
|
||||
if (!(context instanceof Activity activity)) return;
|
||||
|
||||
if (!(activity.findViewById(android.R.id.content) instanceof ViewGroup root)) return;
|
||||
|
||||
FloatingActionMenu thisMenu = this;
|
||||
|
||||
mOverlay = new View(context) {
|
||||
private final int[] loc = new int[2];
|
||||
private final Rect menuRect = new Rect();
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
mShouldCheckExpanded = false;
|
||||
collapse();
|
||||
root.post(() -> root.removeView(this));
|
||||
var replay = MotionEvent.obtain(event);
|
||||
root.post(() -> activity.getWindow().getDecorView().dispatchTouchEvent(replay));
|
||||
thisMenu.getLocationOnScreen(loc);
|
||||
menuRect.set(loc[0], loc[1], loc[0] + thisMenu.getWidth(), loc[1] + thisMenu.getHeight());
|
||||
if (!isInMenuButtonsArea(menuRect, event)) {
|
||||
var replay = MotionEvent.obtain(event);
|
||||
root.post(() -> activity.getWindow().getDecorView().dispatchTouchEvent(replay));
|
||||
collapse();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -205,11 +207,16 @@ public class FloatingActionMenu extends FrameLayout implements View.OnClickListe
|
||||
root.addView(mOverlay);
|
||||
}
|
||||
|
||||
private void hideOverlay() {
|
||||
if (mOverlay == null) return;
|
||||
if (!(mOverlay.getParent() instanceof ViewGroup parent)) return;
|
||||
parent.removeView(mOverlay);
|
||||
mOverlay = null;
|
||||
private boolean isInMenuButtonsArea(Rect menuRect, MotionEvent event) {
|
||||
return menuRect.contains((int) event.getRawX(), (int) event.getRawY());
|
||||
}
|
||||
|
||||
}
|
||||
private void hideOverlay() {
|
||||
if (mOverlay != null) mOverlay.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
public interface OnFloatingActionButtonClickListener {
|
||||
void onClick(FloatingActionButton button, int pos);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -119,8 +119,7 @@ class ExplorerFragment : ViewPagerFragment(0), OnFloatingActionButtonClickListen
|
||||
}
|
||||
|
||||
override fun onFabClick(fab: FloatingActionButton) {
|
||||
// initFloatingActionMenuIfNeeded(fab).run { if (isExpanded) collapse() else expand() }
|
||||
initFloatingActionMenuIfNeeded(fab).run { if (shouldCheckExpanded() && !isExpanded) expand() }
|
||||
initFloatingActionMenuIfNeeded(fab).run { if (isExpanded) collapse() else expand() }
|
||||
}
|
||||
|
||||
private fun initFloatingActionMenuIfNeeded(fab: FloatingActionButton): FloatingActionMenu {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#Thu Jul 03 14:14:37 CST 2025
|
||||
BUILD_TIME=1751523277489
|
||||
#Wed Jul 16 14:49:49 CST 2025
|
||||
BUILD_TIME=1752648589445
|
||||
COMPILE_SDK_VERSION=35
|
||||
IMAGE_QUANT_CMAKE_VERSION=3.22.1
|
||||
IMAGE_QUANT_NDK_VERSION=26.1.10909125
|
||||
@@ -19,6 +19,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13
|
||||
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
|
||||
TARGET_SDK_VERSION=35
|
||||
TARGET_SDK_VERSION_INRT=29
|
||||
VERSION_BUILD=3319
|
||||
VERSION_BUILD=3323
|
||||
VERSION_NAME=6.7.0 Alpha3
|
||||
VSCODE_EXT_REQUIRED_VERSION=1.0.8
|
||||
|
||||
Reference in New Issue
Block a user