diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0b0670e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+*.iml
+/.gradle
+/local.properties
+/.idea
+/key
+/material
+/supersearch/build
+/entry/build
+/supersearch/upload.gradle
+/supersearch/gradle.properties
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+/entry/.preview
+.cxx
+/node_modules
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7ba1250
--- /dev/null
+++ b/README.md
@@ -0,0 +1,319 @@
+## SuperSearch
+
+### 项目介绍
+
+一个开源的ohos Java 库,旨在简化多终端搜索相关功能的实现。
+
+### 功能列表
+
+1. 支持模糊匹配以及精确匹配
+2. 支持开启、关闭搜索记录
+3. 自带搜索算法
+4. 支持超多功能自定义
+5. 代码高可扩展性
+6. 支持多设备使用
+7. 支持开箱即用
+
+### 安装教程
+
+- 方法一:
+
+使用前需先导入SuperSearch依赖,并在所对应的模块build.gradle中添加依赖
+
+```groovy
+allprojects {
+ repositories {
+ mavenCentral()
+ }
+}
+...
+dependencies {
+ ...
+ implementation 'top.xuegao-tzx:SuperSearch:1.2.3.517'
+ ...
+}
+```
+
+- 方式二:
+
+1. 下载模块代码添加到自己的工程
+2. 关联使用
+
+```
+dependencies {
+ implementation project(":supersearch")
+ ……
+}
+```
+
+
+### 使用说明
+
+#### - 添加SuperSearch
+
+##### 1. 加载动画(一个加载中的圆圈)
+
+```xml
+
+
+
+ app:round_progress_color="#FF82F8EF"
+
+ app:round_progress_with="5f"
+```
+
+##### 2. 搜索框
+
+###### 通过 XML 进行定制
+
+```xml
+
+
+
+ app:isDebugEnabled="true"
+
+ app:isWearable="true"
+
+
+ app:background_mask_degree="0.3f"
+
+ app:background_mask_color="#FFADEA6C"
+
+ app:queryRadius="5vp"
+
+ app:suggestion_count="6"
+
+ app:search_history="$graphic:ic_history_black"
+
+ app:delete_search_history="$graphic:ic_close"
+
+ app:queryInput_cursor_color="#FF8377FF"
+
+ app:queryInput_hint_color="#FFFF0000"
+
+ app:queryInput_hint_text="$string:search_hint_text"
+
+ app:queryInput_text_color="#FF000000"
+
+ app:queryInput_background_color="#FFF8F3EC"
+
+ app:queryInput_buttom_color="#A18770B1"
+
+ app:rightButton="$graphic:ic_filters"
+
+ app:rightButton_Clear="$graphic:ic_close"
+
+ app:isrightButton_ClearEnabled="true"
+
+ app:leftButton_Loadding_color="#FF1300FF"
+
+ app:leftButton_Back="$graphic:ic_arrow_left"
+
+
+ app:nullWarnByMySelf="true"
+
+ app:null_warn_text="$string:search_input_null"
+
+ app:null_warn_text_color="#FFFF006E"
+
+
+ app:noneWarnByMySelf="true"
+
+ app:none_warn_text="$string:search_answer_none"
+
+ app:none_warn_text_color="#FFFF003B"
+```
+
+###### 通过 Java 代码进行辅助定制
+
+```java
+ 1. 定义方式1
+ private void initView() {
+ SearchView sv;
+ sv = (SearchView) findComponentById(ResourceTable.Id_searchView);//根据id获取控件
+ sv.Onsearch(getContext(),//获取所在能力的context
+ (ListContainer) findComponentById(ResourceTable.Id_ListContainer),//根据id获取并绑定结果列表展示控件
+ sv,//根据id绑定控件
+ findComponentById(ResourceTable.Id_emptyView),//根据id获取并绑定背景展示控件
+ (com.xcl.supersearch.RoundProgressBar) findComponentById(ResourceTable.Id_progressBar),//根据id获取并绑定背景Loading加载动画控件
+ getSearch(),//传入搜索的数据
+ getSuggection(),//传入搜索建议的数据,如果不配置这个,则不会自带搜索建议
+ true);//是否开启搜索建议
+ }
+ //注意:搜索建议如果无需开启,可以不配置最后2项;如开启搜索建议,倒数第2项也可有可无
+ private List getSearch(){
+ List list = new ArrayList<>();
+ list.add(new SRContactor("zhtzx5", "clsths2"));//支持只传标题、信息,此时后面4个按钮默认不显示
+ list.add(new SRContactor("zhng", "cl1", null, ",2u", "3g", "7n7"));//支持传null,此时传null的将不会显示
+ list.add(new SRContactor("zhxcl5", null));//支持只传标题,同时传null,此时后面4个按钮和信息不显示
+ //TODO:注意:第一个不可为null
+ list.add(new SRContactor("zhags", "clhhs1", "1操", "2", "3码", "47"));//支持传入全部信息
+ return list;
+ }
+ private List getSuggection() {
+ List list = new ArrayList<>();
+ list.add(new SHistoryContactor("小草林", ResourceTable.Media_ic_history_black_24dp, -3));//这里-3代表根据默认图标或xml中配置的图标显示
+ list.add(new SHistoryContactor("TEST", ResourceTable.Media_ic_history_black_24dp, -1));//这里-1代表根据不显示图标
+ list.add(new SHistoryContactor("测试", -1, ResourceTable.Media_ic_close_black_24dp));
+ list.add(new SHistoryContactor("test"));//可以只配置建议信息,会自动根据默认图标或xml中配置的图标显示
+ return list;
+ }
+
+ 2. 定义方式2
+ sv.setContext(getContext())//设置所在能力的context
+ .setRoundProgressBar((com.xcl.supersearch.RoundProgressBar) findComponentById(ResourceTable.Id_progressBar))//设置背景Loading加载动画控件
+ .setSearchView(sv)//设置搜索控件
+ .setSRListContainer(getSearch())//传入搜索的数据
+ .setSuggestionisShow(true)//设置是否开启搜索建议
+ .setSuggestionList(getSuggection())//设置搜索建议的数据
+ .setBackComponent(findComponentById(ResourceTable.Id_emptyView))//设置背景展示控件
+ .setListContainer((ListContainer) findComponentById(ResourceTable.Id_ListContainer))//设置结果列表展示控件
+ .Builder();//执行构造
+
+ -----------------------------一下方法2种构造均一样-----------------------------------
+ sv.setCustomListener(new SearchView.CustomListener() {
+ @Override
+ public void onFilter(String filter) {
+ //TODO:右上角的按钮事件
+ }
+ });
+ sv.setBt1Listener(new SearchView.Bt1Listener() {
+ @Override
+ public void onbT1(int position) {
+ Utils.error(label,"点击了按钮1,其的行号为:"+position+1);
+ //TODO:一行列表第一个的按钮事件
+ }
+ });
+ //依次类推,此处省略其他3个按钮事件
+ sv.setBackClickListener(new SearchView.BackClickListener() {
+ @Override
+ public void onBackClick() {
+ terminate();
+ //TODO:左上角的按钮事件
+ }
+ });
+ sv.setNullWarnListener(new SearchView.NullWarnListener(){
+ @Override
+ public void onNullError() {
+ Utils.error(label, "空搜索警告1");
+ //TODO:支持自定义空搜索警告
+ }
+ });
+ sv.setNoneWarnListener(new SearchView.NoneWarnListener(){
+ @Override
+ public void onNullWarn() {
+ Utils.error(label, "空结果警告1");
+ //TODO:支持自定义空结果警告
+ }
+ });
+```
+
+#### - 使用ImageTracerJava工具
+
+> 参考项目地址: 我的另一个开源项目[ImageTracerJava](https://gitee.com/xuegao-tzx/ImageTracerJava)
+
+1. 在entry/src/test目录下的java文件中含有ImageTracerJava工具的使用示例,可以将图片转换成svg图片,再通过DevEco Studio自带的svg转xml即可将图片资源从media转到graphic中
+2. 使用前需先导入ImageTracerJava工具,并在build.gradle中添加依赖
+
+```groovy
+allprojects {
+ repositories {
+ mavenCentral()
+ }
+}
+...
+dependencies {
+ ...
+ implementation 'top.xuegao-tzx:ImageTracerJava:1.1.4.516'
+ ...
+}
+```
+
+3. 使用示例如下
+
+```java
+ // Options
+ HashMap options = new HashMap();
+ // Tracing
+ options.put("ltres",1f);
+ options.put("qtres",1f);
+ options.put("pathomit",8f);
+ // Color quantization
+ options.put("colorsampling",1f); // 1f means true ; 0f means false: starting with generated palette
+ options.put("numberofcolors",16f);
+ options.put("mincolorratio",0.02f);
+ options.put("colorquantcycles",3f);
+ // SVG rendering
+ options.put("scale",1f);
+ options.put("roundcoords",1f); // 1f means rounded to 1 decimal places, like 7.3 ; 3f means rounded to 3 places, like 7.356 ; etc.
+ options.put("lcpr",0f);
+ options.put("qcpr",0f);
+ options.put("desc",1f); // 1f means true ; 0f means false: SVG descriptions deactivated
+ options.put("viewbox",0f); // 1f means true ; 0f means false: fixed width and height
+ // Selective Gauss Blur
+ options.put("blurradius",0f); // 0f means deactivated; 1f .. 5f : blur with this radius
+ options.put("blurdelta",20f); // smaller than this RGB difference will be blurred
+ // Palette
+ // This is an example of a grayscale palette
+ // please note that signed byte values [ -128 .. 127 ] will be converted to [ 0 .. 255 ] in the getsvgstring function
+ //下方的两个数字16请参照实际图片动态调整以实现最佳效果
+ byte[][] palette = new byte[16][4];
+ for(int colorcnt=0; colorcnt < 16; colorcnt++){
+ palette[colorcnt][0] = (byte)( -128 + colorcnt * 32); // R
+ palette[colorcnt][1] = (byte)( -128 + colorcnt * 32); // G
+ palette[colorcnt][2] = (byte)( -128 + colorcnt * 32); // B
+ palette[colorcnt][3] = (byte)127; // A
+ }
+
+ ImageTracer.saveString(
+ "src\\main\\resources\\base\\media\\ic_close_black_24dp.svg" ,
+ ImageTracer.imageToSVG("src\\main\\resources\\base\\media\\ic_close_black_24dp.png",options,palette)
+ );
+```
+
+### 版本迭代
+
+- v1.2.3.517
+
+## License(许可证)
+
+作者:田梓萱 SuperSearch 在 [AGPL V3.0 License](https://www.gnu.org/licenses/agpl-3.0.txt) 下获得许可
+
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..fe4c010
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,40 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
+ohos {
+ //签名信息
+ compileSdkVersion 6
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://repo.huaweicloud.com/repository/maven/'
+ allowInsecureProtocol = true
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ allowInsecureProtocol = true
+ }
+ mavenCentral()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:3.0.5.2'
+ classpath 'com.huawei.ohos:decctest:1.2.7.2'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://repo.huaweicloud.com/repository/maven/'
+ allowInsecureProtocol = true
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ allowInsecureProtocol = true
+ }
+ mavenCentral()
+ }
+}
diff --git a/entry/build.gradle b/entry/build.gradle
new file mode 100644
index 0000000..b4f4a89
--- /dev/null
+++ b/entry/build.gradle
@@ -0,0 +1,36 @@
+apply plugin: 'com.huawei.ohos.hap'
+apply plugin: 'com.huawei.ohos.decctest'
+//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
+ohos {
+ compileSdkVersion 6
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+ buildTypes {
+ release {
+ proguardOpt {
+ proguardEnabled false
+ rulesFiles 'proguard-rules.pro'
+ }
+ }
+ debug {
+ proguardOpt {
+ proguardEnabled true
+ rulesFiles 'proguard-rules.pro'
+ }
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ //testImplementation files('../libs/ImageTracer.jar')
+ testImplementation 'top.xuegao-tzx:ImageTracerJava:1.1.4.516'
+ testImplementation 'junit:junit:4.13.1'
+ ohosTestImplementation 'com.huawei.ohos.testkit:runner:2.0.0.200'
+ //implementation project(":supersearch")
+ implementation 'top.xuegao-tzx:SuperSearch:1.2.3.517'
+}
+decc {
+ supportType = ['html', 'xml']
+}
diff --git a/entry/proguard-rules.pro b/entry/proguard-rules.pro
new file mode 100644
index 0000000..9ead980
--- /dev/null
+++ b/entry/proguard-rules.pro
@@ -0,0 +1,76 @@
+# config module specific ProGuard rules here.
+-dontwarn
+# 代码混淆压缩比,在0~7之间
+-optimizationpasses 15
+# 混合时不使用大小写混合,混合后的类名为小写
+-dontusemixedcaseclassnames
+# 在读取依赖的库文件时,不要略过那些非public类成员
+-dontskipnonpubliclibraryclassmembers
+# 指定不去忽略非公共库的类
+-dontskipnonpubliclibraryclasses
+# 不做预校验,preverify是proguard的四个步骤之一,去掉这一步能够加快混淆速度。
+-dontpreverify
+-verbose
+# google推荐算法
+-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
+#-dontoptimize#注意在上传时配置,本地无需配置
+# 保留注解、内部类、泛型、匿名类
+-keepattributes *Annotation*,Exceptions,InnerClasses,Signature,EnclosingMethod
+# 重命名抛出异常时的文件名称
+-renamesourcefileattribute SourceFile
+# 抛出异常时保留代码行号
+-keepattributes SourceFile,LineNumberTable
+-dontwarn javax.annotation.**
+# 保留本地native方法不被混淆
+-keepclasseswithmembernames,allowshrinking class * {
+native ;
+}
+# 保留枚举类不被混淆
+-keepclassmembers enum * {
+public static **[] values();
+public static ** valueOf(java.lang.String);
+}
+# 保留自定义类
+-keep enum com.xcl.supersearch.**
+-keep class com.xcl.supersearch.**{*;}
+-keep class com.xcl.supersearch.**
+-keepclassmembers enum com.xcl.supersearch.**{*;}
+-keep interface com.xcl.supersearch.**
+# 忽略继承
+-keepclassmembers class * implements java.io.Serializable {
+ static final long serialVersionUID;
+ private static final java.io.ObjectStreamField[] serialPersistentFields;
+ private void writeObject(java.io.ObjectOutputStream);
+ private void readObject(java.io.ObjectInputStream);
+ java.lang.Object writeReplace();
+ java.lang.Object readResolve();
+}
+# 保留HMS相关接入[AnalyticsKit SDK和依赖SDK的混淆配置]
+-ignorewarnings
+-repackageclasses
+-keep class com.huawei.agconnect.**{*;}
+-keep class com.huawei.hms.analytics.**{*;}
+-keep class com.huawei.hms.push.**{*;}
+-keep class com.huawei.hms.**{*;}
+# HMS接口服务
+-keepattributes Exceptions
+-keep interface com.huawei.hms.analytics.type.HAEventType{*;}
+-keep interface com.huawei.hms.analytics.type.HAParamType{*;}
+-keep class com.huawei.hms.analytics.HiAnalyticsInstance{*;}
+-keep class com.huawei.hms.analytics.HiAnalytics{*;}
+-keep class com.huawei.hianalytics.**{*;}
+-keep class com.huawei.updatesdk.**{*;}
+-keep class com.huawei.harmony.**{*;}
+-keep class com.huawei.mylibrary.**{*;}
+# 保留HarmonyOS应用/服务入口类
+-keep public class * extends *.aafwk.ability.Ability
+-keep public class * extends *.ace.ability.AceAbility
+-keep public class * extends *.aafwk.ability.AbilitySlice
+-keep public class * extends *.aafwk.ability.AbilityPackage
+-dontwarn java.lang.invoke.**
+-dontwarn javax.naming.**
+-dontwarn ohos.utils.PacMap.**
+-keep class **.ResourceTable$* {*;}
+-keepattributes Signature, InnerClasses, EnclosingMethod, Exceptions
+# 保留配置文件
+-printmapping mapping.txt
\ No newline at end of file
diff --git a/entry/src/main/config.json b/entry/src/main/config.json
new file mode 100644
index 0000000..a452e08
--- /dev/null
+++ b/entry/src/main/config.json
@@ -0,0 +1,69 @@
+{
+ "app": {
+ "bundleName": "com.xcl.studyt",
+ "vendor": "tzx",
+ "version": {
+ "code": 1000000,
+ "name": "1.0.0"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.xcl.search.test",
+ "name": ".MyApplication",
+ "mainAbility": "com.xcl.search.test.MainAbility",
+ "deviceType": [
+ "phone",
+ "tablet",
+ "tv",
+ "wearable",
+ "car"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry",
+ "installationFree": false
+ },
+ "metaData": {
+ "customizeData": [
+ {
+ "name": "hwc-theme",
+ "extra": "",
+ "value": "androidhwext:style/Theme.Emui.Wallpaper.NoTitleBar"
+ }
+ ]
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "visible": true,
+ "name": "com.xcl.search.test.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:entry_MainAbility",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.xcl.search.test.SearchDemoAbility",
+ "icon": "$media:icon",
+ "description": "$string:searchdemoability_description",
+ "label": "$string:entry_SearchDemoAbility",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/java/com/xcl/search/test/MainAbility.java b/entry/src/main/java/com/xcl/search/test/MainAbility.java
new file mode 100644
index 0000000..0d633fc
--- /dev/null
+++ b/entry/src/main/java/com/xcl/search/test/MainAbility.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2022 田梓萱, xcl@xuegao-tzx.top
+ *
+ * Licensed under the GNU Affero General Public License, Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.gnu.org/licenses/agpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.xcl.search.test;
+
+import com.xcl.search.test.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.window.service.WindowManager;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setAbilitySliceAnimator(null);
+ super.setTransitionAnimation(0, 0);
+ this.getWindow().addFlags(WindowManager.LayoutConfig.MARK_ALLOW_EXTEND_LAYOUT);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ super.setTransitionAnimation(0, 0);
+ super.setAbilitySliceAnimator(null);
+ }
+}
diff --git a/entry/src/main/java/com/xcl/search/test/MyApplication.java b/entry/src/main/java/com/xcl/search/test/MyApplication.java
new file mode 100644
index 0000000..49cda35
--- /dev/null
+++ b/entry/src/main/java/com/xcl/search/test/MyApplication.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022 田梓萱, xcl@xuegao-tzx.top
+ *
+ * Licensed under the GNU Affero General Public License, Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.gnu.org/licenses/agpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.xcl.search.test;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/entry/src/main/java/com/xcl/search/test/SearchDemoAbility.java b/entry/src/main/java/com/xcl/search/test/SearchDemoAbility.java
new file mode 100644
index 0000000..94212e5
--- /dev/null
+++ b/entry/src/main/java/com/xcl/search/test/SearchDemoAbility.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2022 田梓萱, xcl@xuegao-tzx.top
+ *
+ * Licensed under the GNU Affero General Public License, Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.gnu.org/licenses/agpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.xcl.search.test;
+
+import com.xcl.search.test.slice.SearchDemoAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.window.service.WindowManager;
+
+public class SearchDemoAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setAbilitySliceAnimator(null);
+ super.setTransitionAnimation(0, 0);
+ this.getWindow().addFlags(WindowManager.LayoutConfig.MARK_ALLOW_EXTEND_LAYOUT);
+ super.setMainRoute(SearchDemoAbilitySlice.class.getName());
+ super.setTransitionAnimation(0, 0);
+ super.setAbilitySliceAnimator(null);
+ }
+}
diff --git a/entry/src/main/java/com/xcl/search/test/slice/MainAbilitySlice.java b/entry/src/main/java/com/xcl/search/test/slice/MainAbilitySlice.java
new file mode 100644
index 0000000..19a1789
--- /dev/null
+++ b/entry/src/main/java/com/xcl/search/test/slice/MainAbilitySlice.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2022 田梓萱, xcl@xuegao-tzx.top
+ *
+ * Licensed under the GNU Affero General Public License, Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.gnu.org/licenses/agpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.xcl.search.test.slice;
+
+import com.xcl.search.test.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.aafwk.content.Operation;
+import ohos.agp.components.Component;
+import ohos.agp.window.service.WindowManager;
+import ohos.utils.net.Uri;
+
+public class MainAbilitySlice extends AbilitySlice {
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ this.getWindow().addFlags(WindowManager.LayoutConfig.MARK_ALLOW_EXTEND_LAYOUT);
+ this.findComponentById(ResourceTable.Id_withoutSug).setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component v) {
+ Route("withoutSug");
+ }
+ });
+ this.findComponentById(ResourceTable.Id_recentSug).setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component v) {
+ Route("recentSug");
+ }
+ });
+ this.findComponentById(ResourceTable.Id_hasknownSug).setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component v) {
+ Route("hasknownSug");
+ }
+ });
+ }
+
+ public void Route(String route) {
+ Intent intent1 = new Intent();
+ intent1.setParam("SEARCH_PD", route);
+ Operation operation = new Intent.OperationBuilder()
+ .withDeviceId("")
+ .withBundleName(MainAbilitySlice.this.getBundleName())
+ .withAbilityName("com.xcl.search.test.SearchDemoAbility")
+ .build();
+ intent1.setOperation(operation);
+ MainAbilitySlice.this.startAbility(intent1);
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/entry/src/main/java/com/xcl/search/test/slice/SearchDemoAbilitySlice.java b/entry/src/main/java/com/xcl/search/test/slice/SearchDemoAbilitySlice.java
new file mode 100644
index 0000000..8c9ab65
--- /dev/null
+++ b/entry/src/main/java/com/xcl/search/test/slice/SearchDemoAbilitySlice.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2022 田梓萱, xcl@xuegao-tzx.top
+ *
+ * Licensed under the GNU Affero General Public License, Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.gnu.org/licenses/agpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.xcl.search.test.slice;
+
+import com.xcl.search.test.ResourceTable;
+import com.xcl.supersearch.SHistoryContactor;
+import com.xcl.supersearch.SRContactor;
+import com.xcl.supersearch.SearchView;
+import com.xcl.supersearch.Utils;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.ListContainer;
+import ohos.agp.window.service.WindowManager;
+import ohos.data.distributed.common.KvManagerConfig;
+import ohos.data.distributed.common.KvManagerFactory;
+import ohos.distributedhardware.devicemanager.DeviceInfo;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SearchDemoAbilitySlice extends AbilitySlice {
+ private static final HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x00234, "SearchDemoAbilitySlice");
+ private int PDD = -2;
+ private SearchView sV;
+
+ private static List getSearch() {
+ List list = new ArrayList<>();
+ for (int i = 0; i < 15; i++) {
+ list.add(new SRContactor("zhangsan", "class1", "1", "2你", "3", "4.7"));
+ }
+ list.add(new SRContactor("zhtzx5", "clsths2"));//支持只传标题、信息,此时后面4个按钮默认不显示
+ list.add(new SRContactor("zhng", "cl1", null, ",2u", "3g", "7n7"));//支持传null,此时传null的将不会显示
+ list.add(new SRContactor("zhxcl5", null));//支持只传标题,同时传null,此时后面4个按钮和信息不显示
+ //TODO:注意:第一个不可为null
+ list.add(new SRContactor("zhags", "clhhs1", "1操", "2", "3码", "47"));//支持传入全部信息
+ return list;
+ }
+
+ private static List getSuggection() {
+ List list = new ArrayList<>();
+ list.add(new SHistoryContactor("小草林", ResourceTable.Media_ic_history_black_24dp, -3));//这里-3代表根据默认图标或xml中配置的图标显示
+ list.add(new SHistoryContactor("TEST", ResourceTable.Media_ic_history_black_24dp, -1));//这里-1代表根据不显示图标
+ list.add(new SHistoryContactor("测试", -1, ResourceTable.Media_ic_close_black_24dp));
+ list.add(new SHistoryContactor("...", ResourceTable.Media_ic_history_black_24dp, ResourceTable.Media_ic_close_black_24dp));
+ list.add(new SHistoryContactor("test"));//可以只配置建议信息,会自动根据默认图标或xml中配置的图标显示
+ return list;
+ }
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ getWindow().addFlags(WindowManager.LayoutConfig.MARK_ALLOW_EXTEND_LAYOUT);
+ ohos.data.distributed.device.DeviceInfo localDeviceInfo = KvManagerFactory.getInstance()
+ .createKvManager(new KvManagerConfig((getContext()))).getLocalDeviceInfo();
+ int localDeviceType = Integer.parseInt(localDeviceInfo.getType());
+ if (localDeviceType == DeviceInfo.DeviceType.WEARABLE.value()) {
+ super.setUIContent(ResourceTable.Layout_ability_search_demow);
+ } else {
+ super.setUIContent(ResourceTable.Layout_ability_search_demo);
+ }
+ Utils.pd_pd = true;
+ sV = (SearchView) findComponentById(ResourceTable.Id_searchview);
+ if (sV == null) {
+ Utils.info(SearchDemoAbilitySlice.label, "null");
+ } else {
+ Utils.info(SearchDemoAbilitySlice.label, "not null");
+ }
+ if (intent != null) {
+ String action = intent.getStringParam("SEARCH_PD");
+ if ("withoutSug".equals(action)) {
+ PDD = -1;
+ } else if ("recentSug".equals(action)) {
+ PDD = 0;
+ } else if ("hasknownSug".equals(action)) {
+ PDD = 1;
+ }
+ } else {
+ terminate();
+ }
+
+ initView();
+ }
+
+ private void initView() {
+
+
+ if (PDD == 0) {
+ /*sv.Onsearch(getContext(),
+ (ListContainer) findComponentById(ResourceTable.Id_ListContainer),
+ sv,
+ findComponentById(ResourceTable.Id_emptyView),
+ (com.xcl.supersearch.RoundProgressBar) findComponentById(ResourceTable.Id_progressBar),
+ getSearch(),
+ true);*///TODO:方法一,无需建议列表只需配置true即可
+ sV.setContext(getContext())
+ .setRoundProgressBar((com.xcl.supersearch.RoundProgressBar) findComponentById(ResourceTable.Id_progressBar))
+ .setSearchView(sV)
+ .setSRListContainer(SearchDemoAbilitySlice.getSearch())
+ .setSuggestionisShow(true)
+ .setBackComponent(findComponentById(ResourceTable.Id_emptyView))
+ .setListContainer((ListContainer) findComponentById(ResourceTable.Id_ListContainer))
+ .Builder();//TODO:方法二
+ } else if (PDD == 1) {
+ /*sv.Onsearch(getContext(),//获取所在能力的context
+ (ListContainer) findComponentById(ResourceTable.Id_ListContainer),//根据id获取并绑定结果列表展示控件
+ sv,//根据id绑定控件
+ findComponentById(ResourceTable.Id_emptyView),//根据id获取并绑定背景展示控件
+ (com.xcl.supersearch.RoundProgressBar) findComponentById(ResourceTable.Id_progressBar),//根据id获取并绑定背景Loading加载动画控件
+ getSearch(),//传入搜索的数据
+ getSuggection(),//传入搜索建议的数据,如果不配置这个,则不会自带搜索建议
+ true);//是否开启搜索建议
+ *///TODO:方法一
+ sV.setContext(getContext())//设置所在能力的context
+ .setRoundProgressBar((com.xcl.supersearch.RoundProgressBar) findComponentById(ResourceTable.Id_progressBar))//设置背景Loading加载动画控件
+ .setSearchView(sV)//设置搜索控件
+ .setSRListContainer(SearchDemoAbilitySlice.getSearch())//传入搜索的数据
+ .setSuggestionisShow(true)//设置是否开启搜索建议
+ .setSuggestionList(SearchDemoAbilitySlice.getSuggection())//设置搜索建议的数据
+ .setBackComponent(findComponentById(ResourceTable.Id_emptyView))//设置背景展示控件
+ .setListContainer((ListContainer) findComponentById(ResourceTable.Id_ListContainer))//设置结果列表展示控件
+ .Builder();//执行构造
+ //TODO:方法二
+ } else if (PDD == -1) {
+ sV.setContext(getContext())
+ .setRoundProgressBar((com.xcl.supersearch.RoundProgressBar) findComponentById(ResourceTable.Id_progressBar))
+ .setSearchView(sV)
+ .setSRListContainer(SearchDemoAbilitySlice.getSearch())
+ .setBackComponent(findComponentById(ResourceTable.Id_emptyView))
+ .setListContainer((ListContainer) findComponentById(ResourceTable.Id_ListContainer))
+ .Builder();//TODO:方法二
+ /*sv.Onsearch(getContext(),
+ (ListContainer) findComponentById(ResourceTable.Id_ListContainer),
+ sv,
+ findComponentById(ResourceTable.Id_emptyView),
+ (com.xcl.supersearch.RoundProgressBar) findComponentById(ResourceTable.Id_progressBar),
+ getSearch());*///TODO:方法一,不配置默认不开启搜索建议
+ }
+ sV.setCustomListener(new SearchView.CustomListener() {
+ @Override
+ public void onFilter(String filter) {
+ //TODO:右上角的按钮事件
+ }
+ });
+ sV.setBt1Listener(new SearchView.Bt1Listener() {
+ @Override
+ public void onbT1(int position) {
+ HiLog.error(SearchDemoAbilitySlice.label, "点击了按钮1,其的行号为:" + position + 1);
+ //TODO:一行列表第一个的按钮事件
+ }
+ });
+ sV.setBackClickListener(new SearchView.BackClickListener() {
+ @Override
+ public void onBackClick() {
+ terminate();
+ //TODO:左上角的按钮事件
+ }
+ });
+ sV.setNullWarnListener(new SearchView.NullWarnListener() {
+ @Override
+ public void onNullError() {
+ HiLog.error(SearchDemoAbilitySlice.label, "空搜索警告1");
+ //TODO:支持自定义空搜索警告
+ }
+ });
+ sV.setNoneWarnListener(new SearchView.NoneWarnListener() {
+ @Override
+ public void onNullWarn() {
+ HiLog.error(SearchDemoAbilitySlice.label, "空结果警告1");
+ //TODO:支持自定义空结果警告
+ }
+ });
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000..e450c0d
--- /dev/null
+++ b/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,64 @@
+{
+ "string": [
+ {
+ "name": "entry_MainAbility",
+ "value": "entry_MainAbility"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "mainability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "searchmr",
+ "value": "搜索默认页面"
+ },
+ {
+ "name": "withoutSug",
+ "value": "无建议搜索"
+ },
+ {
+ "name": "recentSug",
+ "value": "有最近建议搜索"
+ },
+ {
+ "name": "hasknownSug",
+ "value": "有已知建议搜索"
+ },
+ {
+ "name": "suggestion_text",
+ "value": "建议文本"
+ },
+ {
+ "name": "search_hint_text",
+ "value": "搜索..."
+ },
+ {
+ "name": "search_hint_text_",
+ "value": "搜索."
+ },
+ {
+ "name": "search_input_null",
+ "value": "搜索值为空"
+ },
+ {
+ "name": "search_answer_none",
+ "value": "搜索结果为空"
+ },
+ {
+ "name": "searchdemoability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "searchdemoability_HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "entry_SearchDemoAbility",
+ "value": "entry_SearchDemoAbility"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/background_ability_main.xml b/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000..a002c23
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/background_ability_search_demo.xml b/entry/src/main/resources/base/graphic/background_ability_search_demo.xml
new file mode 100644
index 0000000..9ed8e67
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/background_ability_search_demo.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/ic_arrow_left.xml b/entry/src/main/resources/base/graphic/ic_arrow_left.xml
new file mode 100644
index 0000000..dac8775
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/ic_arrow_left.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/ic_close.xml b/entry/src/main/resources/base/graphic/ic_close.xml
new file mode 100644
index 0000000..8940e56
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/ic_close.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/ic_filters.xml b/entry/src/main/resources/base/graphic/ic_filters.xml
new file mode 100644
index 0000000..fe9534c
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/ic_filters.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/graphic/ic_history_black.xml b/entry/src/main/resources/base/graphic/ic_history_black.xml
new file mode 100644
index 0000000..2151e9e
--- /dev/null
+++ b/entry/src/main/resources/base/graphic/ic_history_black.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/entry/src/main/resources/base/layout/ability_main.xml b/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000..77db19f
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/ability_search_demo.xml b/entry/src/main/resources/base/layout/ability_search_demo.xml
new file mode 100644
index 0000000..cdda8e7
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_search_demo.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/layout/ability_search_demow.xml b/entry/src/main/resources/base/layout/ability_search_demow.xml
new file mode 100644
index 0000000..87e9754
--- /dev/null
+++ b/entry/src/main/resources/base/layout/ability_search_demow.xml
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/base/media/ic_close_black_24dp.png b/entry/src/main/resources/base/media/ic_close_black_24dp.png
new file mode 100644
index 0000000..8af456d
Binary files /dev/null and b/entry/src/main/resources/base/media/ic_close_black_24dp.png differ
diff --git a/entry/src/main/resources/base/media/ic_history_black_24dp.png b/entry/src/main/resources/base/media/ic_history_black_24dp.png
new file mode 100644
index 0000000..ec48a1e
Binary files /dev/null and b/entry/src/main/resources/base/media/ic_history_black_24dp.png differ
diff --git a/entry/src/main/resources/base/media/icon.png b/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000..ce307a8
Binary files /dev/null and b/entry/src/main/resources/base/media/icon.png differ
diff --git a/entry/src/main/resources/zh/element/string.json b/entry/src/main/resources/zh/element/string.json
new file mode 100644
index 0000000..2059871
--- /dev/null
+++ b/entry/src/main/resources/zh/element/string.json
@@ -0,0 +1,64 @@
+{
+ "string": [
+ {
+ "name": "entry_MainAbility",
+ "value": "entry_MainAbility"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "mainability_HelloWorld",
+ "value": "你好,世界"
+ },
+ {
+ "name": "searchmr",
+ "value": "搜索默认页面"
+ },
+ {
+ "name": "withoutSug",
+ "value": "无建议搜索"
+ },
+ {
+ "name": "recentSug",
+ "value": "有最近建议搜索"
+ },
+ {
+ "name": "hasknownSug",
+ "value": "有已知建议搜索"
+ },
+ {
+ "name": "suggestion_text",
+ "value": "建议文本"
+ },
+ {
+ "name": "search_hint_text",
+ "value": "搜索..."
+ },
+ {
+ "name": "search_hint_text_",
+ "value": "搜索."
+ },
+ {
+ "name": "search_input_null",
+ "value": "搜索值为空"
+ },
+ {
+ "name": "search_answer_none",
+ "value": "搜索结果为空"
+ },
+ {
+ "name": "entry_SearchDemoAbility",
+ "value": "entry_SearchDemoAbility"
+ },
+ {
+ "name": "searchdemoability_description",
+ "value": "Java_Empty Ability"
+ },
+ {
+ "name": "searchdemoability_HelloWorld",
+ "value": "你好,世界"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/entry/src/ohosTest/java/com/xcl/search/test/ExampleOhosTest.java b/entry/src/ohosTest/java/com/xcl/search/test/ExampleOhosTest.java
new file mode 100644
index 0000000..31d9edc
--- /dev/null
+++ b/entry/src/ohosTest/java/com/xcl/search/test/ExampleOhosTest.java
@@ -0,0 +1,14 @@
+package com.xcl.search.test;
+
+import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ExampleOhosTest {
+ @Test
+ public void testBundleName() {
+ final String actualBundleName = AbilityDelegatorRegistry.getArguments().getTestBundleName();
+ assertEquals("com.xcl.search.test", actualBundleName);
+ }
+}
\ No newline at end of file
diff --git a/entry/src/test/java/com/xcl/search/test/ExampleTest.java b/entry/src/test/java/com/xcl/search/test/ExampleTest.java
new file mode 100644
index 0000000..0ab0174
--- /dev/null
+++ b/entry/src/test/java/com/xcl/search/test/ExampleTest.java
@@ -0,0 +1,49 @@
+package com.xcl.search.test;
+
+import com.xcl.imagetracer_mod.ImageTracer;
+import org.junit.Test;
+
+import java.util.HashMap;
+
+public class ExampleTest {
+ @Test
+ public void onStart() throws Exception {
+ // Options
+ HashMap options = new HashMap();
+ // Tracing
+ options.put("ltres", 1f);
+ options.put("qtres", 1f);
+ options.put("pathomit", 8f);
+ // Color quantization
+ options.put("colorsampling", 1f); // 1f means true ; 0f means false: starting with generated palette
+ options.put("numberofcolors", 16f);
+ options.put("mincolorratio", 0.02f);
+ options.put("colorquantcycles", 3f);
+ // SVG rendering
+ options.put("scale", 1f);
+ options.put("roundcoords", 1f); // 1f means rounded to 1 decimal places, like 7.3 ; 3f means rounded to 3 places, like 7.356 ; etc.
+ options.put("lcpr", 0f);
+ options.put("qcpr", 0f);
+ options.put("desc", 1f); // 1f means true ; 0f means false: SVG descriptions deactivated
+ options.put("viewbox", 0f); // 1f means true ; 0f means false: fixed width and height
+ // Selective Gauss Blur
+ options.put("blurradius", 0f); // 0f means deactivated; 1f .. 5f : blur with this radius
+ options.put("blurdelta", 20f); // smaller than this RGB difference will be blurred
+ // Palette
+ // This is an example of a grayscale palette
+ // please note that signed byte values [ -128 .. 127 ] will be converted to [ 0 .. 255 ] in the getsvgstring function
+ //下方的两个数字16请参照实际图片动态调整以实现最佳效果
+ byte[][] palette = new byte[16][4];
+ for (int colorcnt = 0; colorcnt < 16; colorcnt++) {
+ palette[colorcnt][0] = (byte) (-128 + colorcnt * 32); // R
+ palette[colorcnt][1] = (byte) (-128 + colorcnt * 32); // G
+ palette[colorcnt][2] = (byte) (-128 + colorcnt * 32); // B
+ palette[colorcnt][3] = (byte) 127; // A
+ }
+
+ ImageTracer.saveString(
+ "src\\main\\resources\\base\\media\\ic_close_black_24dp.svg",
+ ImageTracer.imageToSVG("src\\main\\resources\\base\\media\\ic_close_black_24dp.png", options, palette)
+ );
+ }
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..be49249
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,13 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# If the Chinese output is garbled, please configure the following parameter.
+# This function is enabled by default when the DevEco Studio builds the hap/app,if you need disable gradle parallel,you should set org.gradle.parallel false.
+# more information see https://docs.gradle.org/current/userguide/performance.html
+# org.gradle.parallel=false
+# org.gradle.jvmargs=-Dfile.encoding=GBK
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..490fda8
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..63c817f
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://repo.huaweicloud.com/gradle/gradle-7.3-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..536f027
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ]; do
+ ls=$(ls -ld "$PRG")
+ link=$(expr "$ls" : '.*-> \(.*\)$')
+ if expr "$link" : '/.*' >/dev/null; then
+ PRG="$link"
+ else
+ PRG=$(dirname "$PRG")"/$link"
+ fi
+done
+SAVED="$(pwd)"
+cd "$(dirname \"$PRG\")/" >/dev/null
+APP_HOME="$(pwd -P)"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=$(basename "$0")
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn() {
+ echo "$*"
+}
+
+die() {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$(uname)" in
+CYGWIN*)
+ cygwin=true
+ ;;
+Darwin*)
+ darwin=true
+ ;;
+MINGW*)
+ msys=true
+ ;;
+NONSTOP*)
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ]; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ]; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ]; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then
+ MAX_FD_LIMIT=$(ulimit -H -n)
+ if [ $? -eq 0 ]; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ]; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ]; then
+ APP_HOME=$(cygpath --path --mixed "$APP_HOME")
+ CLASSPATH=$(cygpath --path --mixed "$CLASSPATH")
+ JAVACMD=$(cygpath --unix "$JAVACMD")
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null)
+ SEP=""
+ for dir in $ROOTDIRSRAW; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ]; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@"; do
+ CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -)
+ CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition
+ eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg")
+ else
+ eval $(echo args$i)="\"$arg\""
+ fi
+ i=$(expr $i + 1)
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save() {
+ for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..62bd9b9
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/libs/ImageTracer.jar b/libs/ImageTracer.jar
new file mode 100644
index 0000000..b9b98af
Binary files /dev/null and b/libs/ImageTracer.jar differ
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/package.json
@@ -0,0 +1 @@
+{}
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..f478a1a
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':supersearch'
diff --git a/supersearch/build.gradle b/supersearch/build.gradle
new file mode 100644
index 0000000..c158787
--- /dev/null
+++ b/supersearch/build.gradle
@@ -0,0 +1,28 @@
+apply plugin: 'com.huawei.ohos.library'
+//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
+//apply from: './upload.gradle'
+ohos {
+ compileSdkVersion 6
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+ buildTypes {
+ release {
+ proguardOpt {
+ proguardEnabled false
+ rulesFiles 'proguard-rules.pro'
+ }
+ }
+ debug {
+ proguardOpt {
+ proguardEnabled false
+ rulesFiles 'proguard-rules.pro'
+ }
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testImplementation 'junit:junit:4.13.1'
+}
diff --git a/supersearch/consumer-rules.pro b/supersearch/consumer-rules.pro
new file mode 100644
index 0000000..9dccc61
--- /dev/null
+++ b/supersearch/consumer-rules.pro
@@ -0,0 +1 @@
+# Add har specific ProGuard rules for consumer here.
\ No newline at end of file
diff --git a/supersearch/src/main/config.json b/supersearch/src/main/config.json
new file mode 100644
index 0000000..e9f64a5
--- /dev/null
+++ b/supersearch/src/main/config.json
@@ -0,0 +1,35 @@
+{
+ "app": {
+ "bundleName": "com.xcl.search",
+ "vendor": "xcl",
+ "version": {
+ "code": 220517,
+ "name": "1.2.3.517"
+ }
+ },
+ "deviceConfig": {
+ },
+ "module": {
+ "package": "com.xcl.supersearch",
+ "deviceType": [
+ "phone",
+ "tablet",
+ "tv",
+ "wearable"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "supersearch",
+ "moduleType": "har"
+ },
+ "metaData": {
+ "customizeData": [
+ {
+ "name": "hwc-theme",
+ "extra": "",
+ "value": "androidhwext:style/Theme.Emui.Wallpaper.NoTitleBar"
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/supersearch/src/main/java/com/xcl/supersearch/BackgroundLoadingAnimation.java b/supersearch/src/main/java/com/xcl/supersearch/BackgroundLoadingAnimation.java
new file mode 100644
index 0000000..2b8aee1
--- /dev/null
+++ b/supersearch/src/main/java/com/xcl/supersearch/BackgroundLoadingAnimation.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2022 田梓萱, xcl@xuegao-tzx.top
+ *
+ * Licensed under the GNU Affero General Public License, Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.gnu.org/licenses/agpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.xcl.supersearch;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.element.Element;
+
+public final class BackgroundLoadingAnimation {
+ private boolean isRecycled;
+
+ private float fromAlpha;
+ private float toAlpha;
+
+ private ComponentContainer view;
+
+ private AnimatorValue animator;
+
+ public BackgroundLoadingAnimation(ComponentContainer view, float fromAlpha, float toAlpha) {
+ this.view = view;
+ this.fromAlpha = fromAlpha;
+ this.toAlpha = toAlpha;
+ this.isRecycled = false;
+ initAnimator();
+ }
+
+ private void initAnimator() {
+ animator = new AnimatorValue();
+ animator.setDuration(200);
+ animator.setCurveType(Animator.CurveType.LINEAR);
+ animator.setValueUpdateListener((valueAnimator, v) -> {
+ Element element = view.getBackgroundElement();
+ element.setAlpha((int) (fromAlpha * 0xFF + (toAlpha - fromAlpha) * 0xFF * v));
+ }
+ );
+ animator.setStateChangedListener(new Animator.StateChangedListener() {
+ @Override
+ public void onStart(Animator animator) {
+
+ }
+
+ @Override
+ public void onStop(Animator animator) {
+ view.setClickable(toAlpha != 0);
+ }
+
+ @Override
+ public void onCancel(Animator animator) {
+
+ }
+
+ @Override
+ public void onEnd(Animator animator) {
+
+ }
+
+ @Override
+ public void onPause(Animator animator) {
+
+ }
+
+ @Override
+ public void onResume(Animator animator) {
+
+ }
+ });
+ }
+
+ public BackgroundLoadingAnimation setFromAlpha(float fromAlpha) {
+ this.fromAlpha = fromAlpha;
+ return this;
+ }
+
+
+ public BackgroundLoadingAnimation setToAlpha(float toAlpha) {
+ this.toAlpha = toAlpha;
+ return this;
+ }
+
+
+ public BackgroundLoadingAnimation setInterpolator(int interpolator) {
+ animator.setCurveType(interpolator);
+ return this;
+ }
+
+
+ public BackgroundLoadingAnimation setDuration(long duration) {
+ animator.setDuration(duration);
+ return this;
+ }
+
+
+ public void start() {
+ if (isRecycled() || view.getAlpha() == toAlpha) {
+ return;
+ }
+
+ stop();
+ animator.start();
+ }
+
+
+ public void stop() {
+ if (!isRecycled() && isRunning()) {
+ animator.cancel();
+ }
+ }
+
+
+ public boolean isRunning() {
+ return animator.isRunning();
+ }
+
+
+ public void recycle() {
+ if (isRecycled) {
+ return;
+ }
+
+ view = null;
+ animator = null;
+ isRecycled = true;
+ }
+
+
+ public boolean isRecycled() {
+ return isRecycled;
+ }
+
+
+}
diff --git a/supersearch/src/main/java/com/xcl/supersearch/ContactProviderSR.java b/supersearch/src/main/java/com/xcl/supersearch/ContactProviderSR.java
new file mode 100644
index 0000000..9442a6c
--- /dev/null
+++ b/supersearch/src/main/java/com/xcl/supersearch/ContactProviderSR.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2022 田梓萱, xcl@xuegao-tzx.top
+ *
+ * Licensed under the GNU Affero General Public License, Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.gnu.org/licenses/agpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.xcl.supersearch;
+
+import ohos.agp.components.*;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.xcl.supersearch.Utils.iswear;
+
+
+public class ContactProviderSR extends BaseItemProvider {
+ private static final HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x00666, "ContactProviderSR");
+ private final Context context;
+ private List contactArrays = new ArrayList<>(0);
+ private AdapterClickListener adapterClickListener;
+
+ public ContactProviderSR(Context context, List contactArrays) {
+ this.context = context;
+ this.contactArrays = contactArrays;
+ }
+
+ public ContactProviderSR(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public int getCount() {
+ return this.contactArrays == null ? 0 : this.contactArrays.size();
+ }
+
+ @Override
+ public SRContactor getItem(int position) {
+ if (position < this.contactArrays.size() && position >= 0) return this.contactArrays.get(position);
+ return null;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public Component getComponent(int position, Component componentPara, ComponentContainer componentContainer) {
+ Component component = componentPara;
+ try {
+ ViewHolder viewHolder = null;
+ if (component == null) {
+ if (iswear) {
+ component = LayoutScatter.getInstance(this.context).parse(ResourceTable.Layout_searchresw,
+ null, false);
+ } else {
+ component = LayoutScatter.getInstance(this.context).parse(ResourceTable.Layout_searchres,
+ null, false);
+ }
+ viewHolder = new ViewHolder();
+ viewHolder.button1 = (Button) component.findComponentById(ResourceTable.Id_button1);
+ viewHolder.button2 = (Button) component.findComponentById(ResourceTable.Id_button2);
+ viewHolder.button3 = (Button) component.findComponentById(ResourceTable.Id_button3);
+ viewHolder.button4 = (Button) component.findComponentById(ResourceTable.Id_button4);
+ viewHolder.text2 = (Text) component.findComponentById(ResourceTable.Id_message);
+ viewHolder.text1 = (Text) component.findComponentById(ResourceTable.Id_title);
+ component.setTag(viewHolder);
+ } else if (component.getTag() instanceof ViewHolder) viewHolder = (ViewHolder) component.getTag();
+ if (viewHolder != null) {
+ viewHolder.text1.setVisibility(Component.VISIBLE);
+ viewHolder.text2.setVisibility(Component.VISIBLE);
+ viewHolder.button1.setVisibility(Component.VISIBLE);
+ viewHolder.button2.setVisibility(Component.VISIBLE);
+ viewHolder.button3.setVisibility(Component.VISIBLE);
+ viewHolder.button4.setVisibility(Component.VISIBLE);
+ if (this.contactArrays.get(position).getBt1() != null) {
+ viewHolder.button1.setText(this.contactArrays.get(position).getBt1());
+ } else {
+ viewHolder.button1.setVisibility(Component.HIDE);
+ }
+ viewHolder.button1.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component deleteComponent) {
+ if (ContactProviderSR.this.adapterClickListener != null)
+ ContactProviderSR.this.adapterClickListener.ann1(position);
+ }
+ });
+ if (this.contactArrays.get(position).getBt2() != null) {
+ viewHolder.button2.setText(this.contactArrays.get(position).getBt2());
+ } else {
+ viewHolder.button2.setVisibility(Component.HIDE);
+ }
+ viewHolder.button2.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component deleteComponent) {
+ if (ContactProviderSR.this.adapterClickListener != null)
+ ContactProviderSR.this.adapterClickListener.ann2(position);
+ }
+ });
+ if (this.contactArrays.get(position).getBt3() != null) {
+ viewHolder.button3.setText(this.contactArrays.get(position).getBt3());
+ } else {
+ viewHolder.button3.setVisibility(Component.HIDE);
+ }
+ viewHolder.button3.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component deleteComponent) {
+ if (ContactProviderSR.this.adapterClickListener != null)
+ ContactProviderSR.this.adapterClickListener.ann3(position);
+ }
+ });
+ if (this.contactArrays.get(position).getBt4() != null) {
+ viewHolder.button4.setText(this.contactArrays.get(position).getBt4());
+ } else {
+ viewHolder.button4.setVisibility(Component.HIDE);
+ }
+ viewHolder.button4.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component deleteComponent) {
+ if (ContactProviderSR.this.adapterClickListener != null)
+ ContactProviderSR.this.adapterClickListener.ann4(position);
+ }
+ });
+ if (this.contactArrays.get(position).getTitle() != null) {
+ viewHolder.text1.setText(this.contactArrays.get(position).getTitle());
+ } else {
+ viewHolder.text1.setVisibility(Component.HIDE);
+ }
+ if (this.contactArrays.get(position).getMessage() != null) {
+ viewHolder.text2.setText(this.contactArrays.get(position).getMessage());
+ } else {
+ viewHolder.text2.setVisibility(Component.HIDE);
+ }
+ }
+ } catch (Exception e) {
+ Utils.error(label, e.getMessage());
+ }
+ return component;
+ }
+
+ void setAdapterClickListener(AdapterClickListener adapterClickListener) {
+ this.adapterClickListener = adapterClickListener;
+ }
+
+ public void setData(List listData) {
+ contactArrays = listData;
+ }
+
+ public interface AdapterClickListener {
+ void ann1(int position);
+
+ void ann2(int position);
+
+ void ann3(int position);
+
+ void ann4(int position);
+ }
+
+ private static class ViewHolder {
+ private Text text1;
+ private Text text2;
+ private Button button1;
+ private Button button2;
+ private Button button3;
+ private Button button4;
+ }
+}
diff --git a/supersearch/src/main/java/com/xcl/supersearch/RoundProgressBar.java b/supersearch/src/main/java/com/xcl/supersearch/RoundProgressBar.java
new file mode 100644
index 0000000..1576b71
--- /dev/null
+++ b/supersearch/src/main/java/com/xcl/supersearch/RoundProgressBar.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2022 田梓萱, xcl@xuegao-tzx.top
+ *
+ * Licensed under the GNU Affero General Public License, Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.gnu.org/licenses/agpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.xcl.supersearch;
+
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.render.Arc;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.Color;
+import ohos.agp.utils.RectFloat;
+import ohos.agp.window.service.Display;
+import ohos.agp.window.service.DisplayAttributes;
+import ohos.agp.window.service.DisplayManager;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+import static com.xcl.supersearch.Utils.*;
+
+public class RoundProgressBar extends Component implements Component.DrawTask {
+ private static final HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x00234, "RoundProgressBar");
+ private final DisplayAttributes displayAttributes;
+ private int backgroundColor = Color.getIntColor("#FF4C29CB");//默认紫色背景
+ private int arcD = 1;
+ private int arcO = 0;
+ private float rotateAngle = 0;
+ private int limite = 0;
+ private Paint arcPaint;
+ private float STROKE_WITH_VP = 3f;
+
+ public RoundProgressBar(Context context) {
+ this(context, null);
+ }
+
+ public RoundProgressBar(Context context, AttrSet attrSet) {
+ this(context, attrSet, "");
+ }
+
+ public RoundProgressBar(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ DisplayManager displayManager = DisplayManager.getInstance();
+ Display display = displayManager.getDefaultDisplay(this.getContext()).get();
+ displayAttributes = display.getAttributes();
+ setAttributes(attrSet);
+ addDrawTask(this);
+ initPaint();
+ }
+
+ protected void initPaint() {
+ try {
+ arcPaint = new Paint();
+ arcPaint.setAntiAlias(true);
+ arcPaint.setStyle(Paint.Style.STROKE_STYLE);
+ } catch (Exception e) {
+ Utils.error(label, e.getMessage());
+ }
+ }
+
+ protected void setAttributes(AttrSet attrs) {
+ try {
+ setMinHeight(vpToPx(32, displayAttributes));
+ setMinWidth(vpToPx(32, displayAttributes));
+ if (attrs != null) {
+ String background = null;
+ if (background != null) {
+ setBackgroundColor(Color.getIntColor(background));
+ }
+ backgroundColor = getColor(attrs, "round_progress_color", backgroundColor);
+ STROKE_WITH_VP = getFloat(attrs, "round_progress_with", STROKE_WITH_VP);
+ }
+ setMinHeight(vpToPx(3, displayAttributes));
+ } catch (Exception e) {
+ Utils.error(label, e.getMessage());
+ }
+ }
+
+
+ private void drawAnimation(Canvas canvas) {
+ try {
+ int halfWidth = getWidth() / 2;
+ int halfHeight = getHeight() / 2;
+ if (arcO == limite) {
+ arcD += 6;
+ }
+ if (arcD >= 290 || arcO > limite) {
+ arcO += 6;
+ arcD -= 6;
+ }
+ if (arcO > limite + 290) {
+ limite = arcO;
+ arcO = limite;
+ arcD = 1;
+ }
+ rotateAngle += 4;
+ canvas.rotate(rotateAngle, halfWidth, halfHeight);
+ int strokeWith = vpToPx(STROKE_WITH_VP, displayAttributes);
+ int halfStrokeWith = vpToPx(STROKE_WITH_VP / 2f, displayAttributes);
+ arcPaint.setStrokeWidth(strokeWith);
+ arcPaint.setColor(new Color(backgroundColor));
+ canvas.drawArc(new RectFloat(halfStrokeWith, halfStrokeWith, getWidth() - halfStrokeWith, getHeight() - halfStrokeWith),
+ new Arc(arcO, arcD, false), arcPaint);
+ getContext().getUITaskDispatcher().asyncDispatch(this::invalidate);
+ } catch (Exception e) {
+ Utils.error(label, e.getMessage());
+ }
+ }
+
+ public void setBackgroundColor(int color) {
+ backgroundColor = color;
+ getContext().getUITaskDispatcher().asyncDispatch(this::invalidate);
+ }
+
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+ drawAnimation(canvas);
+ }
+}
diff --git a/supersearch/src/main/java/com/xcl/supersearch/SHistoryContactor.java b/supersearch/src/main/java/com/xcl/supersearch/SHistoryContactor.java
new file mode 100644
index 0000000..eb75b7e
--- /dev/null
+++ b/supersearch/src/main/java/com/xcl/supersearch/SHistoryContactor.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2022 田梓萱, xcl@xuegao-tzx.top
+ *
+ * Licensed under the GNU Affero General Public License, Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.gnu.org/licenses/agpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.xcl.supersearch;
+
+
+public class SHistoryContactor {
+ private String searchValue;
+ private int searchIcon = -1;
+ private int removeIcon = -1;
+
+ public SHistoryContactor(String searchValue, int searchIcon, int removeIcon) {
+ this.searchValue = searchValue;
+ this.searchIcon = searchIcon;
+ this.removeIcon = removeIcon;
+ }
+
+ public SHistoryContactor(String searchValue) {
+ this.searchValue = searchValue;
+ this.searchIcon = -3;
+ this.removeIcon = -3;
+ }
+
+ public String getSearchValue() {
+ return searchValue;
+ }
+
+ public void setSearchValue(String searchValue) {
+ this.searchValue = searchValue;
+ }
+
+ public int getSearchIcon() {
+ return searchIcon;
+ }
+
+ public void setSearchIcon(int searchIcon) {
+ this.searchIcon = searchIcon;
+ }
+
+ public int getRemoveIcon() {
+ return removeIcon;
+ }
+
+ public void setRemoveIcon(int removeIcon) {
+ this.removeIcon = removeIcon;
+ }
+}
diff --git a/supersearch/src/main/java/com/xcl/supersearch/SRContactor.java b/supersearch/src/main/java/com/xcl/supersearch/SRContactor.java
new file mode 100644
index 0000000..caae89a
--- /dev/null
+++ b/supersearch/src/main/java/com/xcl/supersearch/SRContactor.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2022 田梓萱, xcl@xuegao-tzx.top
+ *
+ * Licensed under the GNU Affero General Public License, Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.gnu.org/licenses/agpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.xcl.supersearch;
+
+public class SRContactor {
+ private String title = null;
+ private String message = null;
+ private String bt1 = null;
+ private String bt2 = null;
+ private String bt3 = null;
+ private String bt4 = null;
+
+ public SRContactor(String title, String message, String bt1, String bt2, String bt3, String bt4) {
+ this.title = title;
+ this.message = message;
+ this.bt1 = bt1;
+ this.bt2 = bt2;
+ this.bt3 = bt3;
+ this.bt4 = bt4;
+ }
+
+ public SRContactor(String title, String bt1, String bt2, String bt3, String bt4) {
+ this.title = title;
+ this.bt1 = bt1;
+ this.bt2 = bt2;
+ this.bt3 = bt3;
+ this.bt4 = bt4;
+ }
+
+ public SRContactor(String title, String message) {
+ this.title = title;
+ this.message = message;
+ }
+
+ public String getBt1() {
+ return bt1;
+ }
+
+ public void setBt1(String bt1) {
+ this.bt1 = bt1;
+ }
+
+ public String getBt2() {
+ return bt2;
+ }
+
+ public void setBt2(String bt2) {
+ this.bt2 = bt2;
+ }
+
+ public String getBt3() {
+ return bt3;
+ }
+
+ public void setBt3(String bt3) {
+ this.bt3 = bt3;
+ }
+
+ public String getBt4() {
+ return bt4;
+ }
+
+ public void setBt4(String bt4) {
+ this.bt4 = bt4;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getCXinxi() {
+ return title + message;
+ }
+}
diff --git a/supersearch/src/main/java/com/xcl/supersearch/SearchView.java b/supersearch/src/main/java/com/xcl/supersearch/SearchView.java
new file mode 100644
index 0000000..b1900fd
--- /dev/null
+++ b/supersearch/src/main/java/com/xcl/supersearch/SearchView.java
@@ -0,0 +1,1024 @@
+/*
+ * Copyright 2022 田梓萱, xcl@xuegao-tzx.top
+ *
+ * Licensed under the GNU Affero General Public License, Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.gnu.org/licenses/agpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.xcl.supersearch;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.colors.RgbColor;
+import ohos.agp.components.*;
+import ohos.agp.components.element.Element;
+import ohos.agp.components.element.PixelMapElement;
+import ohos.agp.components.element.ShapeElement;
+import ohos.agp.utils.Color;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+
+import static com.xcl.supersearch.Utils.*;
+
+public class SearchView extends DependentLayout implements Component.BindStateChangedListener, ContactProviderSR.AdapterClickListener {
+ private static final HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x00234, "SearchView");
+ private static final float DEFAULT_DIM_AMOUNT = 0.5f;
+ private int SuggestionCount = 5;
+ private List CXList;
+ private List ANSList;
+ private ContactProviderSR CPSR;
+ private Context context;
+ private SearchView SV;
+ private Component backComponent = null;
+ private ListContainer ListContaine;
+ private RoundProgressBar RoundPB;
+ private boolean isShow;
+ private Element HistoryPicture;
+ private Element DelHistoryPicture;
+ private boolean isRightClearButtonEnabled;
+ private boolean isDebugEnabled;
+ private boolean isWearable;
+ private int InputHintColor;
+ private boolean NullWarnByMySelf;
+ private String NullWarnText;
+ private int NullWarnColor;
+ private boolean NoneWarnByMySelf;
+ private String NoneWarnText;
+ private int NoneWarnColor;
+ private int InputTextColor;
+ private int InputCursorColor;
+ private int InputButtomColor;
+ private int LeftLoadColor;
+ private int InputBackgroundColor;
+ private int QueryRadius = -1;
+ private float BackMaskDegree;
+ private int BackMaskColor;
+ private Element LeftBackButton;
+ private Element RightButtonCustom;
+ private Element RightClearInputButton;
+ private String QueryInputHint = "";
+ private List SuggestionList = new ArrayList<>(0);
+ private Component Divider;
+ private Image LeftBtnImage;
+ private Image RightBtnImage;
+ private Image ClearInputBtnImage;
+ private RoundProgressBar RPB_System;
+ private TextField InputSearchText;
+ private Component SuggestionContainer;
+ private ListContainer listContainer;
+ private BackgroundLoadingAnimation backgroundEnterAnimation;
+ private BackgroundLoadingAnimation backgroundExitAnimation;
+ private BackClickListener backClickListener;
+ private SearchListener searchListener;
+ private CustomListener customListener;
+ private RemoveListener removeListener;
+ private HistoryProvider hisyoryprovider;
+ private State state;
+ private Component searchLayout;
+ private AnimatorValue animExpand;
+ private AnimatorValue historyAnim;
+ private AnimatorValue animFilter;
+ private Bt1Listener bt1Listener;
+ private Bt2Listener bt2Listener;
+ private Bt3Listener bt3Listener;
+ private Bt4Listener bt4Listener;
+ private NullWarnListener nullWarnListener;
+ private NoneWarnListener noneWarnListener;
+ private final SearchListener SListener = new SearchListener() {
+ @Override
+ public void onSearch(String search) {
+ ListContaine.setVisibility(Component.HIDE);
+ if ("".equals(search) || search == null) {
+ context.getUITaskDispatcher().delayDispatch(new Runnable() {
+ @Override
+ public void run() {
+ Utils.warn(SearchView.label, "空搜索警告");
+ if (NullWarnByMySelf) {
+ nullWarnListener.onNullError();
+ }
+ InputSearchText.setHint(NullWarnText);
+ InputSearchText.setHintColor(new Color(NullWarnColor));
+ RPB_System.setVisibility(Component.HIDE);
+ LeftBtnImage.setVisibility(Component.VISIBLE);
+ }
+ }, 1000);
+
+ } else {
+ InputSearchText.setHint(QueryInputHint);
+ InputSearchText.setHintColor(new Color(InputHintColor));
+ RoundPB.setVisibility(Component.VISIBLE);
+ if (backComponent != null) {
+ backComponent.setVisibility(Component.HIDE);
+ }
+ ANSList = SearchView.getListData(search, CXList);
+ context.getUITaskDispatcher().delayDispatch(new Runnable() {
+ @Override
+ public void run() {
+ Utils.debug(SearchView.label, "非空搜索");
+ for (int i = 0; i < ANSList.size(); i++) {
+ Utils.info(SearchView.label, i + "." + ANSList.get(i).getTitle());
+ }
+ if (!ANSList.isEmpty()) {
+ Utils.warn(SearchView.label, "搜索结果非空");
+ CPSR.setData(ANSList);
+ CPSR.notifyDataChanged();
+ ListContaine.setVisibility(Component.VISIBLE);
+ RoundPB.setVisibility(Component.HIDE);
+ RPB_System.setVisibility(Component.HIDE);
+ LeftBtnImage.setVisibility(Component.VISIBLE);
+ } else {
+ Utils.warn(SearchView.label, "搜索结果为空");
+ RoundPB.setVisibility(Component.HIDE);
+ InputSearchText.setText("");
+ if (NoneWarnByMySelf) {
+ noneWarnListener.onNullWarn();
+ }
+ InputSearchText.setHint(NoneWarnText);
+ InputSearchText.setHintColor(new Color(NoneWarnColor));
+ RPB_System.setVisibility(Component.HIDE);
+ LeftBtnImage.setVisibility(Component.VISIBLE);
+ backComponent.setVisibility(Component.VISIBLE);
+ }
+
+ }
+ }, 1000);
+ if (isShow) {
+ Utils.debug(SearchView.label, "搜索历史列表增加新搜索记录");
+ List suggestionItems = getSuggestionItems();
+ Utils.debug(label, suggestionItems.size() + "个搜索记录");
+ boolean has = false;
+ for (SHistoryContactor item : suggestionItems) {
+ if (search.equals(item.getSearchValue())) {
+ has = true;
+ break;
+ }
+ }
+ if (!has) {
+ addSuggestionItems(new SHistoryContactor(search,
+ -3,
+ -3
+ ), 0);
+ }
+ }
+ }
+ }
+ };
+
+ SearchView(Context context) {
+ this(context, null);
+ }
+
+ public SearchView(Context context, AttrSet attrSet) {
+ this(context, attrSet, "");
+ }//TODO:修饰符务必为public
+
+ public SearchView(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ resManager = context.getResourceManager();
+ initDefault();
+ initAttrSet(attrSet);
+ initAnimation();
+ initView();
+ setEditView();
+ setDefaultBackground();
+ setBindStateChangedListener(this);
+ }//TODO:修饰符务必为public
+
+ private static void showKeyboard() {
+ try {
+ Class inputClass = Class.forName("ohos.miscservices.inputmethod.InputMethodController");
+ Method method = inputClass.getMethod("getInstance");
+ Object object = method.invoke(new Object[]{});
+ Method startInput = inputClass.getMethod("startInput", int.class, boolean.class);
+ startInput.invoke(object, 1, true);
+ } catch (Exception e) {
+ Utils.error(SearchView.label, e.getMessage());
+ }
+ }
+
+ private static List getListData(String searchValue, List CXList) {
+ List List = new ArrayList<>();
+ CXList.stream().filter(new Predicate() {
+ @Override
+ public boolean test(SRContactor e) {
+ return e.getCXinxi().contains(searchValue);
+ }
+ }).forEachOrdered(new Consumer() {
+ @Override
+ public void accept(SRContactor object) {
+ List.add(object);
+ }
+ });
+ return List;
+ }
+
+ private void filterSearchValue(String s) {
+ if (!isShow || SuggestionList == null || SuggestionList.isEmpty()) {
+ return;
+ }
+ try {
+ List list;
+ if ("".equals(s)) {
+ list = SuggestionList;
+ } else {
+ list = new ArrayList<>();
+ for (SHistoryContactor item : SuggestionList) {
+ String searchValue = item.getSearchValue();
+ if (searchValue == null) {
+ continue;
+ }
+ if (searchValue.equals("") || searchValue.toLowerCase().startsWith(s.toLowerCase())) {
+ list.add(item);
+ }
+ }
+ }
+ Utils.debug(label, list.size() + "个搜索记录");
+ hisyoryprovider.setData(list);
+ hisyoryprovider.notifyDataChanged();
+ } catch (Exception e) {
+ Utils.error(SearchView.label, e.getMessage());
+ }
+ }
+
+ private void startResetHistoryHeightAnimation() {
+ if (animFilter != null && animFilter.isRunning()) {
+ return;
+ }
+ try {
+ int ch = SuggestionContainer.getHeight();
+ int mh;
+ if (iswear) {
+ mh = AttrHelper.vp2px(24, getContext()) * (Math.min(hisyoryprovider.getCount(), SuggestionCount));
+ } else {
+ mh = AttrHelper.vp2px(48, getContext()) * (Math.min(hisyoryprovider.getCount(), SuggestionCount));
+ }
+ int tem = mh - ch;
+ if (tem != 0) {
+ animFilter = new AnimatorValue();
+ animFilter.setDuration(100);
+ animFilter.setCurveType(Animator.CurveType.LINEAR);
+ animFilter.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ SuggestionContainer.setHeight((int) (ch + tem * v));
+ }
+ }
+ );
+ animFilter.setStateChangedListener(new Animator.StateChangedListener() {
+ @Override
+ public void onStart(Animator animator) {
+
+ }
+
+ @Override
+ public void onStop(Animator animator) {
+ hisyoryprovider.notifyDataChanged();
+ }
+
+ @Override
+ public void onCancel(Animator animator) {
+
+ }
+
+ @Override
+ public void onEnd(Animator animator) {
+
+ }
+
+ @Override
+ public void onPause(Animator animator) {
+
+ }
+
+ @Override
+ public void onResume(Animator animator) {
+
+ }
+ });
+ animFilter.start();
+ }
+ } catch (Exception e) {
+ Utils.error(SearchView.label, e.getMessage());
+ }
+ }
+
+ private void historyAnimationStart(boolean expand) {
+ int historyHeight = Math.min(hisyoryprovider.getCount(), SuggestionCount) * AttrHelper.vp2px(48, getContext());
+ if ((historyAnim != null && historyAnim.isRunning())
+ || (expand && historyHeight == SuggestionContainer.getHeight())) {
+ return;
+ }
+ historyAnim = new AnimatorValue();
+ historyAnim.setCurveType(Animator.CurveType.LINEAR);
+ historyAnim.setDuration(200);
+ historyAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ if (expand) {
+ SuggestionContainer.setHeight((int) (historyHeight * v));
+ } else {
+ SuggestionContainer.setHeight((int) (historyHeight * (1f - v)));
+ }
+ }
+ });
+ historyAnim.start();
+ }
+
+ private void setDefaultBackground() {
+ try {
+ ShapeElement element = new ShapeElement();
+ element.setRgbColor(RgbColor.fromArgbInt(BackMaskColor));
+ if (InputSearchText.hasFocus()) {
+ element.setAlpha((int) (0xFF * BackMaskDegree));
+ } else {
+ element.setAlpha(0);
+ }
+ setBackground(element);
+ setClickedListener(new ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ InputSearchText.clearFocus();
+ }
+ });
+ setClickable(InputSearchText.hasFocus());
+ } catch (Exception e) {
+ Utils.error(SearchView.label, e.getMessage());
+ }
+ }
+
+ private void initAnimation() {
+ try {
+ Utils.debug(SearchView.label, "initAnimation");
+ backgroundEnterAnimation = new BackgroundLoadingAnimation(
+ this,
+ 0f,
+ BackMaskDegree
+ );
+
+ backgroundExitAnimation = new BackgroundLoadingAnimation(
+ this,
+ BackMaskDegree,
+ 0f
+ );
+ } catch (Exception e) {
+ Utils.error(SearchView.label, e.getMessage());
+ }
+ }
+
+ private void initDefault() {
+ try {
+ InputHintColor = getContext().getColor(Color.getIntColor("#FFA0A0A0"));
+ InputTextColor = getContext().getColor(Color.getIntColor("#FFA5A5A5"));
+ InputCursorColor = getContext().getColor(Color.getIntColor("#A18770B1"));
+ InputButtomColor = getContext().getColor(Color.getIntColor("#A18770B1"));
+ LeftLoadColor = getContext().getColor(Color.getIntColor("#FF8377FF"));
+ InputBackgroundColor = getContext().getColor(Color.getIntColor("#FFFFFFFF"));
+ BackMaskColor = getContext().getColor(Color.getIntColor("#FF000000"));
+ NullWarnColor = getContext().getColor(Color.getIntColor("#63FF0000"));
+ NoneWarnColor = getContext().getColor(Color.getIntColor("#63FF0000"));
+ QueryRadius = AttrHelper.vp2px(2, getContext());
+ try {
+ LeftBackButton = new PixelMapElement(getContext().getResourceManager().getResource(ResourceTable.Media_ic_arrow_left_black_24dp));
+ RightClearInputButton = new PixelMapElement(getContext().getResourceManager().getResource(ResourceTable.Media_ic_close_black_24dp));
+ HistoryPicture = new PixelMapElement(getContext().getResourceManager().getResource(ResourceTable.Media_ic_history_black_24dp));
+ DelHistoryPicture = new PixelMapElement(getContext().getResourceManager().getResource(ResourceTable.Media_ic_close_black_24dp));
+ } catch (Exception e) {
+ Utils.error(SearchView.label, e.getMessage());
+ }
+ QueryInputHint = HQString(ResourceTable.String_search_hint_text_);
+ BackMaskDegree = SearchView.DEFAULT_DIM_AMOUNT;
+ NullWarnText = HQString(ResourceTable.String_search_input_null);
+ NoneWarnText = HQString(ResourceTable.String_search_answer_none);
+ isRightClearButtonEnabled = true;
+ isDebugEnabled = false;
+ isShow = false;
+ state = State.EXPANDED;
+ } catch (Exception e) {
+ Utils.error(SearchView.label, e.getMessage());
+ }
+ }
+
+ private void initAttrSet(AttrSet attributes) {
+ if (attributes == null) {
+ return;
+ }
+ isRightClearButtonEnabled = getBoolean(attributes, "isrightButton_ClearEnabled", isRightClearButtonEnabled);
+ isDebugEnabled = getBoolean(attributes, "isDebugEnabled", isDebugEnabled);
+ pd_pd = isDebugEnabled;
+ isWearable = getBoolean(attributes, "isWearable", isWearable);
+ iswear = isWearable;
+ InputHintColor = getColor(attributes, "queryInput_hint_color", InputHintColor);
+ InputTextColor = getColor(attributes, "queryInput_text_color", InputTextColor);
+ InputCursorColor = getColor(attributes, "queryInput_cursor_color", InputCursorColor);
+ InputButtomColor = getColor(attributes, "queryInput_buttom_color", InputButtomColor);
+ LeftLoadColor = getColor(attributes, "leftButton_Loadding_color", LeftLoadColor);
+ InputBackgroundColor = getColor(attributes, "queryInput_background_color", InputBackgroundColor);
+ HistoryPicture = getElement(attributes, "search_history", HistoryPicture);
+ DelHistoryPicture = getElement(attributes, "delete_search_history", DelHistoryPicture);
+ BackMaskDegree = getFloat(attributes, "background_mask_degree", BackMaskDegree);
+ BackMaskColor = getColor(attributes, "background_mask_color", BackMaskColor);
+ QueryRadius = getDimension(attributes, "queryRadius", QueryRadius);
+ LeftBackButton = getElement(attributes, "leftButton_Back", LeftBackButton);
+ RightButtonCustom = getElement(attributes, "RightButtonCustom", RightButtonCustom);
+ RightClearInputButton = getElement(attributes, "rightButton_Clear", RightClearInputButton);
+ NullWarnByMySelf = getBoolean(attributes, "nullWarnByMySelf", NullWarnByMySelf);
+ NullWarnText = getString(attributes, "null_warn_text", NullWarnText);
+ NullWarnColor = getColor(attributes, "null_warn_text_color", NullWarnColor);
+ NoneWarnByMySelf = getBoolean(attributes, "noneWarnByMySelf", NoneWarnByMySelf);
+ NoneWarnText = getString(attributes, "none_warn_text", NoneWarnText);
+ NoneWarnColor = getColor(attributes, "none_warn_text_color", NoneWarnColor);
+ QueryInputHint = getString(attributes, "queryInput_hint_text", QueryInputHint);
+ SuggestionCount = Integer.parseInt(getString(attributes, "suggestion_count", String.valueOf(SuggestionCount)));
+ if (iswear) {
+ if (SuggestionCount > 6) {
+ SuggestionCount = 6;
+ }
+ }
+ }
+
+ private void initView() {
+ try {
+ if (iswear) {
+ searchLayout = LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_search_vieww, this, false);
+ } else {
+ searchLayout = LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_search_view, this, false);
+ }
+
+ StackLayout.LayoutConfig config = new StackLayout.LayoutConfig();
+ config.width = ComponentContainer.LayoutConfig.MATCH_PARENT;
+ config.height = ComponentContainer.LayoutConfig.MATCH_CONTENT;
+ Element element = searchLayout.getBackgroundElement();
+ if (element instanceof ShapeElement) {
+ ShapeElement e = (ShapeElement) element;
+ if (QueryRadius != -1) {
+ e.setCornerRadius(QueryRadius);
+ }
+ if (InputBackgroundColor != 0) {
+ e.setRgbColor(RgbColor.fromArgbInt(InputBackgroundColor));
+ }
+ }
+ addComponent(searchLayout, config);
+ LeftBtnImage = (Image) findComponentById(ResourceTable.Id_leftBtnIv);
+ RPB_System = (RoundProgressBar) findComponentById(ResourceTable.Id_progressBar);
+ InputSearchText = (TextField) findComponentById(ResourceTable.Id_inputEt);
+ ClearInputBtnImage = (Image) findComponentById(ResourceTable.Id_clearInputBtnIv);
+ RightBtnImage = (Image) findComponentById(ResourceTable.Id_rightBtnIv);
+ SuggestionContainer = findComponentById(ResourceTable.Id_suggestionsContainerLl);
+ Divider = findComponentById(ResourceTable.Id_divider);
+ listContainer = (ListContainer) findComponentById(ResourceTable.Id_suggestionsRecyclerView);
+ InputSearchText.setHintColor(new Color(InputHintColor));
+ InputSearchText.setTextColor(new Color(InputTextColor));
+ RPB_System.setBackgroundColor(LeftLoadColor);
+ ShapeElement dividerElement = new ShapeElement();
+ dividerElement.setRgbColor(RgbColor.fromArgbInt(InputButtomColor));
+ Divider.setBackground(dividerElement);
+ LeftBtnImage.setImageElement(LeftBackButton);
+ ClearInputBtnImage.setImageElement(RightClearInputButton);
+ RightBtnImage.setVisibility(RightButtonCustom == null ? Component.HIDE : Component.VISIBLE);
+ RightBtnImage.setImageElement(RightButtonCustom);
+ InputSearchText.setHint(QueryInputHint);
+ SuggestionContainer.setVisibility(Component.HIDE);
+ } catch (Exception e) {
+ Utils.error(SearchView.label, e.getMessage());
+ }
+ ClearInputBtnImage.setClickedListener(new ClickedListener() {
+ private void run() {
+ InputSearchText.requestFocus();
+ SearchView.showKeyboard();
+ }
+
+ @Override
+ public void onClick(Component component1) {
+ InputSearchText.setText("");
+ if (!InputSearchText.hasFocus()) {
+ getContext().getUITaskDispatcher().delayDispatch(this::run, 130);
+ }
+ }
+ });
+ RightBtnImage.setClickedListener(new ClickedListener() {
+ @Override
+ public void onClick(Component component14) {
+ if (customListener != null) {
+ customListener.onFilter(InputSearchText.getText());
+ }
+ }
+ });
+ LeftBtnImage.setClickedListener(new ClickedListener() {
+ @Override
+ public void onClick(Component component13) {
+ Utils.debug(SearchView.label, "Left返回Btn onClick");
+ if (InputSearchText.hasFocus()) {
+ InputSearchText.clearFocus();
+ } else if (backClickListener != null) {
+ backClickListener.onBackClick();
+ }
+ }
+ });
+ listContainer.setItemClickedListener(new ListContainer.ItemClickedListener() {
+ @Override
+ public void onItemClicked(ListContainer listContainer, Component component, int i, long l) {
+ Utils.debug(SearchView.label, "搜索建议列表点击了第" + i + "行");
+ SHistoryContactor item = hisyoryprovider.getItem(i);
+ InputSearchText.setText(item.getSearchValue());
+ InputSearchText.clearFocus();
+ if (searchListener != null) {
+ searchListener.onSearch(InputSearchText.getText());
+ }
+ }
+ });
+ InputSearchText.setEditorActionListener(new Text.EditorActionListener() {
+ @Override
+ public boolean onTextEditorAction(int i) {
+ Utils.debug(SearchView.label, "点击了键盘自带的搜索按钮");
+ InputSearchText.clearFocus();
+ RPB_System.setVisibility(Component.VISIBLE);
+ LeftBtnImage.setVisibility(Component.HIDE);
+ if (searchListener != null) {
+ searchListener.onSearch(InputSearchText.getText());
+ }
+ return true;
+ }
+ });
+ }
+
+ @Override
+ public void ann1(int position) {
+ if (bt1Listener != null) {
+ bt1Listener.onbT1(position);
+ }
+ }
+
+ @Override
+ public void ann2(int position) {
+ if (bt2Listener != null) {
+ bt2Listener.onbT2(position);
+ }
+ }
+
+ @Override
+ public void ann3(int position) {
+ if (bt3Listener != null) {
+ bt3Listener.onbT3(position);
+ }
+ }
+
+ @Override
+ public void ann4(int position) {
+ if (bt4Listener != null) {
+ bt4Listener.onbT4(position);
+ }
+ }
+
+ private void setEditView() {
+ try {
+ InputSearchText.setFocusChangedListener(new FocusChangedListener() {
+ @Override
+ public void onFocusChange(Component component, boolean b) {
+ if (b) {
+ backgroundEnterAnimation.start();
+ } else {
+ backgroundExitAnimation.start();
+ }
+ if (isShow) {
+ historyAnimationStart(b);
+ }
+ }
+ });
+ InputSearchText.addTextObserver(new Text.TextObserver() {
+ @Override
+ public void onTextUpdated(String s, int i, int i1, int i2) {
+ if (isRightClearButtonEnabled) {
+ if ("".equals(s)) {
+ ClearInputBtnImage.setVisibility(Component.HIDE);
+ } else {
+ ClearInputBtnImage.setVisibility(Component.VISIBLE);
+ }
+ }
+ filterSearchValue(s);
+ }
+ });
+ } catch (Exception e) {
+ Utils.error(SearchView.label, e.getMessage());
+ }
+ }
+
+ private List getSuggestionItems() {
+ return SuggestionList;
+ }
+
+ private void addSuggestionItems(SHistoryContactor suggestions, int position) {
+ if (SuggestionList == null) {
+ SuggestionList = new ArrayList<>();
+ }
+ SuggestionList.add(position, suggestions);
+ Utils.debug(label, SuggestionList.size() + "个搜索记录");
+ }
+
+ public void Onsearch(Context contex, ListContainer ListContai, SearchView sv, Component backComponen, RoundProgressBar pgb, List cslist, List suggestions, boolean ishow) {
+ try {
+ context = contex;
+ RoundPB = pgb;
+ SV = sv;
+ CXList = cslist;
+ isShow = ishow;
+ backComponent = backComponen;
+ CPSR = new ContactProviderSR(context);
+ CPSR.setAdapterClickListener(this);
+ ListContai.setItemProvider(CPSR);
+ ListContai.setVisibility(Component.HIDE);
+ ListContai.enableScrollBar(Component.AXIS_Y, true);
+ ListContai.setLongClickable(false);
+ ListContai.setScrollbarRoundRect(true);
+ ListContai.setScrollbarRadius(ListContai.getScrollbarThickness() / 2);
+ ListContaine = ListContai;
+ setSearchListener(SListener);
+ SuggestionList = suggestions;
+ if (ishow) {
+ SuggestionContainer.setVisibility(Component.VISIBLE);
+ hisyoryprovider = new HistoryProvider(SuggestionList);
+ listContainer.setItemProvider(hisyoryprovider);
+ }
+ } catch (Exception e) {
+ Utils.error(SearchView.label, e.getMessage());
+ }
+ }
+
+ public SearchView setContext(Context contex) {
+ context = contex;
+ return Builder();
+ }
+
+ public SearchView setRoundProgressBar(RoundProgressBar pgb) {
+ RoundPB = pgb;
+ return Builder();
+ }
+
+ public SearchView setSearchView(SearchView sv) {
+ SV = sv;
+ return Builder();
+ }
+
+ public SearchView setSRListContainer(List cslist) {
+ CXList = cslist;
+ return Builder();
+ }
+
+ public SearchView setSuggestionisShow(boolean ishow) {
+ isShow = ishow;
+ return Builder();
+ }
+
+ public SearchView setBackComponent(Component BackComponent) {
+ backComponent = BackComponent;
+ return Builder();
+ }
+
+ public SearchView setListContainer(ListContainer ListContai) {
+ CPSR = new ContactProviderSR(context);
+ CPSR.setAdapterClickListener(this);
+ ListContai.setItemProvider(CPSR);
+ ListContai.setVisibility(Component.HIDE);
+ ListContai.enableScrollBar(Component.AXIS_Y, true);
+ ListContai.setLongClickable(false);
+ ListContai.setScrollbarRoundRect(true);
+ ListContai.setScrollbarRadius(ListContai.getScrollbarThickness() / 2);
+ ListContaine = ListContai;
+ return Builder();
+ }
+
+ public SearchView setSuggestionList(List suggestions) {
+ SuggestionList = suggestions;
+ return Builder();
+ }
+
+ public SearchView Builder() {
+ Utils.debug(SearchView.label, "Builder");
+ if (isShow) {
+ SuggestionContainer.setVisibility(Component.VISIBLE);
+ hisyoryprovider = new HistoryProvider(SuggestionList);
+ listContainer.setItemProvider(hisyoryprovider);
+ }
+ setSearchListener(SListener);
+ return this;
+ }
+
+ public void Onsearch(Context contex, ListContainer ListContai, SearchView sv, Component backComponen, RoundProgressBar pgb, List cslist, boolean ishow) {
+ try {
+ context = contex;
+ RoundPB = pgb;
+ SV = sv;
+ CXList = cslist;
+ isShow = ishow;
+ backComponent = backComponen;
+ CPSR = new ContactProviderSR(context);
+ CPSR.setAdapterClickListener(this);
+ ListContai.setItemProvider(CPSR);
+ ListContai.setVisibility(Component.HIDE);
+ ListContai.enableScrollBar(Component.AXIS_Y, true);
+ ListContai.setLongClickable(false);
+ ListContai.setScrollbarRoundRect(true);
+ ListContai.setScrollbarRadius(ListContai.getScrollbarThickness() / 2);
+ ListContaine = ListContai;
+ setSearchListener(SListener);
+ if (ishow) {
+ SuggestionContainer.setVisibility(Component.VISIBLE);
+ hisyoryprovider = new HistoryProvider(SuggestionList);
+ listContainer.setItemProvider(hisyoryprovider);
+ }
+ } catch (Exception e) {
+ Utils.error(SearchView.label, e.getMessage());
+ }
+ }
+
+ public void Onsearch(Context contex, ListContainer ListContai, SearchView sv, Component backComponen, RoundProgressBar pgb, List cslist) {
+ try {
+ context = contex;
+ RoundPB = pgb;
+ SV = sv;
+ CXList = cslist;
+ isShow = false;
+ backComponent = backComponen;
+ CPSR = new ContactProviderSR(context);
+ CPSR.setAdapterClickListener(this);
+ ListContai.setItemProvider(CPSR);
+ ListContai.setVisibility(Component.HIDE);
+ ListContai.enableScrollBar(Component.AXIS_Y, true);
+ ListContai.setLongClickable(false);
+ ListContai.setScrollbarRoundRect(true);
+ ListContai.setScrollbarRadius(ListContai.getScrollbarThickness() / 2);
+ ListContaine = ListContai;
+ setSearchListener(SListener);
+ } catch (Exception e) {
+ Utils.error(SearchView.label, e.getMessage());
+ }
+ }
+
+ @Override
+ public void onComponentBoundToWindow(Component component) {
+ getContext().getUITaskDispatcher()
+ .delayDispatch(new Runnable() {
+ @Override
+ public void run() {
+ InputSearchText.requestFocus();
+ SearchView.showKeyboard();
+ }
+ },
+ 200);
+ }
+
+ @Override
+ public void onComponentUnboundFromWindow(Component component) {
+
+ }
+
+ public void setBackClickListener(BackClickListener backClickListener) {
+ this.backClickListener = backClickListener;
+ }
+
+ private void setSearchListener(SearchListener searchListener) {
+ this.searchListener = searchListener;
+ }
+
+ public void setCustomListener(CustomListener customlistener) {
+ customListener = customlistener;
+ }
+
+ public void setBt1Listener(Bt1Listener B1L) {
+ bt1Listener = B1L;
+ }
+
+ public void setBt2Listener(Bt2Listener B2L) {
+ bt2Listener = B2L;
+ }
+
+ public void setBt3Listener(Bt3Listener B3L) {
+ bt3Listener = B3L;
+ }
+
+ public void setBt4Listener(Bt4Listener B4L) {
+ bt4Listener = B4L;
+ }
+
+ public void setNullWarnListener(NullWarnListener nullWarn) {
+ nullWarnListener = nullWarn;
+ }
+
+ public void setNoneWarnListener(NoneWarnListener noneWarn) {
+ noneWarnListener = noneWarn;
+ }
+
+ public void setRemoveListener(RemoveListener removeListener) {
+ this.removeListener = removeListener;
+ }
+
+ public boolean isExpand() {
+ return state == State.EXPANDED;
+ }
+
+ public void showSearchView() {
+ startExpandAnimation(true);
+ }
+
+ public void hideSearchView() {
+ startExpandAnimation(false);
+ }
+
+ public void onScroll(Component component, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
+ if (InputSearchText.hasFocus()) {
+ InputSearchText.clearFocus();
+ }
+ }
+
+ private synchronized void startExpandAnimation(boolean expand) {
+ if (animExpand != null && animExpand.isRunning()) {
+ return;
+ }
+ state = expand ? State.EXPANDED : State.COLLAPSED;
+ animExpand = new AnimatorValue();
+ animExpand.setCurveType(Animator.CurveType.LINEAR);
+ animExpand.setDuration(200);
+ animExpand.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ animSearchView(v);
+ }
+ });
+ animExpand.start();
+ }
+
+ private void animSearchView(float v) {
+ int tem = searchLayout.getMarginTop() + searchLayout.getHeight() + getPaddingTop() + getPaddingBottom();
+ setTranslationY(-tem * (state == State.EXPANDED ? (1f - v) : v));
+ }
+
+
+ private enum State {
+ EXPANDED,
+ COLLAPSED
+ }
+
+ public interface BackClickListener {
+ void onBackClick();
+ }
+
+ public interface SearchListener {
+ void onSearch(String search);
+ }
+
+ public interface CustomListener {
+ void onFilter(String filter);
+ }
+
+ public interface Bt1Listener {
+ void onbT1(int position);
+ }
+
+ public interface Bt2Listener {
+ void onbT2(int position);
+ }
+
+ public interface Bt3Listener {
+ void onbT3(int position);
+ }
+
+ public interface Bt4Listener {
+ void onbT4(int position);
+ }
+
+ public interface NullWarnListener {
+ void onNullError();
+ }
+
+ public interface NoneWarnListener {
+ void onNullWarn();
+ }
+
+ public interface RemoveListener {
+ void onRemoveHistory(int position, SHistoryContactor suggestion);
+ }
+
+ private class HistoryProvider extends BaseItemProvider {
+ private List mData;
+
+ HistoryProvider(List data) {
+ mData = data;
+ }
+
+ void setData(List mData) {
+ this.mData = mData;
+ }
+
+ @Override
+ public int getCount() {
+ return mData == null ? 0 : mData.size();
+ }
+
+ @Override
+ public void notifyDataChanged() {
+ startResetHistoryHeightAnimation();
+ super.notifyDataChanged();
+ }
+
+ @Override
+ public SHistoryContactor getItem(int i) {
+ return mData.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+ @Override
+ public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
+ ViewHolder holder;
+ if (component == null) {
+ holder = new ViewHolder();
+ if (iswear) {
+ component = LayoutScatter.getInstance(componentContainer.getContext())
+ .parse(ResourceTable.Layout_persistent_search_view_suggestion_item_layoutw, componentContainer, false);
+ } else {
+ component = LayoutScatter.getInstance(componentContainer.getContext())
+ .parse(ResourceTable.Layout_persistent_search_view_suggestion_item_layout, componentContainer, false);
+ }
+
+ holder.iconIv = (Image) component.findComponentById(ResourceTable.Id_iconIv);
+ holder.removeBtnIv = (Image) component.findComponentById(ResourceTable.Id_removeBtnIv);
+ holder.textTv = (Text) component.findComponentById(ResourceTable.Id_textTv);
+ holder.removeBtnWrapperFl = component.findComponentById(ResourceTable.Id_removeBtnWrapperFl);
+ component.setTag(holder);
+ } else {
+ holder = (ViewHolder) component.getTag();
+ }
+ SHistoryContactor item = getItem(i);
+ if (item.getSearchValue() == null) {
+ holder.textTv.setText("");
+ } else {
+ holder.textTv.setText(item.getSearchValue());
+ }
+ if (item.getSearchIcon() == -1) {
+ holder.iconIv.setVisibility(Component.HIDE);
+ } else {
+ holder.iconIv.setVisibility(Component.VISIBLE);
+ }
+ if (item.getRemoveIcon() == -1) {
+ holder.removeBtnWrapperFl.setVisibility(Component.HIDE);
+ } else {
+ holder.removeBtnWrapperFl.setVisibility(Component.VISIBLE);
+ }
+ try {
+ if (item.getSearchIcon() == -1) {
+ holder.iconIv.setImageElement(null);
+ }
+ if (item.getSearchIcon() == -3) {
+ holder.iconIv.setImageElement(HistoryPicture);
+ } else {
+ holder.iconIv.setImageElement(new PixelMapElement(componentContainer.getContext().getResourceManager().getResource(item.getSearchIcon())));
+ }
+ if (item.getRemoveIcon() == -1) {
+ holder.removeBtnIv.setImageElement(null);
+ } else if (item.getRemoveIcon() == -3) {
+ holder.removeBtnIv.setImageElement(DelHistoryPicture);
+ } else {
+ holder.removeBtnIv.setImageElement(new PixelMapElement(componentContainer.getContext().getResourceManager().getResource(item.getRemoveIcon())));
+ }
+ } catch (Exception e) {
+ Utils.error(SearchView.label, e.getMessage());
+ }
+ holder.removeBtnWrapperFl.setClickedListener(new ClickedListener() {
+ @Override
+ public void onClick(Component component1) {
+ mData.remove(i);
+ notifyDataChanged();
+ if (removeListener != null) {
+ removeListener.onRemoveHistory(i, item);
+ }
+ }
+ });
+ return component;
+ }
+
+ private class ViewHolder {
+ private Image iconIv;
+ private Image removeBtnIv;
+ private Text textTv;
+ private Component removeBtnWrapperFl;
+ }
+ }
+
+}
diff --git a/supersearch/src/main/java/com/xcl/supersearch/Utils.java b/supersearch/src/main/java/com/xcl/supersearch/Utils.java
new file mode 100644
index 0000000..fb949c4
--- /dev/null
+++ b/supersearch/src/main/java/com/xcl/supersearch/Utils.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2022 田梓萱, xcl@xuegao-tzx.top
+ *
+ * Licensed under the GNU Affero General Public License, Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.gnu.org/licenses/agpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.xcl.supersearch;
+
+import ohos.agp.colors.RgbColor;
+import ohos.agp.components.Attr;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.element.Element;
+import ohos.agp.components.element.ShapeElement;
+import ohos.agp.utils.Color;
+import ohos.agp.window.service.DisplayAttributes;
+import ohos.global.resource.ResourceManager;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+import java.util.Optional;
+
+public class Utils {
+ public static boolean pd_pd = false;
+ public static boolean iswear = false;
+ static ResourceManager resManager;
+
+ public static boolean getBoolean(AttrSet attrSet, String attrName, boolean defaultValue) {
+ if (attrSet == null || attrName == null || attrName.isEmpty()) {
+ return defaultValue;
+ }
+ Optional attrOptional = attrSet.getAttr(attrName);
+ if (attrOptional == null || !attrOptional.isPresent()) {
+ return defaultValue;
+ }
+ return attrOptional.get().getBoolValue();
+ }
+
+ public static float getFloat(AttrSet attrSet, String attrName, float defaultValue) {
+ if (attrSet == null || attrName == null || attrName.isEmpty()) {
+ return defaultValue;
+ }
+ Optional attrOptional = attrSet.getAttr(attrName);
+ if (attrOptional == null || !attrOptional.isPresent()) {
+ return defaultValue;
+ }
+ return attrOptional.get().getFloatValue();
+ }
+
+ public static int getColor(AttrSet attrSet, String attrName, int defaultColor) {
+ if (attrSet == null || attrName == null || attrName.isEmpty()) {
+ return defaultColor;
+ }
+
+ Optional attrOptional = attrSet.getAttr(attrName);
+ if (attrOptional == null || !attrOptional.isPresent()) {
+ return defaultColor;
+ }
+ return attrOptional.get().getColorValue().getValue();
+ }
+
+ public static int getDimension(AttrSet attrSet, String attrName, int defaultValue) {
+ if (attrSet == null || attrName == null || attrName.isEmpty()) {
+ return defaultValue;
+ }
+ Optional attrOptional = attrSet.getAttr(attrName);
+ if (attrOptional == null || !attrOptional.isPresent()) {
+ return defaultValue;
+ }
+ return attrOptional.get().getDimensionValue() * 3;
+ }
+
+ public static Element getElement(AttrSet attrSet, String attrName, Element defaultElement) {
+ if (attrSet == null || attrName == null || attrName.isEmpty()) {
+ return defaultElement;
+ }
+ Optional attrOptional = attrSet.getAttr(attrName);
+ if (attrOptional == null || !attrOptional.isPresent()) {
+ return defaultElement;
+ }
+ return attrOptional.get().getElement();
+ }
+
+ public static int vpToPx(float vp, DisplayAttributes displayAttributes) {
+ return (int) (vp * displayAttributes.densityPixels + 0.5f);
+ }
+
+ public static String getString(AttrSet attrSet, String attrName, String defaultValue) {
+ if (attrSet == null || attrName == null || attrName.isEmpty()) {
+ return defaultValue;
+ }
+ Optional attrOptional = attrSet.getAttr(attrName);
+ if (attrOptional == null || !attrOptional.isPresent()) {
+ return defaultValue;
+ }
+ return attrOptional.get().getStringValue();
+ }
+
+ public static String HQString(int a1) {
+ try {
+ String text = resManager.getElement(a1).getString();
+ return text;
+ } catch (Exception e) {
+ return e.getMessage();
+ }
+ }
+
+ public static Element adjustColorAlpha(int color, float alpha) {
+ final int alphaChannel = (int) (255 * alpha);
+ final int redChannel = (color >> 16) & 0xFF;
+ final int greenChannel = (color >> 8) & 0xFF;
+ final int blueChannel = color & 0xFF;
+
+ ShapeElement element = new ShapeElement();
+ element.setAlpha(alphaChannel);
+ element.setRgbColor(RgbColor.fromArgbInt(Color.rgb(redChannel, greenChannel, blueChannel)));
+ return element;
+ }
+
+ public static void info(HiLogLabel label, String message) {
+ if (pd_pd) {
+ HiLog.info(label, "信息:[" + message + "]");
+ }
+ }
+
+ public static void warn(HiLogLabel label, String message) {
+ if (pd_pd) {
+ HiLog.warn(label, "警告:[" + message + "]");
+ }
+ }
+
+ public static void error(HiLogLabel label, String message) {
+ if (pd_pd) {
+ HiLog.error(label, "错误:[" + message + "]");
+ }
+ }
+
+ public static void debug(HiLogLabel label, String message) {
+ if (pd_pd) {
+ HiLog.debug(label, "调试:[" + message + "]");
+ }
+ }
+
+ protected int makePressColor(int backgroundColor) {
+ int r = (backgroundColor >> 16) & 0xFF;
+ int g = (backgroundColor >> 8) & 0xFF;
+ int b = (backgroundColor) & 0xFF;
+ return Color.argb(128, r, g, b);
+ }
+}
diff --git a/supersearch/src/main/resources/base/element/string.json b/supersearch/src/main/resources/base/element/string.json
new file mode 100644
index 0000000..e0038b8
--- /dev/null
+++ b/supersearch/src/main/resources/base/element/string.json
@@ -0,0 +1,40 @@
+{
+ "string": [
+ {
+ "name": "searchmr",
+ "value": "搜索默认页面"
+ },
+ {
+ "name": "withoutSug",
+ "value": "无建议搜索"
+ },
+ {
+ "name": "recentSug",
+ "value": "有最近建议搜索"
+ },
+ {
+ "name": "hasknownSug",
+ "value": "有已知建议搜索"
+ },
+ {
+ "name": "suggestion_text",
+ "value": "建议文本"
+ },
+ {
+ "name": "search_hint_text",
+ "value": "搜索..."
+ },
+ {
+ "name": "search_hint_text_",
+ "value": "搜索."
+ },
+ {
+ "name": "search_input_null",
+ "value": "搜索值为空"
+ },
+ {
+ "name": "search_answer_none",
+ "value": "搜索结果为空"
+ }
+ ]
+}
diff --git a/supersearch/src/main/resources/base/graphic/background_list_item.xml b/supersearch/src/main/resources/base/graphic/background_list_item.xml
new file mode 100644
index 0000000..dc0bb07
--- /dev/null
+++ b/supersearch/src/main/resources/base/graphic/background_list_item.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/supersearch/src/main/resources/base/graphic/background_search_view.xml b/supersearch/src/main/resources/base/graphic/background_search_view.xml
new file mode 100644
index 0000000..d5761a7
--- /dev/null
+++ b/supersearch/src/main/resources/base/graphic/background_search_view.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/supersearch/src/main/resources/base/graphic/ic_search.xml b/supersearch/src/main/resources/base/graphic/ic_search.xml
new file mode 100644
index 0000000..6909712
--- /dev/null
+++ b/supersearch/src/main/resources/base/graphic/ic_search.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/supersearch/src/main/resources/base/layout/persistent_search_view_suggestion_item_layout.xml b/supersearch/src/main/resources/base/layout/persistent_search_view_suggestion_item_layout.xml
new file mode 100644
index 0000000..8cae393
--- /dev/null
+++ b/supersearch/src/main/resources/base/layout/persistent_search_view_suggestion_item_layout.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/supersearch/src/main/resources/base/layout/persistent_search_view_suggestion_item_layoutw.xml b/supersearch/src/main/resources/base/layout/persistent_search_view_suggestion_item_layoutw.xml
new file mode 100644
index 0000000..ed9e3fa
--- /dev/null
+++ b/supersearch/src/main/resources/base/layout/persistent_search_view_suggestion_item_layoutw.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/supersearch/src/main/resources/base/layout/search_view.xml b/supersearch/src/main/resources/base/layout/search_view.xml
new file mode 100644
index 0000000..01429cf
--- /dev/null
+++ b/supersearch/src/main/resources/base/layout/search_view.xml
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/supersearch/src/main/resources/base/layout/search_vieww.xml b/supersearch/src/main/resources/base/layout/search_vieww.xml
new file mode 100644
index 0000000..4e26380
--- /dev/null
+++ b/supersearch/src/main/resources/base/layout/search_vieww.xml
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/supersearch/src/main/resources/base/layout/searchres.xml b/supersearch/src/main/resources/base/layout/searchres.xml
new file mode 100644
index 0000000..c463e00
--- /dev/null
+++ b/supersearch/src/main/resources/base/layout/searchres.xml
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/supersearch/src/main/resources/base/layout/searchresw.xml b/supersearch/src/main/resources/base/layout/searchresw.xml
new file mode 100644
index 0000000..f3c9e6e
--- /dev/null
+++ b/supersearch/src/main/resources/base/layout/searchresw.xml
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/supersearch/src/main/resources/base/media/ic_arrow_left_black_18dp.png b/supersearch/src/main/resources/base/media/ic_arrow_left_black_18dp.png
new file mode 100644
index 0000000..379b6f5
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_arrow_left_black_18dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_arrow_left_black_24dp.png b/supersearch/src/main/resources/base/media/ic_arrow_left_black_24dp.png
new file mode 100644
index 0000000..7a9ff69
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_arrow_left_black_24dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_arrow_left_black_36dp.png b/supersearch/src/main/resources/base/media/ic_arrow_left_black_36dp.png
new file mode 100644
index 0000000..7ca278d
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_arrow_left_black_36dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_arrow_left_black_48dp.png b/supersearch/src/main/resources/base/media/ic_arrow_left_black_48dp.png
new file mode 100644
index 0000000..7987d8c
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_arrow_left_black_48dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_close_black_18dp.png b/supersearch/src/main/resources/base/media/ic_close_black_18dp.png
new file mode 100644
index 0000000..b56d2b4
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_close_black_18dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_close_black_24dp.png b/supersearch/src/main/resources/base/media/ic_close_black_24dp.png
new file mode 100644
index 0000000..8af456d
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_close_black_24dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_close_black_36dp.png b/supersearch/src/main/resources/base/media/ic_close_black_36dp.png
new file mode 100644
index 0000000..a75c6f4
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_close_black_36dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_close_black_48dp.png b/supersearch/src/main/resources/base/media/ic_close_black_48dp.png
new file mode 100644
index 0000000..6dddb5b
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_close_black_48dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_filter_variant_black_18dp.png b/supersearch/src/main/resources/base/media/ic_filter_variant_black_18dp.png
new file mode 100644
index 0000000..b702fee
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_filter_variant_black_18dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_filter_variant_black_24dp.png b/supersearch/src/main/resources/base/media/ic_filter_variant_black_24dp.png
new file mode 100644
index 0000000..1d5971d
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_filter_variant_black_24dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_filter_variant_black_36dp.png b/supersearch/src/main/resources/base/media/ic_filter_variant_black_36dp.png
new file mode 100644
index 0000000..22944aa
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_filter_variant_black_36dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_filter_variant_black_48dp.png b/supersearch/src/main/resources/base/media/ic_filter_variant_black_48dp.png
new file mode 100644
index 0000000..16cf88e
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_filter_variant_black_48dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_history_black_18dp.png b/supersearch/src/main/resources/base/media/ic_history_black_18dp.png
new file mode 100644
index 0000000..ca05fa6
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_history_black_18dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_history_black_24dp.png b/supersearch/src/main/resources/base/media/ic_history_black_24dp.png
new file mode 100644
index 0000000..ec48a1e
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_history_black_24dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_history_black_36dp.png b/supersearch/src/main/resources/base/media/ic_history_black_36dp.png
new file mode 100644
index 0000000..8ab4cd3
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_history_black_36dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_history_black_48dp.png b/supersearch/src/main/resources/base/media/ic_history_black_48dp.png
new file mode 100644
index 0000000..cd85c05
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_history_black_48dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_magnify_black_18dp.png b/supersearch/src/main/resources/base/media/ic_magnify_black_18dp.png
new file mode 100644
index 0000000..d555093
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_magnify_black_18dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_magnify_black_24dp.png b/supersearch/src/main/resources/base/media/ic_magnify_black_24dp.png
new file mode 100644
index 0000000..bd12c21
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_magnify_black_24dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_magnify_black_36dp.png b/supersearch/src/main/resources/base/media/ic_magnify_black_36dp.png
new file mode 100644
index 0000000..972ba66
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_magnify_black_36dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_magnify_black_48dp.png b/supersearch/src/main/resources/base/media/ic_magnify_black_48dp.png
new file mode 100644
index 0000000..51d5371
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_magnify_black_48dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_magnify_grey600_18dp.png b/supersearch/src/main/resources/base/media/ic_magnify_grey600_18dp.png
new file mode 100644
index 0000000..08ac222
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_magnify_grey600_18dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_magnify_grey600_24dp.png b/supersearch/src/main/resources/base/media/ic_magnify_grey600_24dp.png
new file mode 100644
index 0000000..0333cb6
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_magnify_grey600_24dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_magnify_grey600_36dp.png b/supersearch/src/main/resources/base/media/ic_magnify_grey600_36dp.png
new file mode 100644
index 0000000..843eb88
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_magnify_grey600_36dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_magnify_grey600_48dp.png b/supersearch/src/main/resources/base/media/ic_magnify_grey600_48dp.png
new file mode 100644
index 0000000..709f4d3
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_magnify_grey600_48dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_magnify_white_18dp.png b/supersearch/src/main/resources/base/media/ic_magnify_white_18dp.png
new file mode 100644
index 0000000..bf25e31
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_magnify_white_18dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_magnify_white_24dp.png b/supersearch/src/main/resources/base/media/ic_magnify_white_24dp.png
new file mode 100644
index 0000000..f34f90c
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_magnify_white_24dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_magnify_white_36dp.png b/supersearch/src/main/resources/base/media/ic_magnify_white_36dp.png
new file mode 100644
index 0000000..a734319
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_magnify_white_36dp.png differ
diff --git a/supersearch/src/main/resources/base/media/ic_magnify_white_48dp.png b/supersearch/src/main/resources/base/media/ic_magnify_white_48dp.png
new file mode 100644
index 0000000..158a713
Binary files /dev/null and b/supersearch/src/main/resources/base/media/ic_magnify_white_48dp.png differ
diff --git a/supersearch/src/main/resources/en/element/string.json b/supersearch/src/main/resources/en/element/string.json
new file mode 100644
index 0000000..816a1ae
--- /dev/null
+++ b/supersearch/src/main/resources/en/element/string.json
@@ -0,0 +1,40 @@
+{
+ "string": [
+ {
+ "name": "searchmr",
+ "value": "SEARCH DEFAULT PAGE"
+ },
+ {
+ "name": "withoutSug",
+ "value": "NO SUGGESTED SEARCH"
+ },
+ {
+ "name": "recentSug",
+ "value": "HAS RECENT SUGGESTED SEARCHES"
+ },
+ {
+ "name": "hasknownSug",
+ "value": "HAS KNOWN SUGGESTED SEARCHES"
+ },
+ {
+ "name": "suggestion_text",
+ "value": "Suggestion Text"
+ },
+ {
+ "name": "search_hint_text",
+ "value": "Searching..."
+ },
+ {
+ "name": "search_hint_text_",
+ "value": "Search ."
+ },
+ {
+ "name": "search_input_null",
+ "value": "Search Text is Null"
+ },
+ {
+ "name": "search_answer_none",
+ "value": "Search Answer is None"
+ }
+ ]
+}
diff --git a/supersearch/src/main/resources/zh/element/string.json b/supersearch/src/main/resources/zh/element/string.json
new file mode 100644
index 0000000..e0038b8
--- /dev/null
+++ b/supersearch/src/main/resources/zh/element/string.json
@@ -0,0 +1,40 @@
+{
+ "string": [
+ {
+ "name": "searchmr",
+ "value": "搜索默认页面"
+ },
+ {
+ "name": "withoutSug",
+ "value": "无建议搜索"
+ },
+ {
+ "name": "recentSug",
+ "value": "有最近建议搜索"
+ },
+ {
+ "name": "hasknownSug",
+ "value": "有已知建议搜索"
+ },
+ {
+ "name": "suggestion_text",
+ "value": "建议文本"
+ },
+ {
+ "name": "search_hint_text",
+ "value": "搜索..."
+ },
+ {
+ "name": "search_hint_text_",
+ "value": "搜索."
+ },
+ {
+ "name": "search_input_null",
+ "value": "搜索值为空"
+ },
+ {
+ "name": "search_answer_none",
+ "value": "搜索结果为空"
+ }
+ ]
+}
diff --git a/supersearch/src/test/java/com/xcl/supersearch/ExampleTest.java b/supersearch/src/test/java/com/xcl/supersearch/ExampleTest.java
new file mode 100644
index 0000000..87355bf
--- /dev/null
+++ b/supersearch/src/test/java/com/xcl/supersearch/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.xcl.supersearch;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}