6.6.3 - Alpha4 - 布局分析菜单添加渐变分隔线

This commit is contained in:
SuperMonster003
2025-05-13 21:07:22 +08:00
parent 487b4b4edd
commit 514d39eb6c
23 changed files with 229 additions and 92 deletions

View File

@@ -24,6 +24,8 @@
* `修复` console.setContentTextColor 方法导致日志字体颜色丢失默认值的问题 _[`issue #346`](http://issues.autojs6.com/346)_
* `修复` console.setContentBackgroundColor 方法无法接受颜色名称参数的问题 _[`issue #384`](http://issues.autojs6.com/384)_
* `修复` README.md 中部分语言日期格式不正确的问题
* `优化` 布局分析支持控件隐藏 (by [TonyJiangWJ](https://github.com/TonyJiangWJ)) _[`pr #371`](http://pr.autojs6.com/371)_ _[`issue #355`](http://issues.autojs6.com/355)_
* `优化` 布局分析菜单使用渐变分隔线实现一定程度的功能分组
* `优化` 主题色扩充适配范围并支持更多控件类型
* `优化` 主页抽屉在横向屏幕或超宽屏幕的宽度适应性
* `优化` 关于应用与开发者页面增加水平布局及小屏布局适配

View File

@@ -24,6 +24,8 @@
* `修复` console.setContentTextColor 方法导致日志字体颜色丢失默认值的问题 _[`issue #346`](http://issues.autojs6.com/346)_
* `修复` console.setContentBackgroundColor 方法无法接受颜色名称参数的问题 _[`issue #384`](http://issues.autojs6.com/384)_
* `修复` README.md 中部分语言日期格式不正确的问题
* `优化` 布局分析支持控件隐藏 (by [TonyJiangWJ](https://github.com/TonyJiangWJ)) _[`pr #371`](http://pr.autojs6.com/371)_ _[`issue #355`](http://issues.autojs6.com/355)_
* `优化` 布局分析菜单使用渐变分隔线实现一定程度的功能分组
* `优化` 主题色扩充适配范围并支持更多控件类型
* `优化` 主页抽屉在横向屏幕或超宽屏幕的宽度适应性
* `优化` 关于应用与开发者页面增加水平布局及小屏布局适配

View File

@@ -29,7 +29,7 @@ abstract class LayoutFloatyWindow(
private val isServiceRelied: Boolean,
) : FullScreenFloatyWindow() {
protected abstract val popMenuActions: LinkedHashMap<Int, KFunction0<Unit>>
protected abstract val popMenuActions: List<Pair<Int, KFunction0<Unit>>?>
private lateinit var mServiceContext: Context
@@ -68,11 +68,21 @@ abstract class LayoutFloatyWindow(
protected fun getLayoutSelectedNode() = mLayoutSelectedNode
protected fun getBubblePopMenu(): BubblePopupMenu {
return BubblePopupMenu(mServiceContext, popMenuActions.keys.map { context.getString(it) })
val (keys, values) = popMenuActions.filterNotNull().unzip()
val dividerPositions = mutableListOf<Int>()
var realIndex = -1
for (pair in popMenuActions) {
if (pair != null) {
realIndex += 1
continue
}
dividerPositions.add(realIndex)
}
return BubblePopupMenu(mServiceContext, keys.map { context.getString(it) }, dividerPositions)
.apply {
setOnItemClickListener { _: View?, position: Int ->
dismiss()
popMenuActions.values.elementAtOrNull(position)?.invoke()
values.elementAtOrNull(position)?.invoke()
}
width = ViewGroup.LayoutParams.WRAP_CONTENT
height = ViewGroup.LayoutParams.WRAP_CONTENT
@@ -107,7 +117,8 @@ abstract class LayoutFloatyWindow(
protected fun switchWindow() {
val windows = capture.windows
val windowInfoList = windows.map { win: WindowInfo ->
WindowInfoDataSummary(win,
WindowInfoDataSummary(
win,
title = WindowInfoDataItem(context.getString(R.string.text_captured_window_info_title), win.title, context.getString(R.string.text_captured_window_info_title_null)),
order = WindowInfoOrderDataItem(context.getString(R.string.text_captured_window_info_order), win.order),
type = WindowInfoDataItem(context.getString(R.string.text_captured_window_info_type), parseWindowType(context, win.type), context.getString(R.string.text_captured_window_info_type_unknown)),
@@ -129,7 +140,6 @@ abstract class LayoutFloatyWindow(
}
}
protected fun excludeNode() {
mLayoutSelectedNode?.let {
it.hidden = true
@@ -137,10 +147,18 @@ abstract class LayoutFloatyWindow(
}
}
protected fun excludeAllBoundsSameNode(layoutBoundsView: LayoutBoundsView ) {
protected fun excludeAllBoundsSameNode(layoutBoundsView: LayoutBoundsView) {
mLayoutSelectedNode?.let {
layoutBoundsView.hideAllBoundsSameNode(it)
mLayoutSelectedNode = null
}
}
companion object {
@JvmStatic
protected val SPLIT_LINE: Nothing? = null
}
}

View File

@@ -22,13 +22,15 @@ open class LayoutBoundsFloatyWindow @JvmOverloads constructor(
private lateinit var mLayoutBoundsView: LayoutBoundsView
override val popMenuActions = linkedMapOf(
override val popMenuActions = listOf(
R.string.text_show_widget_information to ::showNodeInfo,
R.string.text_show_layout_hierarchy to ::showLayoutHierarchy,
R.string.text_generate_code to ::generateCode,
R.string.text_switch_window to ::switchWindow,
SPLIT_LINE,
R.string.text_hide_node to ::excludeNode,
R.string.text_hide_same_frame_nodes to ::excludeAllBoundsSameNode,
R.string.text_hide_same_frame_nodes to ::excludeAllBoundsSameNodeInternal,
SPLIT_LINE,
R.string.text_switch_window to ::switchWindow,
R.string.text_exit to ::close,
)
@@ -71,7 +73,8 @@ open class LayoutBoundsFloatyWindow @JvmOverloads constructor(
}
}
private fun excludeAllBoundsSameNode() {
private fun excludeAllBoundsSameNodeInternal() {
excludeAllBoundsSameNode(mLayoutBoundsView)
}
}

View File

@@ -22,10 +22,11 @@ open class LayoutHierarchyFloatyWindow @JvmOverloads constructor(
private lateinit var mLayoutHierarchyView: LayoutHierarchyView
override val popMenuActions = linkedMapOf(
override val popMenuActions = listOf(
R.string.text_show_widget_information to ::showNodeInfo,
R.string.text_show_layout_bounds to ::showLayoutBounds,
R.string.text_generate_code to ::generateCode,
SPLIT_LINE,
R.string.text_switch_window to ::switchWindow,
R.string.text_exit to ::close,
)

View File

@@ -1,22 +1,29 @@
package org.autojs.autojs.ui.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import org.autojs.autojs.util.ColorUtils;
import org.autojs.autojs.util.DisplayUtils;
import org.autojs.autojs6.R;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Created by Stardust on May 23, 2017.
* Modified by SuperMonster003 as of Mar 20, 2022.
*/
public class BubblePopupMenu extends PopupWindow {
@@ -29,11 +36,18 @@ public class BubblePopupMenu extends PopupWindow {
private final View mLittleTriangle;
public BubblePopupMenu(Context context, List<String> options) {
this(context, options, null);
}
public BubblePopupMenu(Context context, List<String> options, List<Integer> dividerPositions) {
super(context);
View view = View.inflate(context, R.layout.bubble_popup_menu, null);
mLittleTriangle = view.findViewById(R.id.little_triangle);
mRecyclerView = view.findViewById(R.id.list);
mRecyclerView.setAdapter(new SimpleRecyclerViewAdapter<>(R.layout.bubble_popup_menu_item, options, MenuItemViewHolder::new));
if (dividerPositions != null && !dividerPositions.isEmpty()) {
mRecyclerView.addItemDecoration(new DividerDecoration(context, dividerPositions, 5f, 0.64f, 20f));
}
setContentView(view);
setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
setOutsideTouchable(true);
@@ -89,4 +103,91 @@ public class BubblePopupMenu extends PopupWindow {
}
}
}
private static class DividerDecoration extends RecyclerView.ItemDecoration {
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final int mLineHeight;
private final int mMarginTop;
private final int mMarginBottom;
private final int mFadeWidth;
private final List<Integer> mPositions;
DividerDecoration(Context ctx,
List<Integer> positions,
float marginDp,
float thicknessDp,
float fadeWidthDp) {
mPositions = positions;
mMarginTop = (int) DisplayUtils.dpToPx(marginDp);
mMarginBottom = (int) DisplayUtils.dpToPx(marginDp);
mLineHeight = (int) DisplayUtils.dpToPx(thicknessDp);
mFadeWidth = (int) DisplayUtils.dpToPx(fadeWidthDp);
mPaint.setColor(ctx.getColor(R.color.divider_lighter_night_day));
mPaint.setStyle(Paint.Style.FILL);
}
@Override
public void onDrawOver(@NotNull Canvas canvas,
RecyclerView parent,
RecyclerView.@NotNull State state) {
int childCnt = parent.getChildCount();
int leftPad = parent.getPaddingLeft();
int rightPad = parent.getPaddingRight();
int widthAll = parent.getWidth() - leftPad - rightPad;
if (widthAll <= 0) return;
// 按当前宽度创建一次渐变 Shader.
int solidColor = mPaint.getColor();
LinearGradient shader = new LinearGradient(
leftPad, 0,
leftPad + widthAll, 0,
new int[]{
ColorUtils.applyAlpha(solidColor, 0),
solidColor,
solidColor,
ColorUtils.applyAlpha(solidColor, 0)
},
new float[]{
0f,
(float) mFadeWidth / widthAll,
1f - (float) mFadeWidth / widthAll,
1f
},
Shader.TileMode.CLAMP
);
mPaint.setShader(shader);
for (int i = 0; i < childCnt; i++) {
View child = parent.getChildAt(i);
int pos = parent.getChildAdapterPosition(child);
if (mPositions.contains(pos)) {
float top = child.getBottom() + mMarginTop;
float bottom = top + mLineHeight;
canvas.drawRect(leftPad,
top,
parent.getWidth() - rightPad,
bottom,
mPaint);
}
}
// 清理 shader, 防止影响 RecyclerView 复用.
mPaint.setShader(null);
}
@Override
public void getItemOffsets(@NotNull Rect outRect,
@NotNull View view,
RecyclerView parent,
RecyclerView.@NotNull State state) {
if (mPositions.contains(parent.getChildAdapterPosition(view))) {
outRect.bottom = mMarginTop + mLineHeight + mMarginBottom;
}
}
}
}

View File

@@ -38,6 +38,8 @@
<color name="item_background_dark">@color/dawn_full</color>
<color name="divider">#191919</color>
<color name="divider_night_day">#F2F3F5</color>
<color name="divider_lighter_night_day">#808080</color>
<color name="divider_functions_keyboard">#303030</color>
<color name="divider_app_settings_list">#737B8A</color>

View File

@@ -117,6 +117,8 @@
<color name="item_background_dark">#FAFAFA</color>
<color name="divider">#F2F3F5</color>
<color name="divider_night_day">#191919</color>
<color name="divider_lighter_night_day">#999999</color>
<color name="divider_functions_keyboard">#F0F0F0</color>
<color name="divider_app_settings_list">#F3F5F9</color>