diff --git a/app/build.gradle b/app/build.gradle index 6f07b0f3..2913178e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -78,21 +78,39 @@ dependencies { exclude group: 'com.android.support', module: 'support-annotations' }) testCompile 'junit:junit:4.12' + // LeakCanary (a memory leak tracer) debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' + // Storio (Sqlite api library) annotationProcessor 'com.pushtorefresh.storio:sqlite-annotations-processor:1.12.3' compile 'com.pushtorefresh.storio:sqlite-annotations:1.12.3' + // Android Annotations + annotationProcessor "org.androidannotations:androidannotations:$AAVersion" + compile "org.androidannotations:androidannotations-api:$AAVersion" + // ButterKnife + compile 'com.jakewharton:butterknife:8.6.0' + annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0' + // Android supports compile 'com.android.support:appcompat-v7:25.3.0' - compile 'com.android.support:design:25.1.0' + compile 'com.android.support:design:25.3.0' + compile 'com.android.support:multidex:1.0.1' + // Personal libraries compile 'com.github.hyb1996:MutableTheme:0.2.2' + compile 'com.github.hyb1996:EnhancedFloaty:0.17' + // Material Dialogs compile 'com.afollestad.material-dialogs:core:0.9.2.3' + // Gson compile 'com.google.code.gson:gson:2.8.0' + // Common Markdown compile 'com.github.atlassian:commonmark-java:commonmark-parent-0.9.0' + // AlipayZeroSdk compile 'moe.feng:AlipayZeroSdk:1.1' + // Console compile 'com.jraska:console:0.4.3' + // Android issue reporter (a github issue reporter) compile 'com.heinrichreimersoftware:android-issue-reporter:1.3.1' - compile 'de.codecrafters.tableview:tableview:2.5.0' + // compile group: "pl.openrnd.android", name: "multi-level-listview", version: "1.0.1" compile 'de.psdev.licensesdialog:licensesdialog:1.8.1' compile 'io.mattcarroll.hover:hover:0.9.7' @@ -101,10 +119,8 @@ dependencies { // Tasker Plugin compile group: 'com.twofortyfouram', name: 'android-plugin-client-sdk-for-locale', version: '[4.0.2, 5.0[' compile 'com.android.volley:volley:1.0.0' - compile 'com.github.hyb1996:EnhancedFloaty:0.17' compile 'com.flurry.android:analytics:7.0.0@aar' compile 'com.pushtorefresh.storio:sqlite:1.12.3' - compile 'com.android.support:multidex:1.0.1' // Terminal emulator compile(name: 'libtermexec-release', ext: 'aar') compile(name: 'emulatorview-release', ext: 'aar') diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/HoverMenuService.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/HoverMenuService.java index 78833769..51b863b2 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/HoverMenuService.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/HoverMenuService.java @@ -88,6 +88,7 @@ public class HoverMenuService extends Service { private WindowViewController mWindowViewController; + private ContextThemeWrapper mThemeWrapper; private FloatingLayoutHierarchyView mFloatingLayoutHierarchyView; private FloatingLayoutBoundsView mFloatingLayoutBoundsView; @@ -121,15 +122,16 @@ public class HoverMenuService extends Service { } private void initViews() { - mFloatingLayoutHierarchyView = new FloatingLayoutHierarchyView(this); - mFloatingLayoutBoundsView = new FloatingLayoutBoundsView(this); + mThemeWrapper = new ContextThemeWrapper(this, R.style.AppTheme); + mFloatingLayoutHierarchyView = new FloatingLayoutHierarchyView(mThemeWrapper); + mFloatingLayoutBoundsView = new FloatingLayoutBoundsView(mThemeWrapper); initWindowMenu(); mWindowViewController.addView(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, true, mFloatingLayoutHierarchyView); mWindowViewController.addView(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, true, mFloatingLayoutBoundsView); } private void initWindowMenu() { - mWindowHoverMenu = (WindowHoverMenu) new HoverMenuBuilder(new ContextThemeWrapper(this, R.style.AppTheme)) + mWindowHoverMenu = (WindowHoverMenu) new HoverMenuBuilder(mThemeWrapper) .displayWithinWindow() .useAdapter(new HoverMenuAdapter(this)) .restoreVisualState(loadPreferredLocation()) diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/NodeInfo.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/NodeInfo.java index dbf9795c..8577e02a 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/NodeInfo.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/NodeInfo.java @@ -18,15 +18,27 @@ import java.util.List; public class NodeInfo { private List children = new ArrayList<>(); + private Rect mBoundsInScreen; public String id; - public CharSequence contentDesc, className, packageName, text; + public CharSequence contentDesc; + public CharSequence className; + public CharSequence packageName; + public CharSequence text; public int drawingOrder; - public boolean accessibilityFocused, checked, clickable, contextClickable, dismissable, editable, enabled, - focusable, longClickable, selected, scrollable, visibleToUser; + public boolean accessibilityFocused; + public boolean checked; + public boolean clickable; + public boolean contextClickable; + public boolean dismissable; + public boolean editable; + public boolean enabled; + public boolean focusable; + public boolean longClickable; + public boolean selected; + public boolean scrollable; public String bounds; - private Rect mBoundsInScreen; public NodeInfo(AccessibilityNodeInfoCompat node) { id = simplifyId(node.getViewIdResourceName()); @@ -48,8 +60,6 @@ public class NodeInfo { longClickable = node.isLongClickable(); selected = node.isSelected(); scrollable = node.isScrollable(); - visibleToUser = node.isVisibleToUser(); - mBoundsInScreen = new Rect(); node.getBoundsInScreen(mBoundsInScreen); bounds = boundsToString(mBoundsInScreen); diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutInspectView.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutInspectView.java deleted file mode 100644 index ed7af408..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/LayoutInspectView.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view; - -import android.content.Context; -import android.os.Build; -import android.support.annotation.AttrRes; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.annotation.RequiresApi; -import android.support.annotation.StyleRes; -import android.util.AttributeSet; -import android.view.View; -import android.widget.FrameLayout; -import android.widget.ViewSwitcher; - -import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.NodeInfo; - -/** - * Created by Stardust on 2017/3/10. - */ - -public class LayoutInspectView extends FrameLayout { - - private ViewSwitcher mViewSwitcher; - private NodeInfoView mNodeInfoView; - private LayoutHierarchyView mLayoutBoundsView; - private View mCurrentView; - - public LayoutInspectView(@NonNull Context context) { - super(context); - init(); - } - - public LayoutInspectView(@NonNull Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - init(); - } - - public LayoutInspectView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { - super(context, attrs, defStyleAttr); - init(); - } - - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - public LayoutInspectView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - init(); - } - - private void init() { - inflate(getContext(), R.layout.floating_window_expand, this); - mNodeInfoView = (NodeInfoView) findViewById(R.id.node_info); - mLayoutBoundsView = (LayoutHierarchyView) findViewById(R.id.bounds_view); - mViewSwitcher = (ViewSwitcher) findViewById(R.id.view_switcher); - mCurrentView = mNodeInfoView; - mLayoutBoundsView.setOnNodeInfoLongClickListener(new OnNodeInfoSelectListener() { - @Override - public void onNodeSelect(NodeInfo info) { - mNodeInfoView.setNodeInfo(info); - showNodeInfoView(); - } - }); - } - - public void showNodeInfoView() { - if (mCurrentView != mNodeInfoView) { - mViewSwitcher.showPrevious(); - mCurrentView = mNodeInfoView; - } - } - - public boolean isLayoutBoundsViewShowing() { - return mCurrentView == mLayoutBoundsView; - } - - public boolean isNodeInfoViewShowing() { - return mCurrentView == mNodeInfoView; - } - - public void backToLayoutBoundsView() { - if (mCurrentView != mLayoutBoundsView) { - mViewSwitcher.showNext(); - mCurrentView = mLayoutBoundsView; - } - } -} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/NodeInfoView.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/NodeInfoView.java index b63bf272..de39a963 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/NodeInfoView.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/view/NodeInfoView.java @@ -1,9 +1,11 @@ package com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.view; import android.content.Context; -import android.graphics.Color; import android.support.annotation.Nullable; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; @@ -12,23 +14,67 @@ import android.widget.Toast; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.external.floatingwindow.menu.layout_inspector.NodeInfo; import com.stardust.util.ClipboardUtil; +import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; import java.lang.reflect.Field; +import java.util.Arrays; -import de.codecrafters.tableview.TableDataAdapter; -import de.codecrafters.tableview.TableView; -import de.codecrafters.tableview.model.TableColumnWeightModel; -import de.codecrafters.tableview.toolkit.SimpleTableDataAdapter; -import de.codecrafters.tableview.toolkit.TableDataRowBackgroundProviders; +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; +import butterknife.OnLongClick; +import butterknife.Optional; /** * Created by Stardust on 2017/3/10. */ -public class NodeInfoView extends TableView { +public class NodeInfoView extends RecyclerView { - private static final Field[] fields = NodeInfo.class.getFields(); - private String[][] mData = new String[fields.length][2]; + private static final String[] FIELD_NAMES = {"id", + "bounds", + "contentDesc", + "className", + "packageName", + "text", + "drawingOrder", + "accessibilityFocused", + "checked", + "clickable", + "contextClickable", + "dismissable", + "editable", + "enabled", + "focusable", + "longClickable", + "selected", + "scrollable", + }; + private static final Field[] FIELDS = new Field[FIELD_NAMES.length]; + + static { + Arrays.sort(FIELD_NAMES); + for (int i = 0; i < FIELD_NAMES.length; i++) { + try { + FIELDS[i] = NodeInfo.class.getField(FIELD_NAMES[i]); + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } + } + } + + private String[][] mData = new String[FIELDS.length + 1][2]; + private OnLongClickListener itemLongClickListener = new OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + int pos = getChildAdapterPosition(v); + if (pos < 1 || pos >= mData.length) + return false; + ClipboardUtil.setClip(getContext(), mData[pos][0] + " = " + mData[pos][1]); + Toast.makeText(getContext(), R.string.text_copy_to_clip, Toast.LENGTH_SHORT).show(); + return true; + } + }; public NodeInfoView(Context context) { super(context); @@ -46,67 +92,88 @@ public class NodeInfoView extends TableView { } public void setNodeInfo(NodeInfo nodeInfo) { - for (int i = 0; i < fields.length; i++) { + for (int i = 1; i < FIELD_NAMES.length; i++) { try { - Object value = fields[i].get(nodeInfo); - mData[i][1] = value == null ? "null" : value.toString(); + Object value = FIELDS[i - 1].get(nodeInfo); + mData[i][1] = value == null ? "" : value.toString(); } catch (Exception e) { throw new RuntimeException(e); } } - getDataAdapter().notifyDataSetChanged(); + getAdapter().notifyDataSetChanged(); } private void init() { initData(); - setUpTableConfig(); - setAdapter(); - setUpStyle(); - } - - private void setAdapter() { - setDataAdapter(new TableDataAdapter(getContext(), mData) { - SimpleTableDataAdapter mSimpleTableDataAdapter = new SimpleTableDataAdapter(getContext(), mData); - - @Override - public View getCellView(int rowIndex, int columnIndex, ViewGroup parentView) { - final TextView textView = (TextView) mSimpleTableDataAdapter.getCellView(rowIndex, columnIndex, parentView); - textView.setSingleLine(false); - textView.setMaxLines(3); - textView.setTextColor(0xcc000000); - textView.setTextIsSelectable(true); - textView.setOnLongClickListener(new OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - ClipboardUtil.setClip(getContext(), textView.getText()); - Toast.makeText(getContext(), R.string.text_already_copy_to_clip, Toast.LENGTH_SHORT).show(); - return true; - } - - }); - return textView; - } - }); - } - - private void setUpTableConfig() { - setColumnCount(2); - setColumnModel(new TableColumnWeightModel(2)); + setAdapter(new Adapter()); + setLayoutManager(new LinearLayoutManager(getContext())); + addItemDecoration(new HorizontalDividerItemDecoration.Builder(getContext()) + .color(0x1e000000) + .size(2) + .build()); } private void initData() { - for (int i = 0; i < mData.length; i++) { - mData[i][0] = fields[i].getName(); + mData[0][0] = getResources().getString(R.string.text_attribute); + mData[0][1] = getResources().getString(R.string.text_value); + for (int i = 1; i < mData.length; i++) { + mData[i][0] = FIELD_NAMES[i - 1]; mData[i][1] = ""; } } - private void setUpStyle() { - int colorEvenRows = Color.WHITE; - int colorOddRows = 0xffe7e7e7; - setDataRowBackgroundProvider(TableDataRowBackgroundProviders.alternatingRowColors(colorEvenRows, colorOddRows)); - getChildAt(0).setVisibility(GONE); + private class Adapter extends RecyclerView.Adapter { + + final int VIEW_TYPE_HEADER = 0; + final int VIEW_TYPE_ITEM = 1; + + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + int layoutRes = viewType == VIEW_TYPE_HEADER ? R.layout.node_info_view_header : R.layout.node_info_view_item; + return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(layoutRes, parent, false)); + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + holder.attrName.setText(mData[position][0]); + holder.attrValue.setText(mData[position][1]); + } + + @Override + public int getItemCount() { + return mData.length; + } + + @Override + public int getItemViewType(int position) { + return position == 0 ? VIEW_TYPE_HEADER : VIEW_TYPE_ITEM; + } } + class ViewHolder extends RecyclerView.ViewHolder { + + + @BindView(R.id.name) + TextView attrName; + + @BindView(R.id.value) + TextView attrValue; + + public ViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + + @Optional + @OnClick(R.id.item) + void onItemClick() { + int pos = getAdapterPosition(); + if (pos < 1 || pos >= mData.length) + return; + ClipboardUtil.setClip(getContext(), mData[pos][0] + " = " + mData[pos][1]); + Toast.makeText(getContext(), R.string.text_already_copy_to_clip, Toast.LENGTH_SHORT).show(); + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutBoundsView.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutBoundsView.java index cacbe015..21cbe5ec 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutBoundsView.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutBoundsView.java @@ -51,9 +51,10 @@ public class FloatingLayoutBoundsView extends LayoutBoundsView { mNodeInfoView = new NodeInfoView(getContext()); mNodeInfoDialog = new MaterialDialog.Builder(getContext()) .customView(mNodeInfoView, false) + .backgroundColor(0xddffffff) .theme(Theme.LIGHT) .build(); - mNodeInfoDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); + mNodeInfoDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE); } } diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutHierarchyView.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutHierarchyView.java index 701ab41c..a0fd5294 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutHierarchyView.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/view/FloatingLayoutHierarchyView.java @@ -57,7 +57,7 @@ public class FloatingLayoutHierarchyView extends LayoutHierarchyView { .theme(Theme.LIGHT) .build(); if (mNodeInfoDialog.getWindow() != null) - mNodeInfoDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); + mNodeInfoDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE); } } diff --git a/app/src/main/res/anim/item_hover.xml b/app/src/main/res/anim/item_hover.xml new file mode 100644 index 00000000..1110605d --- /dev/null +++ b/app/src/main/res/anim/item_hover.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/floating_window_expand.xml b/app/src/main/res/layout/floating_window_expand.xml deleted file mode 100644 index b90bda5c..00000000 --- a/app/src/main/res/layout/floating_window_expand.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/node_info_view_header.xml b/app/src/main/res/layout/node_info_view_header.xml new file mode 100644 index 00000000..7a62c43c --- /dev/null +++ b/app/src/main/res/layout/node_info_view_header.xml @@ -0,0 +1,23 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/node_info_view_item.xml b/app/src/main/res/layout/node_info_view_item.xml new file mode 100644 index 00000000..93231b84 --- /dev/null +++ b/app/src/main/res/layout/node_info_view_item.xml @@ -0,0 +1,26 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a1b99127..f8adc9fa 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -184,6 +184,8 @@ 服务器地址 声明 关于项目与开发者 + 属性 +