diff --git a/README.md b/README.md
index 2e39692b..0872c7c3 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
+
# XUI
@@ -74,7 +74,7 @@ allprojects {
dependencies {
...
//androidx project
- implementation 'com.github.xuexiangjys:XUI:1.1.6'
+ implementation 'com.github.xuexiangjys:XUI:1.1.7'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
@@ -209,6 +209,20 @@ protected void attachBaseContext(Context newBase) {
![download_github.png](https://img.rruu.net/image/5f7d827d5d755)
+## Contribution
+
+> Due to my limited energy, you are welcome to actively contribute your idea. You will have the opportunity to participate in the maintenance of star over 1000 projects on GitHub and enhance your industry influence!
+
+Code contribution requirements:
+
+* Please keep the existing code style, not according to your habits. Please comply with Alibaba java coding specification.
+
+* Just modify the code you are sure need to be optimized, not all the different code from your ideas.
+
+* Before launching a pull request, you should test your commit code adequately.
+
+* Please commit new code to the dev branch instead of the master branch.
+
## Thanks
* [QMUI_Android](https://github.com/Tencent/QMUI_Android)
@@ -280,6 +294,19 @@ B*G | 1¥ | WeChat
**俊 | 80¥ | Alipay
*尋 | 10.24¥ | WeChat
爱生活 | 100¥ | QQ
+*茶 | 100¥ | WeChat
+*头 | 2¥ | WeChat
+*噜 | 10.99¥ | WeChat
+*W*m | 10¥ | WeChat
+*谷 | 10¥ | WeChat
+*望 | 5¥ | WeChat
+J*o | 10.24¥ | WeChat
+*休 | 10.24¥ | WeChat
+**俊 | 80¥ | Alipay
+**伟 | 1.1¥ | Alipay
+**云 | 5¥ | Alipay
+*航 | 3¥ | Alipay
+*维 | 5¥ | WeChat
## Contact
@@ -287,4 +314,6 @@ B*G | 1¥ | WeChat
[![](https://img.shields.io/badge/XUIGroup2-700246750-blue.svg)](http://shang.qq.com/wpa/qunwpa?idkey=39497f13d5e456d219be785361a282d2d9c8cd9ba7745f6170def9d90643e164)
+[![](https://img.shields.io/badge/XUIGroup3-1090612354-blue.svg)](https://qm.qq.com/cgi-bin/qm/qr?k=nOY3GGJY-jiwzhQpR8E06G-yrOUsxCP1)
+
![gzh_weixin.jpg](https://img.rruu.net/image/5f871cfff3194)
diff --git a/README_ZH.md b/README_ZH.md
index de49349d..21608ed2 100644
--- a/README_ZH.md
+++ b/README_ZH.md
@@ -1,5 +1,5 @@
-
+
# XUI
@@ -72,7 +72,7 @@ allprojects {
dependencies {
...
//androidx项目
- implementation 'com.github.xuexiangjys:XUI:1.1.6'
+ implementation 'com.github.xuexiangjys:XUI:1.1.7'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
@@ -203,6 +203,20 @@ protected void attachBaseContext(Context newBase) {
![download_github.png](https://img.rruu.net/image/5f7d827d5d755)
+## 贡献代码
+
+> 由于本人精力有限,现欢迎大家踊跃贡献自己的idea,你将有机会参与到github上star过千项目的维护中,提升自己的行业影响力!
+
+代码贡献要求:
+
+* 请保持现有的代码样式,而不是根据您的习惯。请遵守阿里巴巴Java编码规范。
+
+* 只需修改你确定需要优化的代码,而不是所有与你想法不同的代码。
+
+* 在启动pull请求之前,应该充分测试提交代码。
+
+* 请将新代码提交到dev分支,而不是主分支。
+
## 特别感谢
* [QMUI_Android](https://github.com/Tencent/QMUI_Android)
@@ -274,6 +288,19 @@ B*G | 1¥ | 微信
**俊 | 80¥ | 支付宝
*尋 | 10.24¥ | 微信
爱生活 | 100¥ | QQ
+*茶 | 100¥ | 微信
+*头 | 2¥ | 微信
+*噜 | 10.99¥ | 微信
+*W*m | 10¥ | 微信
+*谷 | 10¥ | 微信
+*望 | 5¥ | 微信
+J*o | 10.24¥ | 微信
+*休 | 10.24¥ | 微信
+**俊 | 80¥ | 支付宝
+**伟 | 1.1¥ | 支付宝
+**云 | 5¥ | 支付宝
+*航 | 3¥ | 支付宝
+*维 | 5¥ | 微信
## 联系方式
@@ -281,4 +308,6 @@ B*G | 1¥ | 微信
[![](https://img.shields.io/badge/XUI开源交流2群-700246750-blue.svg)](http://shang.qq.com/wpa/qunwpa?idkey=39497f13d5e456d219be785361a282d2d9c8cd9ba7745f6170def9d90643e164)
+[![](https://img.shields.io/badge/XUI开源交流3群-1090612354-blue.svg)](https://qm.qq.com/cgi-bin/qm/qr?k=nOY3GGJY-jiwzhQpR8E06G-yrOUsxCP1)
+
![gzh_weixin.jpg](https://img.rruu.net/image/5f871cfff3194)
diff --git a/app/build.gradle b/app/build.gradle
index fd9fde06..b1b0d538 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -14,8 +14,8 @@ android {
applicationId "com.xuexiang.xuidemo"
minSdkVersion 17
targetSdkVersion build_versions.target_sdk
- versionCode 17
- versionName "1.1.6"
+ versionCode 18
+ versionName "1.1.7"
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
@@ -103,8 +103,8 @@ dependencies {
implementation 'com.github.bumptech.glide:glide:4.11.0'
//XUI框架
-// implementation project(':xui_lib')
- implementation 'com.github.xuexiangjys:XUI:1.1.6'
+ implementation project(':xui_lib')
+// implementation 'com.github.xuexiangjys:XUI:1.1.6'
// implementation 'com.qmuiteam:qmui:1.2.0'
//工具类
@@ -116,15 +116,13 @@ dependencies {
implementation 'com.github.xuexiangjys.XRouter:xrouter-runtime:1.0.1'
annotationProcessor 'com.github.xuexiangjys.XRouter:xrouter-compiler:1.0.1'
//XPage页面框架
- implementation 'com.github.xuexiangjys.XPage:xpage-lib:3.0.3'
+ implementation 'com.github.xuexiangjys.XPage:xpage-lib:3.1.1'
annotationProcessor project(':widget_compiler')
//ButterKnife
implementation deps.butterknife.runtime
annotationProcessor deps.butterknife.compiler
- //如果开启了内存泄漏监测leak,就需要加上这个依赖
- debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.3'
- releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3'
- testImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3'
+ // LeakCanary内存泄漏检测
+ debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.6'
//弹性布局
implementation 'com.google.android:flexbox:0.3.1'
@@ -199,7 +197,7 @@ dependencies {
implementation 'com.alibaba.android:ultraviewpager:1.0.7.8'
implementation 'com.alibaba.android:tangram:3.3.6'
//版本更新
- implementation 'com.github.xuexiangjys:XUpdate:2.0.6'
+ implementation 'com.github.xuexiangjys:XUpdate:2.0.7'
implementation 'com.zhy:okhttputils:2.6.2'
implementation deps.gson
implementation deps.okhttp3
@@ -207,14 +205,15 @@ dependencies {
implementation 'com.tencent:mmkv:1.0.22'
//腾讯x5TBS
implementation 'com.tencent.tbs.tbssdk:sdk:43967'
-
+ //富文本
+ implementation 'com.zzhoujay.richtext:richtext:3.0.8'
//双列表联动
implementation 'com.kunminx.linkage:linkage-recyclerview:1.9.2'
//umeng统计
- implementation 'com.umeng.umsdk:analytics:8.0.2'
- implementation 'com.umeng.umsdk:common:2.0.2'
+ implementation 'com.umeng.umsdk:analytics:8.1.4'
+ implementation 'com.umeng.umsdk:common:2.1.8'
//ANR异常捕获
implementation 'com.github.anrwatchdog:anrwatchdog:1.4.0'
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index 89e69c22..4961b27d 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -218,6 +218,7 @@
# xpage
-keep class com.xuexiang.xpage.annotation.** { *; }
+-keep class com.xuexiang.xpage.config.** { *; }
# xaop
-keep @com.xuexiang.xaop.annotation.* class * {*;}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/activity/MainActivity.java b/app/src/main/java/com/xuexiang/xuidemo/activity/MainActivity.java
index a9149cc2..fac2cb39 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/activity/MainActivity.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/activity/MainActivity.java
@@ -36,6 +36,7 @@
import com.xuexiang.xuidemo.utils.TokenUtils;
import com.xuexiang.xuidemo.utils.Utils;
import com.xuexiang.xuidemo.utils.XToastUtils;
+import com.xuexiang.xuidemo.widget.GuideTipsDialog;
import com.xuexiang.xutil.common.ClickUtils;
import com.xuexiang.xutil.system.DeviceUtils;
import com.yarolegovich.slidingrootnav.SlideGravity;
@@ -85,6 +86,8 @@ protected void onCreate(Bundle savedInstanceState) {
initSlidingMenu(savedInstanceState);
initViews();
+
+ GuideTipsDialog.showTips(this);
}
private void initData() {
diff --git a/app/src/main/java/com/xuexiang/xuidemo/adapter/NewsListAdapter.java b/app/src/main/java/com/xuexiang/xuidemo/adapter/NewsListAdapter.java
index a5d1eb41..e8edd48c 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/adapter/NewsListAdapter.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/adapter/NewsListAdapter.java
@@ -5,7 +5,7 @@
import com.xuexiang.xui.widget.imageview.RadiusImageView;
import com.xuexiang.xuidemo.DemoDataProvider;
import com.xuexiang.xuidemo.R;
-import com.xuexiang.xuidemo.adapter.base.BroccoliRecyclerAdapter;
+import com.xuexiang.xuidemo.adapter.base.broccoli.BroccoliRecyclerAdapter;
import com.xuexiang.xuidemo.adapter.entity.NewInfo;
import com.xuexiang.xuidemo.utils.PlaceholderHelper;
diff --git a/app/src/main/java/com/xuexiang/xuidemo/adapter/base/BroccoliRecyclerAdapter.java b/app/src/main/java/com/xuexiang/xuidemo/adapter/base/broccoli/BroccoliRecyclerAdapter.java
similarity index 75%
rename from app/src/main/java/com/xuexiang/xuidemo/adapter/base/BroccoliRecyclerAdapter.java
rename to app/src/main/java/com/xuexiang/xuidemo/adapter/base/broccoli/BroccoliRecyclerAdapter.java
index 92143ee3..950c6361 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/adapter/base/BroccoliRecyclerAdapter.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/adapter/base/broccoli/BroccoliRecyclerAdapter.java
@@ -1,4 +1,21 @@
-package com.xuexiang.xuidemo.adapter.base;
+/*
+ * Copyright (C) 2021 xuexiangjys(xuexiangjys@163.com)
+ *
+ * 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
+ *
+ * http://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.
+ *
+ */
+
+package com.xuexiang.xuidemo.adapter.base.broccoli;
import android.view.View;
diff --git a/app/src/main/java/com/xuexiang/xuidemo/adapter/base/broccoli/BroccoliSimpleDelegateAdapter.java b/app/src/main/java/com/xuexiang/xuidemo/adapter/base/broccoli/BroccoliSimpleDelegateAdapter.java
new file mode 100644
index 00000000..de3a6138
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/adapter/base/broccoli/BroccoliSimpleDelegateAdapter.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2021 xuexiangjys(xuexiangjys@163.com)
+ *
+ * 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
+ *
+ * http://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.
+ *
+ */
+
+package com.xuexiang.xuidemo.adapter.base.broccoli;
+
+import android.view.View;
+
+import androidx.annotation.NonNull;
+
+import com.alibaba.android.vlayout.LayoutHelper;
+import com.xuexiang.xui.adapter.recyclerview.RecyclerViewHolder;
+import com.xuexiang.xuidemo.adapter.base.delegate.SimpleDelegateAdapter;
+import com.xuexiang.xuidemo.adapter.base.delegate.XDelegateAdapter;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import me.samlss.broccoli.Broccoli;
+
+/**
+ * 使用Broccoli占位的基础适配器
+ *
+ * @author xuexiang
+ * @since 2021/1/9 4:52 PM
+ */
+public abstract class BroccoliSimpleDelegateAdapter extends SimpleDelegateAdapter {
+
+ /**
+ * 是否已经加载成功
+ */
+ private boolean mHasLoad = false;
+ private Map mBroccoliMap = new HashMap<>();
+
+ public BroccoliSimpleDelegateAdapter(int layoutId, LayoutHelper layoutHelper) {
+ super(layoutId, layoutHelper);
+ }
+
+ public BroccoliSimpleDelegateAdapter(int layoutId, LayoutHelper layoutHelper, Collection list) {
+ super(layoutId, layoutHelper, list);
+ }
+
+ public BroccoliSimpleDelegateAdapter(int layoutId, LayoutHelper layoutHelper, T[] data) {
+ super(layoutId, layoutHelper, data);
+ }
+
+ @Override
+ protected void bindData(@NonNull RecyclerViewHolder holder, int position, T item) {
+ Broccoli broccoli = mBroccoliMap.get(holder.itemView);
+ if (broccoli == null) {
+ broccoli = new Broccoli();
+ mBroccoliMap.put(holder.itemView, broccoli);
+ }
+ if (mHasLoad) {
+ broccoli.removeAllPlaceholders();
+
+ onBindData(holder, item, position);
+ } else {
+ onBindBroccoli(holder, broccoli);
+ broccoli.show();
+ }
+ }
+
+
+ /**
+ * 绑定控件
+ *
+ * @param holder
+ * @param model
+ * @param position
+ */
+ protected abstract void onBindData(RecyclerViewHolder holder, T model, int position);
+
+ /**
+ * 绑定占位控件
+ *
+ * @param holder
+ * @param broccoli
+ */
+ protected abstract void onBindBroccoli(RecyclerViewHolder holder, Broccoli broccoli);
+
+ @Override
+ public XDelegateAdapter refresh(Collection collection) {
+ mHasLoad = true;
+ return super.refresh(collection);
+ }
+
+ /**
+ * 资源释放,防止内存泄漏
+ */
+ public void recycle() {
+ for (Broccoli broccoli : mBroccoliMap.values()) {
+ broccoli.removeAllPlaceholders();
+ }
+ mBroccoliMap.clear();
+ clear();
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/base/http/entity/ApiResult.java b/app/src/main/java/com/xuexiang/xuidemo/base/http/entity/ApiResult.java
new file mode 100644
index 00000000..80b537b8
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/base/http/entity/ApiResult.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 xuexiangjys(xuexiangjys@163.com)
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.xuexiang.xuidemo.base.http.entity;
+
+import androidx.annotation.Keep;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * 提供的默认的标注返回api
+ *
+ * @author xuexiang
+ * @since 2018/5/22 下午4:22
+ */
+@Keep
+public class ApiResult {
+ public final static String CODE = "Code";
+ public final static String MSG = "Msg";
+ public final static String DATA = "Data";
+
+ @SerializedName(value = CODE, alternate = {"code"})
+ private int Code;
+ @SerializedName(value = MSG, alternate = {"msg"})
+ private String Msg;
+ @SerializedName(value = DATA, alternate = {"data"})
+ private T Data;
+
+ public int getCode() {
+ return Code;
+ }
+
+ public ApiResult setCode(int code) {
+ Code = code;
+ return this;
+ }
+
+ public String getMsg() {
+ return Msg;
+ }
+
+ public ApiResult setMsg(String msg) {
+ Msg = msg;
+ return this;
+ }
+
+ public ApiResult setData(T data) {
+ Data = data;
+ return this;
+ }
+
+ /**
+ * 获取请求响应的数据,自定义api的时候需要重写【很关键】
+ *
+ * @return
+ */
+ public T getData() {
+ return Data;
+ }
+
+ /**
+ * 是否请求成功,自定义api的时候需要重写【很关键】
+ *
+ * @return
+ */
+ public boolean isSuccess() {
+ return getCode() == 0;
+ }
+
+ @Override
+ public String toString() {
+ return "ApiResult{" +
+ "Code='" + Code + '\'' +
+ ", Msg='" + Msg + '\'' +
+ ", Data=" + Data +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/base/http/entity/TipInfo.java b/app/src/main/java/com/xuexiang/xuidemo/base/http/entity/TipInfo.java
new file mode 100644
index 00000000..e680a5ca
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/base/http/entity/TipInfo.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 xuexiangjys(xuexiangjys@163.com)
+ *
+ * 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
+ *
+ * http://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.
+ *
+ */
+
+package com.xuexiang.xuidemo.base.http.entity;
+
+import androidx.annotation.Keep;
+
+/**
+ * @author xuexiang
+ * @since 2019-08-28 15:35
+ */
+@Keep
+public class TipInfo {
+ /**
+ * title : 小贴士3
+ * content : 欢迎关注我的微信公众号:我的Android开源之旅。
+ */
+
+ private String title;
+ private String content;
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ @Override
+ public String toString() {
+ return "TipInfo{" +
+ "title='" + title + '\'' +
+ ", content='" + content + '\'' +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/base/webview/AgentWebActivity.java b/app/src/main/java/com/xuexiang/xuidemo/base/webview/AgentWebActivity.java
index 2d862bdc..4c30b1b4 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/base/webview/AgentWebActivity.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/base/webview/AgentWebActivity.java
@@ -68,18 +68,29 @@ private void loadWeb(Intent intent) {
public void onArrival(Postcard postcard) {
finish();
}
+
+ @Override
+ public void onLost(Postcard postcard) {
+ loadUrl(uri.toString());
+ }
});
} else {
String url = intent.getStringExtra(KEY_URL);
- if (url != null) {
- openFragment(url);
- } else {
- XToastUtils.toast("数据出错!");
- finish();
- }
+ loadUrl(url);
}
}
+
+ private void loadUrl(String url) {
+ if (url != null) {
+ openFragment(url);
+ } else {
+ XToastUtils.error("数据出错!");
+ finish();
+ }
+ }
+
+
private AgentWebFragment mAgentWebFragment;
private void openFragment(String url) {
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/ComponentsFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/ComponentsFragment.java
index 0b560a79..8399c885 100755
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/ComponentsFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/ComponentsFragment.java
@@ -1,7 +1,7 @@
package com.xuexiang.xuidemo.fragment;
-import com.xuexiang.xpage.AppPageConfig;
import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xpage.config.AppPageConfig;
import com.xuexiang.xpage.enums.CoreAnim;
import com.xuexiang.xpage.model.PageInfo;
import com.xuexiang.xuidemo.base.BaseHomeFragment;
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/ExpandsFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/ExpandsFragment.java
index f458fec9..bee86bbf 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/ExpandsFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/ExpandsFragment.java
@@ -16,8 +16,8 @@
package com.xuexiang.xuidemo.fragment;
-import com.xuexiang.xpage.AppPageConfig;
import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xpage.config.AppPageConfig;
import com.xuexiang.xpage.enums.CoreAnim;
import com.xuexiang.xpage.model.PageInfo;
import com.xuexiang.xuidemo.base.BaseHomeFragment;
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/SearchComponentFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/SearchComponentFragment.java
index 6b2480ff..4b97dcf1 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/SearchComponentFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/SearchComponentFragment.java
@@ -25,8 +25,8 @@
import com.xuexiang.xaop.annotation.SingleClick;
import com.xuexiang.xormlite.XUIDataBaseRepository;
import com.xuexiang.xormlite.db.DBService;
-import com.xuexiang.xpage.AppPageConfig;
import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xpage.config.AppPageConfig;
import com.xuexiang.xpage.model.PageInfo;
import com.xuexiang.xui.adapter.recyclerview.RecyclerViewHolder;
import com.xuexiang.xui.widget.actionbar.TitleBar;
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/UtilitiesFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/UtilitiesFragment.java
index 4a31f4bd..c658fc5a 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/UtilitiesFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/UtilitiesFragment.java
@@ -16,8 +16,8 @@
package com.xuexiang.xuidemo.fragment;
-import com.xuexiang.xpage.AppPageConfig;
import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xpage.config.AppPageConfig;
import com.xuexiang.xpage.enums.CoreAnim;
import com.xuexiang.xpage.model.PageInfo;
import com.xuexiang.xuidemo.base.BaseHomeFragment;
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/dialog/DialogStrategyFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/dialog/DialogStrategyFragment.java
index 29bca6ab..36fec721 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/dialog/DialogStrategyFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/dialog/DialogStrategyFragment.java
@@ -20,6 +20,7 @@
import android.text.InputType;
import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xui.utils.KeyboardUtils;
import com.xuexiang.xui.widget.dialog.DialogLoader;
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog;
import com.xuexiang.xui.widget.dialog.strategy.InputInfo;
@@ -62,7 +63,7 @@ protected List initSimpleData(List lists) {
*/
@Override
protected void onItemClick(int position) {
- switch(position) {
+ switch (position) {
case 0:
DialogLoader.getInstance().setIDialogStrategy(new MaterialDialogStrategy());
break;
@@ -105,13 +106,17 @@ protected void onItemClick(int position) {
(dialog, input) -> XToastUtils.toast(input.toString()),
getString(R.string.lab_continue),
(dialog, which) -> {
+ KeyboardUtils.hideSoftInput(dialog);
dialog.dismiss();
if (dialog instanceof MaterialDialog) {
- XToastUtils.toast("你输入了:" + ((MaterialDialog)dialog).getInputEditText().getText().toString());
+ XToastUtils.toast("你输入了:" + ((MaterialDialog) dialog).getInputEditText().getText().toString());
}
},
getString(R.string.lab_change),
- null);
+ (dialog, which) -> {
+ KeyboardUtils.hideSoftInput(dialog);
+ dialog.dismiss();
+ });
break;
case 5:
DialogLoader.getInstance().showContextMenuDialog(getContext(),
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/imageview/preview/ImageViewInfo.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/imageview/preview/ImageViewInfo.java
index 85e27fa9..30e7e5e7 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/imageview/preview/ImageViewInfo.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/imageview/preview/ImageViewInfo.java
@@ -19,10 +19,14 @@
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
+
import androidx.annotation.Nullable;
import com.xuexiang.xui.widget.imageview.preview.enitity.IPreviewInfo;
+import java.util.Collections;
+import java.util.List;
+
/**
* 图片预览实体类
*
@@ -31,16 +35,31 @@
*/
public class ImageViewInfo implements IPreviewInfo {
- private String mUrl; //图片地址
- private Rect mBounds; // 记录坐标
+ /**
+ * 图片地址
+ */
+ private String mUrl;
+ /**
+ * 记录坐标
+ */
+ private Rect mBounds;
private String mVideoUrl;
private String mDescription = "描述信息";
+ public static List newInstance(String url, Rect bounds) {
+ return Collections.singletonList(new ImageViewInfo(url, bounds));
+ }
+
public ImageViewInfo(String url) {
mUrl = url;
}
+ public ImageViewInfo(String url, Rect bounds) {
+ mUrl = url;
+ mBounds = bounds;
+ }
+
public ImageViewInfo(String videoUrl, String url) {
mUrl = url;
mVideoUrl = videoUrl;
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/tabbar/EasyIndicatorFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/tabbar/EasyIndicatorFragment.java
index 14a9d85a..a7939d9a 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/tabbar/EasyIndicatorFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/tabbar/EasyIndicatorFragment.java
@@ -49,6 +49,8 @@ public class EasyIndicatorFragment extends BaseFragment {
@BindView(R.id.easy_indicator1)
EasyIndicator mEasyIndicator1;
+ @BindView(R.id.easy_indicator2)
+ EasyIndicator mEasyIndicator2;
@BindView(R.id.easy_indicator)
EasyIndicator mEasyIndicator;
@@ -128,6 +130,8 @@ private void initIndicatorNoViewPager() {
mEasyIndicator1.setTabTitles(ContentPage.getPageNames());
mEasyIndicator1.setOnTabClickListener((title, position) -> XToastUtils.toast("点击了" + title));
+
+ mEasyIndicator2.setTabTitles(ContentPage.getPageNames());
}
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/textview/LoggerTextViewFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/textview/LoggerTextViewFragment.java
index 16f0d271..18c22d78 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/components/textview/LoggerTextViewFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/components/textview/LoggerTextViewFragment.java
@@ -23,6 +23,9 @@
import com.xuexiang.xui.widget.textview.LoggerTextView;
import com.xuexiang.xuidemo.R;
import com.xuexiang.xuidemo.base.BaseFragment;
+import com.xuexiang.xutil.data.DateUtils;
+
+import java.text.SimpleDateFormat;
import butterknife.BindView;
import butterknife.OnClick;
@@ -44,6 +47,8 @@ protected int getLayoutId() {
@Override
protected void initViews() {
+ // 这里设置自定义的日志格式
+ logger.setLogFormatter((logContent, logType) -> DateUtils.getNowString(new SimpleDateFormat("[HH:mm]")) + logContent);
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomLinkagePrimaryAdapterConfig.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomLinkagePrimaryAdapterConfig.java
index f1b42cd4..f741f87a 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomLinkagePrimaryAdapterConfig.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomLinkagePrimaryAdapterConfig.java
@@ -46,7 +46,7 @@ public CustomLinkagePrimaryAdapterConfig(OnPrimaryItemClickListener itemClickLis
mItemClickListener = itemClickListener;
}
- public CustomLinkagePrimaryAdapterConfig setOnItemClickListner(OnPrimaryItemClickListener itemClickListener) {
+ public CustomLinkagePrimaryAdapterConfig setOnItemClickListener(OnPrimaryItemClickListener itemClickListener) {
mItemClickListener = itemClickListener;
return this;
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomLinkageSecondaryAdapterConfig.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomLinkageSecondaryAdapterConfig.java
index 1d44bfd3..e0a820cd 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomLinkageSecondaryAdapterConfig.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/custom/CustomLinkageSecondaryAdapterConfig.java
@@ -42,7 +42,7 @@ public CustomLinkageSecondaryAdapterConfig(OnSecondaryItemClickListener itemClic
mItemClickListener = itemClickListener;
}
- public CustomLinkageSecondaryAdapterConfig setOnItemClickListner(OnSecondaryItemClickListener itemClickListener) {
+ public CustomLinkageSecondaryAdapterConfig setOnItemClickListener(OnSecondaryItemClickListener itemClickListener) {
mItemClickListener = itemClickListener;
return this;
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/eleme/ElemeSecondaryAdapterConfig.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/eleme/ElemeSecondaryAdapterConfig.java
index e2ea7079..0ea1402f 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/eleme/ElemeSecondaryAdapterConfig.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/linkage/eleme/ElemeSecondaryAdapterConfig.java
@@ -49,7 +49,7 @@ public ElemeSecondaryAdapterConfig(OnSecondaryItemClickListener itemClickListene
mItemClickListener = itemClickListener;
}
- public ElemeSecondaryAdapterConfig setOnItemClickListner(OnSecondaryItemClickListener itemClickListener) {
+ public ElemeSecondaryAdapterConfig setOnItemClickListener(OnSecondaryItemClickListener itemClickListener) {
mItemClickListener = itemClickListener;
return this;
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/materialdesign/BottomSheetDialogFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/materialdesign/BottomSheetDialogFragment.java
index 0dd31c11..2686bca4 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/materialdesign/BottomSheetDialogFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/materialdesign/BottomSheetDialogFragment.java
@@ -24,8 +24,8 @@
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetDialog;
-import com.xuexiang.xpage.AppPageConfig;
import com.xuexiang.xpage.annotation.Page;
+import com.xuexiang.xpage.config.AppPageConfig;
import com.xuexiang.xpage.model.PageInfo;
import com.xuexiang.xui.utils.DensityUtils;
import com.xuexiang.xui.utils.WidgetUtils;
@@ -34,6 +34,7 @@
import com.xuexiang.xuidemo.adapter.SimpleRecyclerAdapter;
import com.xuexiang.xuidemo.adapter.WidgetItemAdapter;
import com.xuexiang.xuidemo.base.BaseSimpleListFragment;
+import com.xuexiang.xuidemo.fragment.expands.materialdesign.bottom.DemoBottomSheetDialog;
import java.util.Collections;
import java.util.List;
@@ -54,6 +55,7 @@ public class BottomSheetDialogFragment extends BaseSimpleListFragment {
protected List initSimpleData(List lists) {
lists.add("List");
lists.add("Grid");
+ lists.add("DialogFragment");
return lists;
}
@@ -71,6 +73,9 @@ protected void onItemClick(int position) {
case 1:
showBottomSheetListDialog(false);
break;
+ case 2:
+ DemoBottomSheetDialog.newInstance().show(getFragmentManager());
+ break;
default:
break;
}
@@ -91,6 +96,8 @@ private void showBottomSheetListDialog(boolean isList) {
dialog.setCancelable(true);
dialog.setCanceledOnTouchOutside(true);
dialog.show();
+
+ WidgetUtils.transparentBottomSheetDialogBackground(dialog);
}
private void initDialogList(RecyclerView recyclerView) {
@@ -111,6 +118,7 @@ private void initDialogGrid(RecyclerView recyclerView) {
/**
* 进行排序
+ *
* @param pageInfoList
* @return
*/
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/materialdesign/DrawerLayoutFragment.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/materialdesign/DrawerLayoutFragment.java
index 2eae5e21..27222704 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/materialdesign/DrawerLayoutFragment.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/materialdesign/DrawerLayoutFragment.java
@@ -78,6 +78,10 @@ protected int getLayoutId() {
protected TitleBar initTitle() {
toolbar.setTitle("资讯");
toolbar.inflateMenu(R.menu.menu_setting);
+ toolbar.setOnMenuItemClickListener(item -> {
+ XToastUtils.toast("点击了:" + item.getTitle());
+ return true;
+ });
return null;
}
@@ -100,6 +104,8 @@ protected void initViews() {
viewPager.setAdapter(adapter);
ViewUtils.setViewsFont(bottomNavigation);
+ ViewUtils.clearViewLongClick(bottomNavigation, R.id.item_dashboard, R.id.item_photo, R.id.item_music, R.id.item_movie);
+ ViewUtils.clearAllViewLongClick(toolbar);
}
@@ -124,7 +130,7 @@ protected void initListeners() {
@SingleClick
@Override
public void onClick(View v) {
- switch(v.getId()) {
+ switch (v.getId()) {
case R.id.nav_header:
XToastUtils.toast("点击头部!");
break;
diff --git a/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/materialdesign/bottom/DemoBottomSheetDialog.java b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/materialdesign/bottom/DemoBottomSheetDialog.java
new file mode 100644
index 00000000..1ac3691c
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/fragment/expands/materialdesign/bottom/DemoBottomSheetDialog.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2021 xuexiangjys(xuexiangjys@163.com)
+ *
+ * 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
+ *
+ * http://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.
+ *
+ */
+
+package com.xuexiang.xuidemo.fragment.expands.materialdesign.bottom;
+
+import android.app.Dialog;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.google.android.material.bottomsheet.BottomSheetDialog;
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
+import com.xuexiang.xpage.config.AppPageConfig;
+import com.xuexiang.xpage.model.PageInfo;
+import com.xuexiang.xui.utils.DensityUtils;
+import com.xuexiang.xui.utils.WidgetUtils;
+import com.xuexiang.xuidemo.R;
+import com.xuexiang.xuidemo.adapter.WidgetItemAdapter;
+
+import java.util.Collections;
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.Unbinder;
+
+/**
+ * 底部弹窗
+ *
+ * @author xuexiang
+ * @since 2021/3/28 1:30 PM
+ */
+public class DemoBottomSheetDialog extends BottomSheetDialogFragment {
+
+ private static final String TAG = "BottomSheetDialog";
+
+ public static DemoBottomSheetDialog newInstance() {
+ Bundle args = new Bundle();
+ DemoBottomSheetDialog fragment = new DemoBottomSheetDialog();
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ private Unbinder mUnbinder;
+
+ @BindView(R.id.recyclerView)
+ RecyclerView recyclerView;
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.dialog_bottom_sheet, container, false);
+ }
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+ // 这里可以自定义弹窗的样式
+ Dialog dialog = new BottomSheetDialog(getContext(), R.style.XUITheme_BottomSheetDialog);
+ dialog.setCancelable(true);
+ dialog.setCanceledOnTouchOutside(true);
+ return dialog;
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ WidgetUtils.transparentBottomSheetDialogBackground((BottomSheetDialog) getDialog());
+ }
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ mUnbinder = ButterKnife.bind(this, view);
+ initView(view);
+ }
+
+ private void initView(@NonNull View view) {
+ WidgetUtils.initGridRecyclerView(recyclerView, 3, DensityUtils.dp2px(2));
+
+ WidgetItemAdapter widgetItemAdapter = new WidgetItemAdapter(sortPageInfo(AppPageConfig.getInstance().getComponents()));
+ recyclerView.setAdapter(widgetItemAdapter);
+ }
+
+ /**
+ * 进行排序
+ *
+ * @param pageInfoList
+ * @return
+ */
+ private List sortPageInfo(List pageInfoList) {
+ Collections.sort(pageInfoList, (o1, o2) -> o1.getClassPath().compareTo(o2.getClassPath()));
+ return pageInfoList;
+ }
+
+ public void show(@NonNull FragmentManager manager) {
+ super.show(manager, TAG);
+ }
+
+ @Override
+ public void onDestroyView() {
+ if (mUnbinder != null) {
+ mUnbinder.unbind();
+ }
+ super.onDestroyView();
+ }
+
+}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/utils/Utils.java b/app/src/main/java/com/xuexiang/xuidemo/utils/Utils.java
index fb247961..5b922d1b 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/utils/Utils.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/utils/Utils.java
@@ -6,6 +6,7 @@
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.LruCache;
@@ -14,7 +15,6 @@
import android.widget.FrameLayout;
import android.widget.ImageView;
-import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
@@ -31,20 +31,22 @@
import com.xuexiang.xui.XUI;
import com.xuexiang.xui.utils.DrawableUtils;
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog;
+import com.xuexiang.xui.widget.imageview.preview.PreviewBuilder;
import com.xuexiang.xuidemo.R;
import com.xuexiang.xuidemo.activity.MainActivity;
import com.xuexiang.xuidemo.base.webview.AgentWebActivity;
import com.xuexiang.xuidemo.base.webview.MiddlewareWebViewClient;
+import com.xuexiang.xuidemo.fragment.components.imageview.preview.ImageViewInfo;
import com.xuexiang.xuidemo.utils.update.CustomUpdateFailureListener;
import com.xuexiang.xupdate.XUpdate;
import com.xuexiang.xutil.XUtil;
import com.xuexiang.xutil.app.ActivityUtils;
+import com.xuexiang.xutil.common.StringUtils;
import com.xuexiang.xutil.data.DateUtils;
import com.xuexiang.xutil.file.FileIOUtils;
import com.xuexiang.xutil.file.FileUtils;
import java.io.File;
-import java.util.Stack;
import static com.xuexiang.xuidemo.base.webview.AgentWebFragment.KEY_URL;
@@ -157,6 +159,33 @@ public static PictureSelectionModel getPictureSelector(Activity activity) {
.previewEggs(true);
}
+ //==========图片预览===========//
+
+ /**
+ * 大图预览
+ *
+ * @param fragment
+ * @param url 图片资源
+ * @param view 小图加载控件
+ */
+ public static void previewPicture(Fragment fragment, String url, View view) {
+ if (fragment == null || StringUtils.isEmpty(url)) {
+ return;
+ }
+ Rect bounds = new Rect();
+ if (view != null) {
+ view.getGlobalVisibleRect(bounds);
+ }
+ PreviewBuilder.from(fragment)
+ .setImgs(ImageViewInfo.newInstance(url, bounds))
+ .setCurrentIndex(0)
+ .setSingleFling(true)
+ .setProgressColor(R.color.xui_config_color_main_theme)
+ .setType(PreviewBuilder.IndicatorType.Number)
+ .start();
+ }
+
+
//==========拍照===========//
public static final String JPEG = ".jpeg";
diff --git a/app/src/main/java/com/xuexiang/xuidemo/utils/sdkinit/PreLoadX5Service.java b/app/src/main/java/com/xuexiang/xuidemo/utils/sdkinit/PreLoadX5Service.java
index de83151a..382ffb92 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/utils/sdkinit/PreLoadX5Service.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/utils/sdkinit/PreLoadX5Service.java
@@ -92,13 +92,13 @@ public void onViewInitFinished(boolean arg0) {
public void onCoreInitFinished() {
}
};
- QbSdk.initX5Environment(getApplicationContext(), cb);
+ QbSdk.initX5Environment(this, cb);
}
private void preInitX5WebCore() {
if (!QbSdk.isTbsCoreInited()) {
// 设置X5初始化完成的回调接口
- QbSdk.preInit(getApplicationContext(), null);
+ QbSdk.preInit(this, null);
}
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/utils/sdkinit/XBasicLibInit.java b/app/src/main/java/com/xuexiang/xuidemo/utils/sdkinit/XBasicLibInit.java
index 5f8c7fe3..5afb3758 100644
--- a/app/src/main/java/com/xuexiang/xuidemo/utils/sdkinit/XBasicLibInit.java
+++ b/app/src/main/java/com/xuexiang/xuidemo/utils/sdkinit/XBasicLibInit.java
@@ -22,7 +22,6 @@
import com.xuexiang.xaop.XAOP;
import com.xuexiang.xormlite.XUIDataBaseRepository;
import com.xuexiang.xormlite.logs.DBLog;
-import com.xuexiang.xpage.AppPageConfig;
import com.xuexiang.xpage.PageConfig;
import com.xuexiang.xrouter.launcher.XRouter;
import com.xuexiang.xuidemo.MyApp;
@@ -79,13 +78,8 @@ private static void initUtils(Application application) {
private static void initPage(Application application) {
//自动注册页面
PageConfig.getInstance()
- .setPageConfiguration(context -> {
- //自动注册页面,是编译时自动生成的,build一下就出来了
- return AppPageConfig.getInstance().getPages();
- })
.debug(MyApp.isDebug() ? "PageLog" : null)
.setContainActivityClazz(BaseActivity.class)
- .enableWatcher(MyApp.isDebug())
.init(application);
}
diff --git a/app/src/main/java/com/xuexiang/xuidemo/widget/GuideTipsDialog.java b/app/src/main/java/com/xuexiang/xuidemo/widget/GuideTipsDialog.java
new file mode 100644
index 00000000..3488f4b2
--- /dev/null
+++ b/app/src/main/java/com/xuexiang/xuidemo/widget/GuideTipsDialog.java
@@ -0,0 +1,216 @@
+package com.xuexiang.xuidemo.widget;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.CompoundButton;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.widget.AppCompatCheckBox;
+
+import com.tencent.mmkv.MMKV;
+import com.xuexiang.xaop.annotation.SingleClick;
+import com.xuexiang.xui.widget.dialog.BaseDialog;
+import com.xuexiang.xuidemo.R;
+import com.xuexiang.xuidemo.base.http.entity.ApiResult;
+import com.xuexiang.xuidemo.base.http.entity.TipInfo;
+import com.xuexiang.xutil.app.AppUtils;
+import com.xuexiang.xutil.common.ObjectUtils;
+import com.xuexiang.xutil.net.JsonUtil;
+import com.xuexiang.xutil.net.type.TypeBuilder;
+import com.zhy.http.okhttp.OkHttpUtils;
+import com.zhy.http.okhttp.callback.StringCallback;
+import com.zzhoujay.richtext.RichText;
+
+import java.lang.reflect.Type;
+import java.util.List;
+
+import okhttp3.Call;
+
+/**
+ * 小贴士弹窗
+ *
+ * @author xuexiang
+ * @since 2019-08-22 17:02
+ */
+public class GuideTipsDialog extends BaseDialog implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
+
+ private static final String KEY_IS_IGNORE_TIPS = "com.xuexiang.xuidemo.widget.key_is_ignore_tips_";
+
+ private static final String TIPS_URL = "https://gitee.com/xuexiangjys/Resource/raw/master/jsonapi/tips.json";
+
+ private List mTips;
+ private int mIndex = -1;
+
+ private TextView mTvPrevious;
+ private TextView mTvNext;
+
+ private TextView mTvTitle;
+ private TextView mTvContent;
+
+ /**
+ * 显示提示
+ *
+ * @param context 上下文
+ */
+ public static void showTips(final Context context) {
+ if (!isIgnoreTips()) {
+ OkHttpUtils.get()
+ .url(TIPS_URL)
+ .build()
+ .execute(new StringCallback() {
+ @Override
+ public void onError(Call call, Exception e, int id) {
+
+ }
+
+ @Override
+ public void onResponse(String response, int id) {
+ showTips(context, response);
+ }
+ });
+ }
+ }
+
+ private static void showTips(Context context, String response) {
+ Type type = TypeBuilder.newInstance(ApiResult.class)
+ .beginSubType(List.class)
+ .addTypeParam(TipInfo.class)
+ .endSubType()
+ .build();
+
+ ApiResult> apiResult = JsonUtil.fromJson(response, type);
+ if (apiResult != null) {
+ List tips = apiResult.getData();
+ if (ObjectUtils.isNotEmpty(tips)) {
+ new GuideTipsDialog(context, tips).show();
+ }
+ }
+ }
+
+ public GuideTipsDialog(Context context, @NonNull List tips) {
+ super(context, R.layout.dialog_guide_tips);
+ initViews();
+ updateTips(tips);
+ }
+
+ /**
+ * 初始化弹窗
+ */
+ private void initViews() {
+ mTvTitle = findViewById(R.id.tv_title);
+ mTvContent = findViewById(R.id.tv_content);
+ AppCompatCheckBox cbIgnore = findViewById(R.id.cb_ignore);
+ ImageView ivClose = findViewById(R.id.iv_close);
+
+ mTvPrevious = findViewById(R.id.tv_previous);
+ mTvNext = findViewById(R.id.tv_next);
+
+ if (cbIgnore != null) {
+ cbIgnore.setOnCheckedChangeListener(this);
+ }
+ if (ivClose != null) {
+ ivClose.setOnClickListener(this);
+ }
+ mTvPrevious.setOnClickListener(this);
+ mTvNext.setOnClickListener(this);
+ mTvPrevious.setEnabled(false);
+ mTvNext.setEnabled(true);
+ setCancelable(false);
+ setCanceledOnTouchOutside(true);
+ }
+
+ /**
+ * 更新提示信息
+ *
+ * @param tips 提示信息
+ */
+ private void updateTips(List tips) {
+ mTips = tips;
+ if (mTips != null && mTips.size() > 0 && mTvContent != null) {
+ mIndex = 0;
+ showRichText(mTips.get(mIndex));
+ }
+ }
+
+ /**
+ * 切换提示信息
+ *
+ * @param index 索引
+ */
+ private void switchTipInfo(int index) {
+ if (mTips != null && mTips.size() > 0 && mTvContent != null) {
+ if (index >= 0 && index <= mTips.size() - 1) {
+ showRichText(mTips.get(index));
+ if (index == 0) {
+ mTvPrevious.setEnabled(false);
+ mTvNext.setEnabled(true);
+ } else if (index == mTips.size() - 1) {
+ mTvPrevious.setEnabled(true);
+ mTvNext.setEnabled(false);
+ } else {
+ mTvPrevious.setEnabled(true);
+ mTvNext.setEnabled(true);
+ }
+ }
+ }
+ }
+
+ /**
+ * 显示富文本
+ *
+ * @param tipInfo 提示信息
+ */
+ private void showRichText(TipInfo tipInfo) {
+ mTvTitle.setText(tipInfo.getTitle());
+ RichText.fromHtml(tipInfo.getContent())
+ .bind(this)
+ .into(mTvContent);
+ }
+
+
+ @SingleClick(300)
+ @Override
+ public void onClick(View view) {
+ switch (view.getId()) {
+ case R.id.iv_close:
+ dismiss();
+ break;
+ case R.id.tv_previous:
+ if (mIndex > 0) {
+ mIndex--;
+ switchTipInfo(mIndex);
+ }
+ break;
+ case R.id.tv_next:
+ if (mIndex < mTips.size() - 1) {
+ mIndex++;
+ switchTipInfo(mIndex);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ setIsIgnoreTips(isChecked);
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ RichText.clear(this);
+ super.onDetachedFromWindow();
+ }
+
+ public static boolean setIsIgnoreTips(boolean isIgnore) {
+ return MMKV.defaultMMKV().encode(KEY_IS_IGNORE_TIPS + AppUtils.getAppVersionCode(), isIgnore);
+ }
+
+ public static boolean isIgnoreTips() {
+ return MMKV.defaultMMKV().decodeBool(KEY_IS_IGNORE_TIPS + AppUtils.getAppVersionCode());
+ }
+
+}
diff --git a/app/src/main/res/drawable/bg_bottom_sheet.xml b/app/src/main/res/drawable/bg_bottom_sheet.xml
new file mode 100644
index 00000000..a4d00e44
--- /dev/null
+++ b/app/src/main/res/drawable/bg_bottom_sheet.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_dialog_common_tip_corner_white.xml b/app/src/main/res/drawable/bg_dialog_common_tip_corner_white.xml
new file mode 100644
index 00000000..dbcadadd
--- /dev/null
+++ b/app/src/main/res/drawable/bg_dialog_common_tip_corner_white.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_action_close_white.xml b/app/src/main/res/drawable/ic_action_close_white.xml
new file mode 100644
index 00000000..266e01fa
--- /dev/null
+++ b/app/src/main/res/drawable/ic_action_close_white.xml
@@ -0,0 +1,22 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/img_guide_tip_top.xml b/app/src/main/res/drawable/img_guide_tip_top.xml
new file mode 100644
index 00000000..6c787f8f
--- /dev/null
+++ b/app/src/main/res/drawable/img_guide_tip_top.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/shape_indicator_line.xml b/app/src/main/res/drawable/shape_indicator_line.xml
new file mode 100644
index 00000000..a0f2a50a
--- /dev/null
+++ b/app/src/main/res/drawable/shape_indicator_line.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/dialog_bottom_sheet.xml b/app/src/main/res/layout/dialog_bottom_sheet.xml
index 96509782..33ad0c71 100644
--- a/app/src/main/res/layout/dialog_bottom_sheet.xml
+++ b/app/src/main/res/layout/dialog_bottom_sheet.xml
@@ -19,6 +19,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:background="@drawable/bg_bottom_sheet"
android:orientation="vertical">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_easy_indicator.xml b/app/src/main/res/layout/fragment_easy_indicator.xml
index b49152c3..bffa7a74 100644
--- a/app/src/main/res/layout/fragment_easy_indicator.xml
+++ b/app/src/main/res/layout/fragment_easy_indicator.xml
@@ -25,22 +25,38 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
- app:indicator_line_show="true"
- app:indicator_line_height="2dp"
app:indicator_height="42dp"
+ app:indicator_line_height="2dp"
+ app:indicator_line_show="true"
app:indicator_textSize="14sp"
app:indicator_width="0dp" />
+ app:indicator_vertical_line_h="30dp"
+ app:indicator_vertical_line_w="1dp"
+ app:indicator_width="300dp" />
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml
index b8089a42..fae01de0 100644
--- a/app/src/main/res/values-v21/styles.xml
+++ b/app/src/main/res/values-v21/styles.xml
@@ -53,6 +53,9 @@
- @color/colorPrimaryDark
- @color/colorAccent
+
+ - @style/Button.AlertDialog
+
- true
- false
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 01422020..53ccbd8a 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -81,4 +81,7 @@
#f2f2f2
#9C27B0
+
+ #FFF1F1F1
+
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 81f7d1b8..773f2fc1 100755
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -33,4 +33,15 @@
24dp
60dp
+ 16dp
+ 14dp
+ 10dp
+ 20dp
+ 8dp
+ 5dp
+ 18dp
+ 30dp
+ 12dp
+ 24dp
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ccc5e124..5095e287 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -455,4 +455,9 @@ The lake was formed about 2 million years ago and is a part of the Lake Tahoe Ba
Lake Tahoe
分类展示
+ 上一条
+ 下一条
+ 以后不再提示此类信息
+ 你知道吗?
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 21782ab1..0c545746 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -60,6 +60,9 @@
- @color/colorPrimaryDark
- @color/colorAccent
+
+ - @style/Button.AlertDialog
+
- true
- false
diff --git a/versions.gradle b/versions.gradle
index 6125590f..caa346e2 100644
--- a/versions.gradle
+++ b/versions.gradle
@@ -116,7 +116,7 @@ static def addRepos(RepositoryHandler handler) {
handler.jcenter { url 'https://maven.aliyun.com/repository/jcenter' }
handler.mavenCentral { url 'https://maven.aliyun.com/repository/central' }
handler.maven { url "https://jitpack.io" }
- handler.maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
+ handler.maven { url 'https://maven.aliyun.com/repository/public' }
handler.maven { url "https://dl.bintray.com/umsdk/release" }
handler.maven { url 'https://oss.sonatype.org/content/repositories/public' }
//Add the Local repository
diff --git a/widget_compiler/src/main/java/com/xuexiang/compiler/PageConfigProcessor.java b/widget_compiler/src/main/java/com/xuexiang/compiler/PageConfigProcessor.java
index ad901f51..9689532a 100755
--- a/widget_compiler/src/main/java/com/xuexiang/compiler/PageConfigProcessor.java
+++ b/widget_compiler/src/main/java/com/xuexiang/compiler/PageConfigProcessor.java
@@ -62,11 +62,11 @@ public class PageConfigProcessor extends AbstractProcessor {
*/
private String moduleName = null;
/**
- * Page name where page configuration is located
+ * 页面配置所在的包名
*/
- private static final String PACKAGE_NAME = "com.xuexiang.xpage";
+ private static final String PAGE_CONFIG_PACKAGE_NAME = "com.xuexiang.xpage.config";
- private static final String PAGE_CONFIG_CLASS_NAME = "PageConfig";
+ private static final String PAGE_CONFIG_CLASS_NAME_SUFFIX = "PageConfig";
private TypeMirror mFragment = null;
@@ -131,7 +131,7 @@ private void parsePages(Set extends Element> pageElements) throws IOException
if (CollectionUtils.isNotEmpty(pageElements)) {
mLogger.info(">>> Found Pages, size is " + pageElements.size() + " <<<");
- ClassName pageConfigClassName = ClassName.get(PACKAGE_NAME, upperFirstLetter(moduleName) + PAGE_CONFIG_CLASS_NAME);
+ ClassName pageConfigClassName = ClassName.get(PAGE_CONFIG_PACKAGE_NAME, upperFirstLetter(moduleName) + PAGE_CONFIG_CLASS_NAME_SUFFIX);
TypeSpec.Builder pageConfigBuilder = TypeSpec.classBuilder(pageConfigClassName);
/*
@@ -307,7 +307,7 @@ private void parsePages(Set extends Element> pageElements) throws IOException
.addMethod(getComponentsMethod)
.addMethod(getUtilsMethod)
.addMethod(getExpandsMethod);
- JavaFile.builder(PACKAGE_NAME, pageConfigBuilder.build()).build().writeTo(mFiler);
+ JavaFile.builder(PAGE_CONFIG_PACKAGE_NAME, pageConfigBuilder.build()).build().writeTo(mFiler);
}
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/utils/KeyboardUtils.java b/xui_lib/src/main/java/com/xuexiang/xui/utils/KeyboardUtils.java
index a978378f..169f63c0 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/utils/KeyboardUtils.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/utils/KeyboardUtils.java
@@ -20,6 +20,7 @@
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.graphics.Rect;
import android.os.Build;
import android.view.KeyEvent;
@@ -396,6 +397,30 @@ public static void hideSoftInput(final View view) {
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
+ /**
+ * 动态隐藏弹窗弹出的软键盘【注意:一定要在dialog.dismiss之前调用】
+ *
+ * @param dialog 对话框
+ */
+ public static void hideSoftInput(@NonNull DialogInterface dialog) {
+ if (dialog instanceof Dialog) {
+ hideSoftInput((Dialog) dialog);
+ }
+ }
+
+ /**
+ * 动态隐藏弹窗弹出的软键盘【注意:一定要在dialog.dismiss之前调用】
+ *
+ * @param dialog 对话框
+ */
+ public static void hideSoftInput(@NonNull Dialog dialog) {
+ View view = dialog.getCurrentFocus();
+ if (view == null && dialog.getWindow() != null) {
+ view = dialog.getWindow().getDecorView();
+ }
+ hideSoftInput(view);
+ }
+
/**
* 动态隐藏软键盘并且清除当前view的焦点【记住,要在xml的父布局加上android:focusable="true" 和 android:focusableInTouchMode="true"】
*
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/utils/ViewUtils.java b/xui_lib/src/main/java/com/xuexiang/xui/utils/ViewUtils.java
index 2523e243..6c76d2fc 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/utils/ViewUtils.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/utils/ViewUtils.java
@@ -1102,6 +1102,53 @@ public static void setViewsFont(View... views) {
setViewsFont(XUI.getDefaultTypeface(), views);
}
+ /**
+ * 清除控件的长按事件
+ *
+ * @param rootView 根布局
+ * @param ids 需要清除的控件id集合
+ */
+ public static void clearViewLongClick(View rootView, int... ids) {
+ if (rootView == null || ids == null || ids.length == 0) {
+ return;
+ }
+ for (int id : ids) {
+ View view = rootView.findViewById(id);
+ if (view != null) {
+ view.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ return true;
+ }
+ });
+ }
+ }
+ }
+
+ /**
+ * 清除所有控件的长按事件
+ *
+ * @param view 根布局
+ */
+ public static void clearAllViewLongClick(View view) {
+ if (view == null) {
+ return;
+ }
+ if (view instanceof ViewGroup) {
+ ViewGroup viewGroup = (ViewGroup) view;
+ for (int i = 0; i < viewGroup.getChildCount(); i++) {
+ clearAllViewLongClick(viewGroup.getChildAt(i));
+ }
+ } else {
+ view.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ return true;
+ }
+ });
+ }
+ }
+
/**
* 设置CollapsingToolbarLayout选项卡的字体
*
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/utils/WidgetUtils.java b/xui_lib/src/main/java/com/xuexiang/xui/utils/WidgetUtils.java
index 3ca51e00..bc263e2d 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/utils/WidgetUtils.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/utils/WidgetUtils.java
@@ -19,6 +19,7 @@
import android.app.Activity;
import android.content.Context;
+import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
@@ -27,6 +28,7 @@
import android.view.Window;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
+import android.widget.FrameLayout;
import android.widget.Spinner;
import android.widget.TextView;
@@ -34,6 +36,7 @@
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.RecyclerView;
+import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.android.material.tabs.TabLayout;
import com.xuexiang.xui.R;
import com.xuexiang.xui.XUI;
@@ -363,4 +366,18 @@ public static MiniLoadingDialog getMiniLoadingDialog(@NonNull Context context, @
}
+ /**
+ * 隐藏底部弹窗的背景颜色(用于显示圆角)
+ *
+ * @param dialog 底部弹窗
+ */
+ public static void transparentBottomSheetDialogBackground(BottomSheetDialog dialog) {
+ if (dialog != null && dialog.getWindow() != null) {
+ FrameLayout frameLayout = dialog.getWindow().findViewById(R.id.design_bottom_sheet);
+ if (frameLayout != null) {
+ frameLayout.setBackgroundColor(Color.TRANSPARENT);
+ }
+ }
+ }
+
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/strategy/impl/AlertDialogStrategy.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/strategy/impl/AlertDialogStrategy.java
index f0b379ce..81078190 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/strategy/impl/AlertDialogStrategy.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/dialog/strategy/impl/AlertDialogStrategy.java
@@ -21,13 +21,13 @@
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
+import android.widget.EditText;
+import android.widget.FrameLayout;
import androidx.annotation.ArrayRes;
import androidx.annotation.NonNull;
-import android.widget.EditText;
-import android.widget.FrameLayout;
-
+import com.xuexiang.xui.R;
import com.xuexiang.xui.utils.DensityUtils;
import com.xuexiang.xui.widget.dialog.strategy.IDialogStrategy;
import com.xuexiang.xui.widget.dialog.strategy.InputCallback;
@@ -41,6 +41,24 @@
*/
public class AlertDialogStrategy implements IDialogStrategy {
+ /**
+ * 弹窗的主题
+ */
+ private int mThemeStyle;
+
+ public AlertDialogStrategy() {
+ mThemeStyle = R.style.XUITheme_AlertDialog;
+ }
+
+ /**
+ * 构造AlertDialog 策略
+ *
+ * @param themeStyle 弹窗的主题
+ */
+ public AlertDialogStrategy(int themeStyle) {
+ mThemeStyle = themeStyle;
+ }
+
/**
* 获取对话框的构建者
*
@@ -50,9 +68,9 @@ public class AlertDialogStrategy implements IDialogStrategy {
*/
private AlertDialog.Builder getBuilder(Context context, int icon) {
if (icon == NO_ICON) {
- return new AlertDialog.Builder(context);
+ return new AlertDialog.Builder(context, mThemeStyle);
} else {
- return new AlertDialog.Builder(context)
+ return new AlertDialog.Builder(context, mThemeStyle)
.setIcon(icon);
}
}
@@ -87,7 +105,7 @@ public Dialog showTipDialog(Context context, int icon, String title, String cont
*/
@Override
public Dialog showTipDialog(Context context, String title, String content, String submitText) {
- return new AlertDialog.Builder(context)
+ return new AlertDialog.Builder(context, mThemeStyle)
.setTitle(title)
.setMessage(content)
.setPositiveButton(submitText, null)
@@ -108,7 +126,7 @@ public Dialog showTipDialog(Context context, String title, String content, Strin
*/
@Override
public Dialog showConfirmDialog(Context context, String title, String content, String submitText, DialogInterface.OnClickListener submitListener, String cancelText, DialogInterface.OnClickListener cancelListener) {
- return new AlertDialog.Builder(context)
+ return new AlertDialog.Builder(context, mThemeStyle)
.setTitle(title)
.setMessage(content)
.setPositiveButton(submitText, submitListener)
@@ -129,7 +147,7 @@ public Dialog showConfirmDialog(Context context, String title, String content, S
*/
@Override
public Dialog showConfirmDialog(Context context, String content, String submitText, DialogInterface.OnClickListener submitListener, String cancelText, DialogInterface.OnClickListener cancelListener) {
- return new AlertDialog.Builder(context)
+ return new AlertDialog.Builder(context, mThemeStyle)
.setMessage(content)
.setPositiveButton(submitText, submitListener)
.setNegativeButton(cancelText, cancelListener)
@@ -148,7 +166,7 @@ public Dialog showConfirmDialog(Context context, String content, String submitTe
*/
@Override
public Dialog showConfirmDialog(Context context, String content, String submitText, DialogInterface.OnClickListener submitListener, String cancelText) {
- return new AlertDialog.Builder(context)
+ return new AlertDialog.Builder(context, mThemeStyle)
.setMessage(content)
.setPositiveButton(submitText, submitListener)
.setNegativeButton(cancelText, null)
@@ -205,7 +223,7 @@ public void onClick(DialogInterface dialog, int which) {
@Override
public Dialog showContextMenuDialog(Context context, String title, String[] items, DialogInterface.OnClickListener listener) {
- return new AlertDialog.Builder(context)
+ return new AlertDialog.Builder(context, mThemeStyle)
.setTitle(title)
.setItems(items, listener)
.show();
@@ -213,7 +231,7 @@ public Dialog showContextMenuDialog(Context context, String title, String[] item
@Override
public Dialog showContextMenuDialog(Context context, String title, @ArrayRes int itemsId, DialogInterface.OnClickListener listener) {
- return new AlertDialog.Builder(context)
+ return new AlertDialog.Builder(context, mThemeStyle)
.setTitle(title)
.setItems(itemsId, listener)
.show();
@@ -221,7 +239,7 @@ public Dialog showContextMenuDialog(Context context, String title, @ArrayRes int
@Override
public Dialog showSingleChoiceDialog(Context context, String title, String[] items, int selectedIndex, final DialogInterface.OnClickListener listener, String submitText, String cancelText) {
- return new AlertDialog.Builder(context)
+ return new AlertDialog.Builder(context, mThemeStyle)
.setTitle(title)
.setSingleChoiceItems(items, selectedIndex, new DialogInterface.OnClickListener() {
@Override
@@ -238,7 +256,7 @@ public void onClick(DialogInterface dialog, int which) {
@Override
public Dialog showSingleChoiceDialog(Context context, String title, int itemsId, int selectedIndex, final DialogInterface.OnClickListener listener, String submitText, String cancelText) {
- return new AlertDialog.Builder(context)
+ return new AlertDialog.Builder(context, mThemeStyle)
.setTitle(title)
.setSingleChoiceItems(itemsId, selectedIndex, new DialogInterface.OnClickListener() {
@Override
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/EasyIndicator.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/EasyIndicator.java
index 3ab07b03..b758ee87 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/EasyIndicator.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/EasyIndicator.java
@@ -24,6 +24,7 @@
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
@@ -52,14 +53,14 @@
* @since 2018/12/20 上午12:32
*/
public class EasyIndicator extends LinearLayout implements View.OnClickListener, ViewPager.OnPageChangeListener, HasTypeface {
- private View mIndicator;
+ private LinearLayout mIndicatorContainer;
private ViewPager mViewPager;
/**
* 选项卡点击监听
*/
- public onTabClickListener mOnTabClickListener;
+ public OnTabClickListener mOnTabClickListener;
- private LinearLayout tab_content;
+ private LinearLayout tabContent;
/**
* Tab集合
*/
@@ -77,56 +78,63 @@ public class EasyIndicator extends LinearLayout implements View.OnClickListener,
/**
* tab宽度,默认填充全屏
*/
- private int indicator_width = -1;
+ private int indicatorWidth = LayoutParams.MATCH_PARENT;
//==============//
/**
* 是否显示指示器
*/
- private boolean indicator_line_show = true;
+ private boolean indicatorLineShow = true;
/**
* 指示器默认高度
*/
- private int indicator_line_height = 3;
+ private int indicatorLineHeight = 3;
+ /**
+ * 指示器默认宽度
+ */
+ private int indicatorLineWidth = LayoutParams.MATCH_PARENT;
/**
* 指示器颜色
*/
- private int indicator_line_color;
+ private int indicatorLineColor;
+ /**
+ * 指示器资源
+ */
+ private Drawable indicatorLineDrawable;
//==============//
/**
* 指示器底部线条高度
*/
- private int indicator_bottom_line_height = 0;
+ private int indicatorBottomLineHeight = 0;
/**
* 指示器底部线条颜色
*/
- private int indicator_bottom_line_color;
+ private int indicatorBottomLineColor;
/**
* 中间分割线宽度
*/
- private int indicator_vertical_line_w = 0;
+ private int indicatorVerticalLineWidth = 0;
/**
* 中间分割线高度
*/
- private int indicator_vertical_line_h = 0;
+ private int indicatorVerticalLineHeight = 0;
/**
* 中间分割线颜色
*/
- private int indicator_vertical_line_color;
-
+ private int indicatorVerticalLineColor;
/**
* 选中颜色和默认颜色
*/
- private int indicator_selected_color, indicator_normal_color;
+ private int indicatorSelectedColor, indicatorNormalColor;
/**
* 默认字体大小
*/
- private float indicator_textSize = 14;
+ private float indicatorTextSize = 14;
/**
* 选中字体大小
*/
- private float indicator_select_textSize = indicator_textSize;
+ private float indicatorSelectTextSize = indicatorTextSize;
public EasyIndicator(Context context) {
this(context, null);
@@ -147,44 +155,48 @@ public EasyIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
* 初始化View
*/
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.EasyIndicator, defStyleAttr, 0);
- if (a != null) {
- indicatorHeight = (int) getDimensionPixelSize(a, R.styleable.EasyIndicator_indicator_height, indicatorHeight);
- indicator_line_height = (int) getDimensionPixelSize(a, R.styleable.EasyIndicator_indicator_line_height, indicator_line_height);
- indicator_bottom_line_height = (int) getDimensionPixelSize(a, R.styleable.EasyIndicator_indicator_bottom_line_height, indicator_bottom_line_height);
- indicator_bottom_line_color = a.getColor(R.styleable.EasyIndicator_indicator_bottom_line_color, ThemeUtils.resolveColor(getContext(), R.attr.xui_config_color_separator_dark));
- indicator_selected_color = a.getColor(R.styleable.EasyIndicator_indicator_selected_color, ThemeUtils.resolveColor(getContext(), R.attr.colorAccent));
- indicator_normal_color = a.getColor(R.styleable.EasyIndicator_indicator_normal_color, ResUtils.getColor(R.color.xui_config_color_black));
- indicator_line_color = a.getColor(R.styleable.EasyIndicator_indicator_line_color, ThemeUtils.resolveColor(getContext(), R.attr.colorAccent));
- indicator_textSize = getDimensionPixelSize(a, R.styleable.EasyIndicator_indicator_textSize, (int) indicator_textSize);
- indicator_line_show = a.getBoolean(R.styleable.EasyIndicator_indicator_line_show, indicator_line_show);
- indicator_vertical_line_w = (int) getDimensionPixelSize(a, R.styleable.EasyIndicator_indicator_vertical_line_w, indicator_vertical_line_w);
- indicator_vertical_line_color = a.getColor(R.styleable.EasyIndicator_indicator_vertical_line_color, ThemeUtils.resolveColor(getContext(), R.attr.xui_config_color_separator_dark));
- indicator_vertical_line_h = (int) getDimensionPixelSize(a, R.styleable.EasyIndicator_indicator_vertical_line_h, indicator_vertical_line_h);
- indicator_width = (int) getDimensionPixelSize(a, R.styleable.EasyIndicator_indicator_width, indicator_width);
- indicator_select_textSize = getDimensionPixelSize(a, R.styleable.EasyIndicator_indicator_select_textSize, 14);
- if (indicator_width == 0) {
- indicator_width = -1;
+ TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.EasyIndicator, defStyleAttr, 0);
+ if (typedArray != null) {
+ indicatorWidth = (int) getDimensionPixelSize(typedArray, R.styleable.EasyIndicator_indicator_width, indicatorWidth);
+ indicatorHeight = (int) getDimensionPixelSize(typedArray, R.styleable.EasyIndicator_indicator_height, indicatorHeight);
+ indicatorLineShow = typedArray.getBoolean(R.styleable.EasyIndicator_indicator_line_show, indicatorLineShow);
+ indicatorLineWidth = (int) getDimensionPixelSize(typedArray, R.styleable.EasyIndicator_indicator_line_width, indicatorLineWidth);
+ indicatorLineHeight = (int) getDimensionPixelSize(typedArray, R.styleable.EasyIndicator_indicator_line_height, indicatorLineHeight);
+ indicatorLineColor = typedArray.getColor(R.styleable.EasyIndicator_indicator_line_color, ThemeUtils.resolveColor(getContext(), R.attr.colorAccent));
+ indicatorLineDrawable = ResUtils.getDrawableAttrRes(context, typedArray, R.styleable.EasyIndicator_indicator_line_res);
+ indicatorBottomLineHeight = (int) getDimensionPixelSize(typedArray, R.styleable.EasyIndicator_indicator_bottom_line_height, indicatorBottomLineHeight);
+ indicatorBottomLineColor = typedArray.getColor(R.styleable.EasyIndicator_indicator_bottom_line_color, ThemeUtils.resolveColor(getContext(), R.attr.xui_config_color_separator_dark));
+ indicatorSelectedColor = typedArray.getColor(R.styleable.EasyIndicator_indicator_selected_color, ThemeUtils.resolveColor(getContext(), R.attr.colorAccent));
+ indicatorNormalColor = typedArray.getColor(R.styleable.EasyIndicator_indicator_normal_color, ResUtils.getColor(R.color.xui_config_color_black));
+ indicatorTextSize = getDimensionPixelSize(typedArray, R.styleable.EasyIndicator_indicator_textSize, (int) indicatorTextSize);
+ indicatorVerticalLineWidth = (int) getDimensionPixelSize(typedArray, R.styleable.EasyIndicator_indicator_vertical_line_w, indicatorVerticalLineWidth);
+ indicatorVerticalLineColor = typedArray.getColor(R.styleable.EasyIndicator_indicator_vertical_line_color, ThemeUtils.resolveColor(getContext(), R.attr.xui_config_color_separator_dark));
+ indicatorVerticalLineHeight = (int) getDimensionPixelSize(typedArray, R.styleable.EasyIndicator_indicator_vertical_line_h, indicatorVerticalLineHeight);
+ indicatorSelectTextSize = getDimensionPixelSize(typedArray, R.styleable.EasyIndicator_indicator_select_textSize, 14);
+ // 指引器不能超过屏幕的宽度
+ indicatorWidth = Math.min(indicatorWidth, screenWidth);
+ if (indicatorWidth == 0) {
+ indicatorWidth = LayoutParams.MATCH_PARENT;
}
- a.recycle();
+ typedArray.recycle();
}
-
- tab_content = new LinearLayout(getContext());
- LayoutParams params = new LayoutParams(indicator_width, LayoutParams.WRAP_CONTENT);
- tab_content.setBackgroundColor(Color.WHITE);
+ tabContent = new LinearLayout(getContext());
+ LayoutParams params = new LayoutParams(indicatorWidth, LayoutParams.WRAP_CONTENT);
+ tabContent.setBackgroundColor(Color.WHITE);
params.gravity = Gravity.CENTER;
- tab_content.setLayoutParams(params);
+ tabContent.setLayoutParams(params);
+ tabContent.setGravity(Gravity.CENTER);
}
/**
- * 设置tab item
+ * 设置tab的标题
*
- * @param tabTitles
+ * @param tabTitles tab的标题
*/
public void setTabTitles(String[] tabTitles) {
// Create tab
tvs = new TextView[tabTitles.length];
- tab_content.removeAllViews();
+ tabContent.removeAllViews();
TextView view;
for (int i = 0; i < tabTitles.length; i++) {
view = new TextView(getContext());
@@ -195,48 +207,55 @@ public void setTabTitles(String[] tabTitles) {
view.setGravity(Gravity.CENTER);
LayoutParams lp = new LayoutParams(0, indicatorHeight, 1.0f);
view.setLayoutParams(lp);
- switch (i) {
- case 0:
- view.setTextColor(indicator_selected_color);
- view.setTextSize(TypedValue.COMPLEX_UNIT_PX, indicator_select_textSize);
- break;
- default:
- view.setTextColor(indicator_normal_color);
- view.setTextSize(TypedValue.COMPLEX_UNIT_PX, indicator_textSize);
- break;
+ if (i == 0) {
+ view.setTextColor(indicatorSelectedColor);
+ view.setTextSize(TypedValue.COMPLEX_UNIT_PX, indicatorSelectTextSize);
+ } else {
+ view.setTextColor(indicatorNormalColor);
+ view.setTextSize(TypedValue.COMPLEX_UNIT_PX, indicatorTextSize);
}
view.setOnClickListener(this);
tvs[i] = view;
- tab_content.addView(view);
+ tabContent.addView(view);
if (i != tabTitles.length - 1) {
View line = new View(getContext());
- line.setBackgroundColor(indicator_vertical_line_color);
- LinearLayoutCompat.LayoutParams compat = new LinearLayoutCompat.LayoutParams(indicator_vertical_line_w, indicator_vertical_line_h);
+ line.setBackgroundColor(indicatorVerticalLineColor);
+ LinearLayoutCompat.LayoutParams compat = new LinearLayoutCompat.LayoutParams(indicatorVerticalLineWidth, indicatorVerticalLineHeight);
line.setLayoutParams(compat);
- tab_content.addView(line);
+ tabContent.addView(line);
}
}
removeAllViews();
- addView(tab_content);
-
- if (indicator_line_show) {
- // Create tab mIndicator
- mIndicator = new View(getContext());
- int iw = 0;
- if (indicator_width == 0 || indicator_width == -1) {
- iw = screenWidth / tvs.length;
+ addView(tabContent);
+
+ if (indicatorLineShow) {
+ mIndicatorContainer = new LinearLayout(getContext());
+ mIndicatorContainer.setGravity(Gravity.CENTER);
+ int iw = indicatorWidth > 0 ? indicatorWidth / tvs.length : screenWidth / tvs.length;
+ mIndicatorContainer.setLayoutParams(new LinearLayoutCompat.LayoutParams(iw, indicatorLineHeight));
+ View indicator = new View(getContext());
+ indicator.setLayoutParams(new LinearLayoutCompat.LayoutParams(indicatorLineWidth > 0 ? indicatorLineWidth : LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ if (indicatorLineDrawable != null) {
+ indicator.setBackground(indicatorLineDrawable);
+ } else {
+ indicator.setBackgroundColor(indicatorLineColor);
+ }
+ mIndicatorContainer.addView(indicator);
+ addView(mIndicatorContainer);
+ if (indicatorWidth > 0) {
+ LayoutParams ll = (LayoutParams) mIndicatorContainer
+ .getLayoutParams();
+ ll.setMarginStart((screenWidth - indicatorWidth) / 2);
+ mIndicatorContainer.setLayoutParams(ll);
}
- mIndicator.setLayoutParams(new LinearLayoutCompat.LayoutParams(iw, indicator_line_height));
- mIndicator.setBackgroundColor(indicator_line_color);
- addView(mIndicator);
}
// Create tab bottom line
View line = new View(getContext());
- LinearLayoutCompat.LayoutParams params = new LinearLayoutCompat.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, indicator_bottom_line_height);
+ LinearLayoutCompat.LayoutParams params = new LinearLayoutCompat.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, indicatorBottomLineHeight);
line.setLayoutParams(params);
- line.setBackgroundColor(indicator_bottom_line_color);
+ line.setBackgroundColor(indicatorBottomLineColor);
addView(line);
}
@@ -269,15 +288,15 @@ public void setViewPager(ViewPager viewPage, PagerAdapter adapter) {
}
private AnimatorSet buildIndicatorAnimatorTowards(TextView tv) {
- float x = tab_content.getX();
- ObjectAnimator xAnimator = ObjectAnimator.ofFloat(mIndicator, "X", mIndicator.getX(), tv.getX() + x);
- final ViewGroup.LayoutParams params = mIndicator.getLayoutParams();
+ float x = tabContent.getX();
+ ObjectAnimator xAnimator = ObjectAnimator.ofFloat(mIndicatorContainer, "X", mIndicatorContainer.getX(), tv.getX() + x);
+ final ViewGroup.LayoutParams params = mIndicatorContainer.getLayoutParams();
ValueAnimator widthAnimator = ValueAnimator.ofInt(params.width, tv.getMeasuredWidth());
widthAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
params.width = (Integer) animation.getAnimatedValue();
- mIndicator.setLayoutParams(params);
+ mIndicatorContainer.setLayoutParams(params);
}
});
AnimatorSet set = new AnimatorSet();
@@ -290,50 +309,50 @@ public void onAnimationUpdate(ValueAnimator animation) {
@Override
public void onClick(View v) {
TextView tv = (TextView) v;
- int mPosition = (int) v.getTag();
+ int position = (int) v.getTag();
if (mViewPager != null) {
- mViewPager.setCurrentItem(mPosition);
+ mViewPager.setCurrentItem(position);
} else {
setSelectorColor(tv);
- if (indicator_line_show) {
+ if (indicatorLineShow) {
buildIndicatorAnimatorTowards(tv).start();
}
}
if (mOnTabClickListener != null) {
- mOnTabClickListener.onTabClick(((TextView) v).getText().toString(), mPosition);
+ mOnTabClickListener.onTabClick(((TextView) v).getText().toString(), position);
}
}
private void setSelectorColor(TextView tv) {
for (TextView textView : tvs) {
- textView.setTextColor(indicator_normal_color);
- textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, indicator_textSize);
+ textView.setTextColor(indicatorNormalColor);
+ textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, indicatorTextSize);
}
- tv.setTextColor(indicator_selected_color);
- tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, indicator_select_textSize);
+ tv.setTextColor(indicatorSelectedColor);
+ tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, indicatorSelectTextSize);
}
/**
* 设置选项卡点击监听
*
- * @param onTabClickListener
+ * @param onTabClickListener 选项卡点击监听
*/
- public void setOnTabClickListener(EasyIndicator.onTabClickListener onTabClickListener) {
+ public void setOnTabClickListener(OnTabClickListener onTabClickListener) {
mOnTabClickListener = onTabClickListener;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- LayoutParams ll = (LayoutParams) mIndicator
+ LayoutParams ll = (LayoutParams) mIndicatorContainer
.getLayoutParams();
if (mCurrIndex == position) {
- ll.setMarginStart((int) (mCurrIndex * mIndicator.getMeasuredWidth() + positionOffset
- * mIndicator.getMeasuredWidth()));
+ ll.setMarginStart((int) (mCurrIndex * mIndicatorContainer.getMeasuredWidth() + positionOffset
+ * mIndicatorContainer.getMeasuredWidth()));
} else if (mCurrIndex > position) {
- ll.setMarginStart((int) (mCurrIndex * mIndicator.getMeasuredWidth() - (1 - positionOffset)
- * mIndicator.getMeasuredWidth()));
+ ll.setMarginStart((int) (mCurrIndex * mIndicatorContainer.getMeasuredWidth() - (1 - positionOffset)
+ * mIndicatorContainer.getMeasuredWidth()));
}
- mIndicator.setLayoutParams(ll);
+ mIndicatorContainer.setLayoutParams(ll);
}
@Override
@@ -356,16 +375,18 @@ public void setTypeface(Typeface typeface) {
}
}
-
/**
* 选项卡点击监听
+ *
+ * @author xuexiang
+ * @since 2021/3/14 3:38 PM
*/
- public interface onTabClickListener {
+ public interface OnTabClickListener {
/**
* tab点击
*
- * @param title
- * @param position
+ * @param title 标题
+ * @param position 位置
*/
void onTabClick(String title, int position);
}
@@ -396,7 +417,6 @@ private float getPixelSizeBySp(int sp) {
return sp * scale;
}
-
/**
* 初始化屏幕宽高
*/
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/TabSegment.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/TabSegment.java
index 2ce2158c..ab4eb608 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/TabSegment.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/tabbar/TabSegment.java
@@ -117,8 +117,13 @@ public class TabSegment extends HorizontalScrollView {
private static final String TAG = "TabSegment";
- // mode: 自适应宽度+滚动 / 均分
+ /**
+ * 自适应宽度+滚动
+ */
public static final int MODE_SCROLLABLE = 0;
+ /**
+ * 均分
+ */
public static final int MODE_FIXED = 1;
// icon position
public static final int ICON_POSITION_LEFT = 0;
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/ExpandableTextView.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/ExpandableTextView.java
index 891f2288..7a62461d 100755
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/ExpandableTextView.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/ExpandableTextView.java
@@ -6,6 +6,7 @@
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
+import android.text.Layout;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.SparseBooleanArray;
@@ -318,7 +319,8 @@ private static Drawable getDrawable(@NonNull Context context, @DrawableRes int r
}
private static int getRealTextViewHeight(@NonNull TextView textView) {
- int textHeight = textView.getLayout().getLineTop(textView.getLineCount());
+ Layout layout = textView.getLayout();
+ int textHeight = layout != null ? layout.getLineTop(textView.getLineCount()) : 0;
int padding = textView.getCompoundPaddingTop() + textView.getCompoundPaddingBottom();
return textHeight + padding;
}
diff --git a/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/LoggerTextView.java b/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/LoggerTextView.java
index 2feb2df3..fbbe6593 100644
--- a/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/LoggerTextView.java
+++ b/xui_lib/src/main/java/com/xuexiang/xui/widget/textview/LoggerTextView.java
@@ -19,12 +19,14 @@
import android.content.Context;
import android.os.Looper;
+import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.method.ScrollingMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatTextView;
@@ -39,6 +41,16 @@
*/
public class LoggerTextView extends AppCompatTextView {
+ /**
+ * 日志格式化接口
+ */
+ private ILogFormatter mLogFormatter = new DefaultLogFormatter();
+
+ /**
+ * 日志装饰接口
+ */
+ private ILogDecorator mLogDecorator = new DefaultLogDecorator();
+
public LoggerTextView(Context context) {
this(context, null);
}
@@ -52,6 +64,29 @@ public LoggerTextView(Context context, @Nullable AttributeSet attrs, int defStyl
setMovementMethod(new ScrollingMovementMethod());
}
+ /**
+ * 设置日志格式化接口
+ *
+ * @param logFormatter 日志格式化接口
+ * @return 日志打印显示控件
+ */
+ public LoggerTextView setLogFormatter(@NonNull ILogFormatter logFormatter) {
+ mLogFormatter = logFormatter;
+ return this;
+ }
+
+
+ /**
+ * 设置日志装饰接口
+ *
+ * @param logDecorator 日志装饰接口
+ * @return 日志打印显示控件
+ */
+ public LoggerTextView setLogDecorator(@NonNull ILogDecorator logDecorator) {
+ mLogDecorator = logDecorator;
+ return this;
+ }
+
/**
* 添加普通日志
*
@@ -90,6 +125,16 @@ public void logWarning(String logContent) {
addLog(logContent, LogType.WARNING);
}
+ /**
+ * 添加自定义等级日志
+ *
+ * @param logContent 日志内容
+ */
+
+ public void logCustom(String logContent) {
+ addLog(logContent, LogType.CUSTOM);
+ }
+
/**
* 添加日志
*
@@ -97,29 +142,7 @@ public void logWarning(String logContent) {
* @param logType 日志类型
*/
public void addLog(String logContent, LogType logType) {
- SpannableString spannableString = new SpannableString(logContent);
- switch (logType) {
- case ERROR:
- spannableString.setSpan(new ForegroundColorSpan(ResUtils.getColor(R.color.xui_config_color_error)),
- 0,
- logContent.length(),
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- break;
- case SUCCESS:
- spannableString.setSpan(new ForegroundColorSpan(ResUtils.getColor(R.color.xui_config_color_success)),
- 0,
- logContent.length(),
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- break;
- case WARNING:
- spannableString.setSpan(new ForegroundColorSpan(ResUtils.getColor(R.color.xui_config_color_waring)),
- 0,
- logContent.length(),
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- break;
- default:
- break;
- }
+ SpannableString spannableString = getLogDecorator().decorate(getLogFormatter().format(logContent, logType), logType);
appendLogInMainThread(spannableString);
}
@@ -136,6 +159,31 @@ public void run() {
}
}
+
+ /**
+ * 获取日志装饰接口
+ *
+ * @return 日志装饰接口
+ */
+ public ILogDecorator getLogDecorator() {
+ if (mLogDecorator == null) {
+ mLogDecorator = new DefaultLogDecorator();
+ }
+ return mLogDecorator;
+ }
+
+ /**
+ * 获取日志格式化接口
+ *
+ * @return 日志格式化接口
+ */
+ public ILogFormatter getLogFormatter() {
+ if (mLogFormatter == null) {
+ mLogFormatter = new DefaultLogFormatter();
+ }
+ return mLogFormatter;
+ }
+
private void appendLog(SpannableString spannableString) {
append(spannableString);
append("\r\n");
@@ -156,7 +204,8 @@ private void scrollToEnd() {
* @return 获取当前TextView文字的真实高度
*/
private int getTextRealHeight() {
- return getLayout().getLineTop(getLineCount()) + getCompoundPaddingTop() + getCompoundPaddingBottom();
+ Layout layout = getLayout();
+ return (layout != null ? layout.getLineTop(getLineCount()) : 0) + getCompoundPaddingTop() + getCompoundPaddingBottom();
}
/**
@@ -177,6 +226,92 @@ public void run() {
}
}
+ /**
+ * 默认日志格式化接口
+ *
+ * @author xuexiang
+ * @since 2021/4/14 1:48 AM
+ */
+ public static class DefaultLogFormatter implements ILogFormatter {
+
+ @Override
+ public String format(String logContent, LogType logType) {
+ return logContent;
+ }
+ }
+
+ /**
+ * 日志格式化接口
+ *
+ * @author xuexiang
+ * @since 2021/4/14 1:30 AM
+ */
+ public interface ILogFormatter {
+ /**
+ * 格式化日志内容
+ *
+ * @param logContent 日志内容
+ * @param logType 日志类型
+ * @return 格式化后的日志
+ */
+ String format(String logContent, LogType logType);
+ }
+
+
+ /**
+ * 默认日志装饰接口
+ *
+ * @author xuexiang
+ * @since 2021/4/14 1:49 AM
+ */
+ public static class DefaultLogDecorator implements ILogDecorator {
+
+ @Override
+ public SpannableString decorate(String logContent, LogType logType) {
+ SpannableString spannableString = new SpannableString(logContent);
+ switch (logType) {
+ case ERROR:
+ spannableString.setSpan(new ForegroundColorSpan(ResUtils.getColor(R.color.xui_config_color_error)),
+ 0,
+ logContent.length(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ break;
+ case SUCCESS:
+ spannableString.setSpan(new ForegroundColorSpan(ResUtils.getColor(R.color.xui_config_color_success)),
+ 0,
+ logContent.length(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ break;
+ case WARNING:
+ spannableString.setSpan(new ForegroundColorSpan(ResUtils.getColor(R.color.xui_config_color_waring)),
+ 0,
+ logContent.length(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ break;
+ default:
+ break;
+ }
+ return spannableString;
+ }
+ }
+
+ /**
+ * 日志装饰接口
+ *
+ * @author xuexiang
+ * @since 2021/4/14 1:30 AM
+ */
+ public interface ILogDecorator {
+ /**
+ * 装饰日志内容
+ *
+ * @param logContent 日志内容
+ * @param logType 日志类型
+ * @return 装饰后的日志
+ */
+ SpannableString decorate(String logContent, LogType logType);
+ }
+
/**
* 日志类型
*/
@@ -196,7 +331,11 @@ public enum LogType {
/**
* 警告日志
*/
- WARNING
+ WARNING,
+ /**
+ * 自定义等级日志
+ */
+ CUSTOM
}
diff --git a/xui_lib/src/main/res/drawable-hdpi/xui_icon_checkbox_checked.png b/xui_lib/src/main/res/drawable-v17/xui_icon_checkbox_checked.png
similarity index 100%
rename from xui_lib/src/main/res/drawable-hdpi/xui_icon_checkbox_checked.png
rename to xui_lib/src/main/res/drawable-v17/xui_icon_checkbox_checked.png
diff --git a/xui_lib/src/main/res/drawable-hdpi/xui_icon_checkbox_normal.png b/xui_lib/src/main/res/drawable-v17/xui_icon_checkbox_normal.png
similarity index 100%
rename from xui_lib/src/main/res/drawable-hdpi/xui_icon_checkbox_normal.png
rename to xui_lib/src/main/res/drawable-v17/xui_icon_checkbox_normal.png
diff --git a/xui_lib/src/main/res/drawable-v21/xui_icon_checkbox.xml b/xui_lib/src/main/res/drawable-v21/xui_icon_checkbox.xml
new file mode 100644
index 00000000..2dbb87df
--- /dev/null
+++ b/xui_lib/src/main/res/drawable-v21/xui_icon_checkbox.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xui_lib/src/main/res/drawable-v21/xui_icon_checkbox_checked.xml b/xui_lib/src/main/res/drawable-v21/xui_icon_checkbox_checked.xml
new file mode 100644
index 00000000..414e0a8d
--- /dev/null
+++ b/xui_lib/src/main/res/drawable-v21/xui_icon_checkbox_checked.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/xui_lib/src/main/res/drawable-v21/xui_icon_checkbox_normal.xml b/xui_lib/src/main/res/drawable-v21/xui_icon_checkbox_normal.xml
new file mode 100644
index 00000000..ac01f1f4
--- /dev/null
+++ b/xui_lib/src/main/res/drawable-v21/xui_icon_checkbox_normal.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/xui_lib/src/main/res/drawable/xui_icon_checkbox_checked.xml b/xui_lib/src/main/res/drawable/xui_icon_checkbox_checked.xml
new file mode 100644
index 00000000..414e0a8d
--- /dev/null
+++ b/xui_lib/src/main/res/drawable/xui_icon_checkbox_checked.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/xui_lib/src/main/res/drawable/xui_icon_checkbox_normal.xml b/xui_lib/src/main/res/drawable/xui_icon_checkbox_normal.xml
new file mode 100644
index 00000000..ac01f1f4
--- /dev/null
+++ b/xui_lib/src/main/res/drawable/xui_icon_checkbox_normal.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/xui_lib/src/main/res/values/xui_attrs.xml b/xui_lib/src/main/res/values/xui_attrs.xml
index 1dd5f83d..78c64f95 100755
--- a/xui_lib/src/main/res/values/xui_attrs.xml
+++ b/xui_lib/src/main/res/values/xui_attrs.xml
@@ -1286,8 +1286,12 @@
+
+
+
+
diff --git a/xui_lib/src/main/res/values/xui_styles_common.xml b/xui_lib/src/main/res/values/xui_styles_common.xml
index 48679a79..adcf7c94 100755
--- a/xui_lib/src/main/res/values/xui_styles_common.xml
+++ b/xui_lib/src/main/res/values/xui_styles_common.xml
@@ -270,6 +270,67 @@
- 0
+
+
+
+
+
+
+
+
+
diff --git a/xui_lib/src/main/res/values/xui_themes.xml b/xui_lib/src/main/res/values/xui_themes.xml
index 6123e390..b87820a0 100755
--- a/xui_lib/src/main/res/values/xui_themes.xml
+++ b/xui_lib/src/main/res/values/xui_themes.xml
@@ -53,6 +53,10 @@
- @color/xui_btn_blue_normal_color
- @color/xui_btn_blue_select_color
+ - @color/xui_config_color_title_text
+ - @color/xui_config_color_content_text
+ - @color/xui_config_color_explain_text
+
- true
- false
@@ -77,9 +81,6 @@
- @style/AppTheme.Widget.TextView
- @style/TextField
- - @color/xui_config_color_title_text
- - @color/xui_config_color_content_text
- - @color/xui_config_color_explain_text
- @color/xui_config_color_primary_text
@@ -95,15 +96,14 @@
- @style/EditText
- @style/EditText
-
- - 0.6
-
- @style/GridView
-
- @drawable/xui_config_selectable_item_selector
- @drawable/xui_config_list_divider
+
+ - 0.6
+