Commit 0897b40c by 霍志良

Merge remote-tracking branch 'origin/release' into feat/diamond_category_zl

# Conflicts:
#	config.gradle
#	m-consultant/src/main/java/com/yidianling/consultant/ExpertSearchFragment.kt
parents a82638ea f2f0882b
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply from: "../../maven_push_api.gradle" apply from: "../../publish.gradle"
version = '1.0.4'
android { android {
compileSdkVersion rootProject.ext.android["compileSdkVersion"] compileSdkVersion rootProject.ext.android["compileSdkVersion"]
......
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply from: "../../maven_push_api.gradle" apply from: "../../publish.gradle"
version = '1.0.3'
android { android {
compileSdkVersion rootProject.ext.android["compileSdkVersion"] compileSdkVersion rootProject.ext.android["compileSdkVersion"]
......
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply from: "../../maven_push_api.gradle" apply from: "../../publish.gradle"
version = '1.0.0'
android { android {
compileSdkVersion rootProject.ext.android["compileSdkVersion"] compileSdkVersion rootProject.ext.android["compileSdkVersion"]
......
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply from: "../../maven_push_api.gradle" apply from: "../../publish.gradle"
version = '1.0.0'
android { android {
compileSdkVersion rootProject.ext.android["compileSdkVersion"] compileSdkVersion rootProject.ext.android["compileSdkVersion"]
......
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply from: "../../maven_push_api.gradle" apply from: "../../publish.gradle"
version = '1.0.0'
android { android {
compileSdkVersion rootProject.ext.android["compileSdkVersion"] compileSdkVersion rootProject.ext.android["compileSdkVersion"]
......
/build
\ No newline at end of file
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply from: "../../publish.gradle"
android {
compileSdkVersion rootProject.ext.android["compileSdkVersion"]
buildToolsVersion rootProject.ext.android["buildToolsVersion"]
defaultConfig {
minSdkVersion rootProject.ext.android["minSdkVersion"]
targetSdkVersion rootProject.ext.android["targetSdkVersion"]
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation "com.alibaba:arouter-api:$arouter_api"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.ydl.home.api">
</manifest>
\ No newline at end of file
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply from: "../../maven_push_api.gradle" apply from: "../../publish.gradle"
version = '1.0.2'
android { android {
compileSdkVersion rootProject.ext.android["compileSdkVersion"] compileSdkVersion rootProject.ext.android["compileSdkVersion"]
......
...@@ -23,6 +23,7 @@ interface IImService : IProvider { ...@@ -23,6 +23,7 @@ interface IImService : IProvider {
// 直接打开聊天页面,不走分配导医 // 直接打开聊天页面,不走分配导医
fun startChatBySessionId(context: Activity, toUid: String) fun startChatBySessionId(context: Activity, toUid: String)
// 打开信息前置收集页 // 打开信息前置收集页
fun startP2PSession(context: Activity, location: Int, ffrom2: String?) fun startP2PSession(context: Activity, location: Int, ffrom2: String?)
...@@ -183,4 +184,8 @@ interface IImService : IProvider { ...@@ -183,4 +184,8 @@ interface IImService : IProvider {
fun initIm(app: Application, activity: Class<out Activity>, imInitBean: IMInitConfigBean) fun initIm(app: Application, activity: Class<out Activity>, imInitBean: IMInitConfigBean)
fun isWifiOr3G(activity: Activity): Boolean fun isWifiOr3G(activity: Activity): Boolean
fun showConsultServiceDialog(activity: Activity, toUid: String, doctorId: String)
fun dismissConsultServiceDialog();
} }
\ No newline at end of file
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply from: "../../maven_push_api.gradle" apply from: "../../publish.gradle"
version = '1.0.0'
android { android {
compileSdkVersion rootProject.ext.android["compileSdkVersion"] compileSdkVersion rootProject.ext.android["compileSdkVersion"]
......
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply from: "../../maven_push_api.gradle" apply from: "../../publish.gradle"
version = '1.0.0'
android { android {
compileSdkVersion rootProject.ext.android["compileSdkVersion"] compileSdkVersion rootProject.ext.android["compileSdkVersion"]
......
...@@ -116,6 +116,8 @@ interface IUserService : IProvider { ...@@ -116,6 +116,8 @@ interface IUserService : IProvider {
* */ * */
fun loginByOneKeyLogin(context: Context, isOpenDialog: Boolean) :Boolean fun loginByOneKeyLogin(context: Context, isOpenDialog: Boolean) :Boolean
fun checkOneLoginEnvAvailable(): Boolean
/** /**
* 调用优先使用一键登录,并返回调用时的登录状态, * 调用优先使用一键登录,并返回调用时的登录状态,
* @param isOpenDialog true:一键登录使用弹窗展示 false:一键登录使用全屏模式 * @param isOpenDialog true:一键登录使用弹窗展示 false:一键登录使用全屏模式
......
...@@ -31,7 +31,6 @@ android { ...@@ -31,7 +31,6 @@ android {
flavorDimensions "versionCode" flavorDimensions "versionCode"
javaCompileOptions { javaCompileOptions {
annotationProcessorOptions { annotationProcessorOptions {
includeCompileClasspath true
arguments = [AROUTER_MODULE_NAME: project.getName(), AROUTER_GENERATE_DOC: "enable"] arguments = [AROUTER_MODULE_NAME: project.getName(), AROUTER_GENERATE_DOC: "enable"]
} }
} }
...@@ -178,6 +177,7 @@ android { ...@@ -178,6 +177,7 @@ android {
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.github.feeeei:CircleSeekbar:v1.1.2'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation(rootProject.ext.dependencies["appcompat-v7"]) implementation(rootProject.ext.dependencies["appcompat-v7"])
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
......
...@@ -23,6 +23,8 @@ import com.ydl.ydlcommon.utils.AppProgressUtils; ...@@ -23,6 +23,8 @@ import com.ydl.ydlcommon.utils.AppProgressUtils;
import com.ydl.ydlcommon.utils.Utils; import com.ydl.ydlcommon.utils.Utils;
import com.yidianling.common.tools.LogUtil; import com.yidianling.common.tools.LogUtil;
import com.yidianling.common.tools.ToastUtil; import com.yidianling.common.tools.ToastUtil;
import com.yidianling.consultant.preview.TestImageLoader;
import com.yidianling.consultant.preview.ZoomMediaLoader;
import com.yidianling.course.lifeCallback.CoursePlayLifecycle; import com.yidianling.course.lifeCallback.CoursePlayLifecycle;
...@@ -48,7 +50,7 @@ public class ComponentTestApp extends BaseApp { ...@@ -48,7 +50,7 @@ public class ComponentTestApp extends BaseApp {
com.ydl.ydlcommon.utils.LogUtil.debug = BuildConfig.DEBUG; com.ydl.ydlcommon.utils.LogUtil.debug = BuildConfig.DEBUG;
webviewSetPath(this); webviewSetPath(this);
ZoomMediaLoader.getInstance().init(new TestImageLoader());
if (!BuildConfig.DEBUG && Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {//release包去除,debug包不去除,用于检测是否还有反射api的方法 if (!BuildConfig.DEBUG && Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {//release包去除,debug包不去除,用于检测是否还有反射api的方法
//去掉在Android P上的提醒弹窗 Detected problems with API //去掉在Android P上的提醒弹窗 Detected problems with API
......
...@@ -20,7 +20,6 @@ import com.umeng.socialize.UMShareAPI ...@@ -20,7 +20,6 @@ import com.umeng.socialize.UMShareAPI
import com.ydl.component.BuildConfig import com.ydl.component.BuildConfig
import com.ydl.component.MainActivity import com.ydl.component.MainActivity
import com.ydl.component.R import com.ydl.component.R
import com.ydl.media.audio.PlayService
import com.ydl.ydlcommon.actions.crash.Cockroach import com.ydl.ydlcommon.actions.crash.Cockroach
import com.ydl.ydlcommon.actions.crash.ExceptionHandler import com.ydl.ydlcommon.actions.crash.ExceptionHandler
import com.ydl.ydlcommon.base.config.HttpConfig import com.ydl.ydlcommon.base.config.HttpConfig
...@@ -78,15 +77,6 @@ class DemoAppLifecycles : IAppLifecycles { ...@@ -78,15 +77,6 @@ class DemoAppLifecycles : IAppLifecycles {
// YDLCommonPlugin plugin = new YDLCommonPlugin(); // YDLCommonPlugin plugin = new YDLCommonPlugin();
// flutterEngine.getLocalizationChannel().channel.setMethodCallHandler(plugin); // flutterEngine.getLocalizationChannel().channel.setMethodCallHandler(plugin);
val intent = Intent(application, PlayService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
application.startForegroundService(intent)
}else{
application.startService(intent)
}
// application.registerActivityLifecycleCallbacks(new CoursePlayLifecycle());
} }
} }
......
...@@ -110,7 +110,7 @@ class JsMethod(private val webView: WebView?) { ...@@ -110,7 +110,7 @@ class JsMethod(private val webView: WebView?) {
if (callback.isNullOrBlank()) return true if (callback.isNullOrBlank()) return true
webView?.post { webView?.post {
when (type) { when (type) {
1 -> {//检查音频权限能力 1,2 -> {//检查音频权限能力
webView.loadUrl("javascript:$callback(1)") webView.loadUrl("javascript:$callback(1)")
} }
else -> { else -> {
......
package com.ydl.component.service.web; package com.ydl.component.service.web;
import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.graphics.Rect;
import com.alibaba.android.arouter.launcher.ARouter; import com.alibaba.android.arouter.launcher.ARouter;
import com.blankj.utilcode.util.ScreenUtils;
import com.ydl.confide.api.IConfideService; import com.ydl.confide.api.IConfideService;
import com.ydl.confide.home.event.ChangeAnotherExpertEvent; import com.ydl.confide.home.event.ChangeAnotherExpertEvent;
import com.ydl.webview.H5JsBean; import com.ydl.webview.H5JsBean;
import com.ydl.webview.H5Params; import com.ydl.webview.H5Params;
import com.ydl.webview.NewH5Activity; import com.ydl.webview.NewH5Activity;
import com.ydl.ydl_router.manager.YDLRouterManager;
import com.ydl.ydl_router.manager.YDLRouterParams;
import com.ydl.ydlcommon.modular.ModularServiceManager; import com.ydl.ydlcommon.modular.ModularServiceManager;
import com.yidianling.common.tools.LogUtil; import com.yidianling.common.tools.LogUtil;
import com.yidianling.consultant.preview.GPreviewBuilder;
import com.yidianling.consultant.preview.UserViewInfo;
import com.yidianling.im.api.service.IImService; import com.yidianling.im.api.service.IImService;
import com.yidianling.im.event.CloseBottomWebviewEvent;
import com.yidianling.muse.activity.ChooseMusicActivity; import com.yidianling.muse.activity.ChooseMusicActivity;
//import static com.ydl.ydlcommon.router.IYDLRouterConstant.ROUTER_MUSE_PLAY; import java.util.ArrayList;
import java.util.List;
import de.greenrobot.event.EventBus;
import com.yidianling.im.event.CloseBottomWebviewEvent;
import de.greenrobot.event.EventBus; import de.greenrobot.event.EventBus;
...@@ -56,7 +58,11 @@ public class WVClickAbstractListener implements WebViewClientClickListener { ...@@ -56,7 +58,11 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
@Override @Override
public void contactYi() { public void contactYi() {
try {
ModularServiceManager.INSTANCE.provide(IImService.class)
.startP2PSession(mContext, -1, "14", "14", "客服小壹", "14");
} catch (Exception e) {
}
} }
@Override @Override
...@@ -106,7 +112,17 @@ public class WVClickAbstractListener implements WebViewClientClickListener { ...@@ -106,7 +112,17 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
@Override @Override
public void chat(int id, int toUid, int canTalk, String accessToken, int isFromQingShu) { public void chat(int id, int toUid, int canTalk, String accessToken, int isFromQingShu) {
if ((toUid + "").equals("14")) {
//找客服私聊不需要积分
contactYi();
} else {
try {
ModularServiceManager.INSTANCE.provide(IImService.class)
.startChatCloseReplaceChat(mContext, String.valueOf(toUid));
} catch (Exception e) {
e.printStackTrace();
}
}
} }
@Override @Override
...@@ -296,7 +312,9 @@ public class WVClickAbstractListener implements WebViewClientClickListener { ...@@ -296,7 +312,9 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
@Override @Override
public void shareAction(H5JsBean.H5JsCmd.Params params) { public void shareAction(H5JsBean.H5JsCmd.Params params) {
if (mContext instanceof NewH5Activity) {
((NewH5Activity) mContext).showShareMenu(params);
}
} }
@Override @Override
...@@ -384,7 +402,7 @@ public class WVClickAbstractListener implements WebViewClientClickListener { ...@@ -384,7 +402,7 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
@Override @Override
public void back() { public void back() {
mContext.finish();
} }
@Override @Override
...@@ -495,6 +513,39 @@ public class WVClickAbstractListener implements WebViewClientClickListener { ...@@ -495,6 +513,39 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
} }
@Override @Override
public void resourceToPreview(H5JsBean.H5JsCmd.Params params) {
List<H5JsBean.MediaInfo> dataList = params.getDataList();
H5JsBean.DoctorInfo info = params.getInfo();
List<UserViewInfo> mThumbViewInfoList = new ArrayList<>();
for (H5JsBean.MediaInfo mediaInfo : dataList) {
UserViewInfo userViewInfo = new UserViewInfo(mediaInfo.getCover(), mediaInfo.getUrl(), mediaInfo.getSourcesType());
Rect bounds = new Rect();
bounds.left = ScreenUtils.getScreenWidth() / 2;
bounds.top = ScreenUtils.getScreenHeight() / 2;
bounds.right = ScreenUtils.getScreenWidth() / 2;
bounds.bottom = ScreenUtils.getScreenHeight() / 2;
userViewInfo.setBounds(bounds);
mThumbViewInfoList.add(userViewInfo);
}
GPreviewBuilder.form(mContext)
.setData(mThumbViewInfoList)
.setCurrentIndex(params.getPreview_index())
.setFullscreen(true)
.setToUid(info.getToUid() + "")
.setDoctorId(info.getDoctorId())
.setType(GPreviewBuilder.IndicatorType.Dot)
.start();
}
@Override
public void showDocBooking(H5JsBean.H5JsCmd.Params params) {
ModularServiceManager.INSTANCE.provide(IImService.class).showConsultServiceDialog(mContext, params.getToUid() + "", params.getDoctorId() + "");
}
@Override
public void switchSound(int mediaId, long meditationId, int meditationType, int businessType, public void switchSound(int mediaId, long meditationId, int meditationType, int businessType,
String buried, String mediaUrl, String mediaCoverUrl, String buried, String mediaUrl, String mediaCoverUrl,
String title, String desc, int status) { String title, String desc, int status) {
...@@ -506,9 +557,11 @@ public class WVClickAbstractListener implements WebViewClientClickListener { ...@@ -506,9 +557,11 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
businessType, buried, mediaUrl, mediaCoverUrl, title, desc, status); businessType, buried, mediaUrl, mediaCoverUrl, title, desc, status);
} }
} }
@Override @Override
public void chatCloseBottomWebView() { public void chatCloseBottomWebView() {
EventBus.getDefault().post(new CloseBottomWebviewEvent(true)); EventBus.getDefault().post(new CloseBottomWebviewEvent(true));
ModularServiceManager.INSTANCE.provide(IImService.class).dismissConsultServiceDialog();
} }
...@@ -521,8 +574,26 @@ public class WVClickAbstractListener implements WebViewClientClickListener { ...@@ -521,8 +574,26 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
@Override @Override
public void setWebViewBG(String rgb, String alpha) { public void setWebViewBG(String rgb, String alpha) {
if (mContext instanceof NewH5Activity) {
((NewH5Activity) mContext).setBG(rgb, alpha);
}
}
/**
* 打开时间选择器
*/
@SuppressLint("CheckResult")
@Override
public void openTimePicker(String jsCallBackName, String day, String doctorId, String orderId) {
}
@Override
public void showCommentArticleDialog(H5JsBean.H5JsCmd.Params params) {
if (mContext instanceof NewH5Activity){ if (mContext instanceof NewH5Activity){
((NewH5Activity)mContext).setBG(rgb, alpha); ((NewH5Activity)mContext).showCommentArticleDialog(params.getTitle());
} }
} }
} }
...@@ -14,6 +14,7 @@ import com.ydl.ydlcommon.base.BaseActivityMgr ...@@ -14,6 +14,7 @@ import com.ydl.ydlcommon.base.BaseActivityMgr
import com.ydl.ydlcommon.base.config.HttpConfig import com.ydl.ydlcommon.base.config.HttpConfig
import com.ydl.ydlcommon.modular.ModularServiceManager import com.ydl.ydlcommon.modular.ModularServiceManager
import com.ydl.ydlcommon.modular.findRouteService import com.ydl.ydlcommon.modular.findRouteService
import com.ydl.ydlcommon.utils.Utils
import com.ydl.ydlcommon.utils.log.LogHelper import com.ydl.ydlcommon.utils.log.LogHelper
import com.yidianling.common.tools.LogUtil import com.yidianling.common.tools.LogUtil
import com.yidianling.user.UserHelper import com.yidianling.user.UserHelper
...@@ -459,6 +460,27 @@ class WebJavascriptHandler(private val webView: WebView?, private val wvEnventPr ...@@ -459,6 +460,27 @@ class WebJavascriptHandler(private val webView: WebView?, private val wvEnventPr
"switch_push_status" -> { "switch_push_status" -> {
wvEnventPro?.switchPushStatus(jsData.cmd?.params) wvEnventPro?.switchPushStatus(jsData.cmd?.params)
} }
// 打开时间选择器
"requestSelectTime"->{
if (Utils.isFastClick()){
return
}
wvEnventPro?.openTimePicker(jsData.cmd?.params?.callBack,jsData.cmd?.params?.day,jsData.cmd?.params?.doctorId.toString(),jsData.cmd?.params?.orderId)
}
"open_article_comment_dialog" -> {
wvEnventPro?.showCommentArticleDialog(jsData.cmd?.params)
}
"resources_to_preview" -> {
wvEnventPro?.resourceToPreview(jsData.cmd?.params)
}
"doctor_booking" -> {
wvEnventPro?.showDocBooking(jsData.cmd?.params)
}
} }
} }
......
...@@ -203,4 +203,16 @@ public interface WebViewClientClickListener { ...@@ -203,4 +203,16 @@ public interface WebViewClientClickListener {
//h5页面是否需要打开推送 //h5页面是否需要打开推送
void switchPushStatus(H5JsBean.H5JsCmd.Params params); void switchPushStatus(H5JsBean.H5JsCmd.Params params);
//显示评论弹窗
void showCommentArticleDialog(H5JsBean.H5JsCmd.Params params);
void resourceToPreview(H5JsBean.H5JsCmd.Params params);
void showDocBooking(H5JsBean.H5JsCmd.Params params);
// 打开时间选择器
void openTimePicker(String jsCallBackName,String day,String doctorId,String orderId);
} }
...@@ -3,7 +3,7 @@ apply from: "config.gradle" ...@@ -3,7 +3,7 @@ apply from: "config.gradle"
buildscript { buildscript {
ext { ext {
kotlin_version = '1.3.50' kotlin_version = '1.6.10'
support_version = '26.1.0' support_version = '26.1.0'
minSdkVersion = 21 minSdkVersion = 21
targetSdkVersion = 28 targetSdkVersion = 28
...@@ -13,42 +13,45 @@ buildscript { ...@@ -13,42 +13,45 @@ buildscript {
arouter_compiler = '1.2.2' arouter_compiler = '1.2.2'
ydlrouter_version = '1.2.3' ydlrouter_version = '1.2.3'
constrait_support_version = '1.0.2' constrait_support_version = '1.0.2'
componentVersion = "0.3.0.12-SNAPSHOT"
} }
repositories { repositories {
maven {
url 'http://nexus.yidianling.com/repository/android/'
credentials {
username "admin"
password "fjoi#1+#@"
}
}
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
mavenCentral() mavenCentral()
google() google()
mavenLocal() mavenLocal()
// maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.2.0' classpath 'com.android.tools.build:gradle:7.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.ydl.plugins:modular:1.0.3'
classpath 'com.ydl:notracepoint-gradle-plugin:0.0.3'
} }
} }
allprojects { p ->
allprojects { if (p.path.startsWith(":ydl-")) {
p.version = componentVersion
}
if (p.path.startsWith(":m-")) {
p.version = componentVersion
}
if (p.path.startsWith(":api:")) {
p.version = componentVersion
}
repositories { repositories {
//壹点灵android maven私服 开发版
maven { maven {
url 'http://nexus.yidianling.com/repository/android/' url 'http://nexus.yidianling.com/repository/android/'
allowInsecureProtocol true
credentials { credentials {
username "admin" username "admin"
password "fjoi#1+#@" password "fjoi#1+#@"
} }
} }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
mavenCentral() mavenCentral()
google() google()
maven {
url 'http://maven.aliyun.com/nexus/content/groups/public/'
allowInsecureProtocol true
}
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
mavenLocal() mavenLocal()
} }
} }
...@@ -56,26 +59,6 @@ allprojects { ...@@ -56,26 +59,6 @@ allprojects {
task clean(type: Delete) { task clean(type: Delete) {
delete rootProject.buildDir delete rootProject.buildDir
} }
task packYdl1 {
doLast {
println("doLast packYdl1!!!!")
}
}
task packYdl2 {
doLast {
println("doLast packYdl2!!!!")
}
}
task packYdl {
doLast {
println("doLast packYdl!!!!")
}
}
task packM{
doLast {
println("doLast packM!!!!")
}
}
subprojects { subprojects {
project.configurations.all { project.configurations.all {
...@@ -88,27 +71,3 @@ subprojects { ...@@ -88,27 +71,3 @@ subprojects {
} }
} }
} }
apply plugin: 'modular-plugin'
modular {
compileSdkVersion 28
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
repositories {
maven {
url 'http://nexus.yidianling.com/repository/AndroidReleases/'
credentials {
username "admin"
password "fjoi#1+#@"
}
}
}
}
ext { ext {
dev_mode = true //组件发布的时候需要设置为false
ydl2PublishVersion = "0.2.0.8"
ydlPublishVersion = [
// -------------- 业务模块 --------------
//第三步 若干
"m-confide" : "0.0.50.50",
"m-consultant" : "0.0.60.78",
"m-fm" : "0.0.30.09",
"m-user" : "0.0.62.72",
"m-home" : "0.0.24.06",
"m-im" : "0.0.21.69",
"m-dynamic" : "0.0.7.80",
"m-article" : "0.0.0.10",
"m-muse" : "0.0.28.87",
"m-tests" : "0.0.24.24",
"m-course" : "0.0.43.39",
//-------------- 功能组件 --------------
//mdt 组件
"ydl-tuicore" : "0.0.25",
//第一步
"ydl-platform" : "0.0.41.54",
//第二步 若干
"ydl-webview" : "0.0.39.03",
"ydl-media" : "0.0.21.52",
"ydl-pay" : "0.0.18.21",
"m-audioim" : "0.0.49.30.23",
"ydl-flutter-base": "0.0.14.44",
//以下 几乎不会动
"router" : "0.0.1",
"ydl-net" : "0.0.3.94",
"ydl-utils" : "0.0.3.12",
//-------------- 业务模块 API 层 --------------
"m-home-api" : "0.0.4.4",
]
ydl_app = [ ydl_app = [
appName : "壹点灵心理咨询", appName : "壹点灵心理咨询",
applicationId: "com.cxzapp.yidianling", applicationId: "com.cxzapp.yidianling",
...@@ -74,7 +38,7 @@ ext { ...@@ -74,7 +38,7 @@ ext {
dependencies = [ dependencies = [
//support //support
"appcompat-v7" : 'androidx.appcompat:appcompat:1.2.0', "appcompat-v7" : 'androidx.appcompat:appcompat:1.2.0',
"design" : 'com.google.android.material:material:1.4.0', "design" : 'com.google.android.material:material:1.3.0',
"support-v4" : 'androidx.legacy:legacy-support-v4:1.0.0', "support-v4" : 'androidx.legacy:legacy-support-v4:1.0.0',
"cardview-v7" : 'androidx.cardview:cardview:1.0.0', "cardview-v7" : 'androidx.cardview:cardview:1.0.0',
"annotations" : "androidx.annotation:annotation:1.0.0", "annotations" : "androidx.annotation:annotation:1.0.0",
...@@ -134,12 +98,6 @@ ext { ...@@ -134,12 +98,6 @@ ext {
"xxpermission" : "com.hjq:xxpermissions:10.2", "xxpermission" : "com.hjq:xxpermissions:10.2",
"rxerrorhandler2" : "me.jessyan:rxerrorhandler:2.1.1", "rxerrorhandler2" : "me.jessyan:rxerrorhandler:2.1.1",
//tools
// "dagger2" : "com.google.dagger:dagger:${version["dagger2SdkVersion"]}",
// "dagger2-android" : "com.google.dagger:dagger-android:${version["dagger2SdkVersion"]}",
// "dagger2-android-support" : "com.google.dagger:dagger-android-support:${version["dagger2SdkVersion"]}",
// "dagger2-compiler" : "com.google.dagger:dagger-compiler:${version["dagger2SdkVersion"]}",
// "dagger2-android-processor" : "com.google.dagger:dagger-android-processor:${version["dagger2SdkVersion"]}",
"androideventbus" : "org.simple:androideventbus:1.0.5.1", "androideventbus" : "org.simple:androideventbus:1.0.5.1",
"otto" : "com.squareup:otto:1.3.8", "otto" : "com.squareup:otto:1.3.8",
"gson" : "com.google.code.gson:gson:2.8.5", "gson" : "com.google.code.gson:gson:2.8.5",
...@@ -208,33 +166,9 @@ ext { ...@@ -208,33 +166,9 @@ ext {
"ydl-hnet" : "com.ydl:h-net:0.0.8", "ydl-hnet" : "com.ydl:h-net:0.0.8",
"ydl-user-router" : "com.ydl:router:1.0.0-SNAPSHOT@aar", "ydl-user-router" : "com.ydl:router:1.0.0-SNAPSHOT@aar",
"ydl-device" : "com.ydl:device-id:0.0.31", "ydl-device" : "com.ydl:device-id:0.0.31",
"ydl-net" : "com.ydl:ydl-net:${ydl2PublishVersion}",
"ydl-utils" : "com.ydl:ydl-utils:${ydl2PublishVersion}",
//flutter功能组件升级===>发布ydl-flutter组件===>引用flutter相关的业务模块 //flutter功能组件升级===>发布ydl-flutter组件===>引用flutter相关的业务模块
"ydl-flutter-base" : "com.ydl:ydl-flutter-base:${ydl2PublishVersion}", //组件化项目中的flutter base模块
"ydl-flutter" : "com.ydl:ydl-flutter:0.0.51@aar", //flutter aar "ydl-flutter" : "com.ydl:ydl-flutter:0.0.51@aar", //flutter aar
// "ydl-flutter-sp" : "com.ydl:ydl-flutter-sp:0.0.2@aar", //flutter 缓存 aar // "ydl-flutter-sp" : "com.ydl:ydl-flutter-sp:0.0.2@aar", //flutter 缓存 aar
//基础组件 <<--- 先发这个,发完改这里的版本号
"ydl-platform" : "com.ydl:ydl-platform:${ydl2PublishVersion}",
"ydl-tuicore" : "com.ydl:ydl-tuicore:${ydlPublishVersion["ydl-tuicore"]}",
//功能组件 <<--- 再发这些,发完改这里的版本号
"ydl-webview" : "com.ydl:ydl-webview:${ydl2PublishVersion}",
"ydl-media" : "com.ydl:ydl-media:${ydl2PublishVersion}",
"ydl-pay" : "com.ydl:ydl-pay:${ydl2PublishVersion}",
"m-audioim" : "com.ydl:m-audioim:${ydl2PublishVersion}",
//业务组件 <<--- 最后发这些(只发改过的)
"ydl-m-user-api" : "com.ydl:m-user-api:1.0.0",
"ydl-m-fm-api" : "com.ydl:m-fm-api:1.0.0",
"ydl-m-tests-api" : "com.ydl:m-tests-api:1.0.0",
"ydl-m-im-api" : "com.ydl:m-im-api:1.0.2",
"ydl-m-home-api" : "com.ydl:m-home-api:${ydlPublishVersion["m-home-api"]}",
"ydl-m-consultant-api" : "com.ydl:m-consultant-api:1.0.3",
"ydl-m-dynamic-api" : "com.ydl:m-dynamic-api:1.0.0",
"ydl-m-confide-api" : "com.ydl:m-confide-api:1.0.4",
"ydl-m-course-api" : "com.ydl:m-course-api:1.0.0",
] ]
} }
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
...@@ -2,7 +2,7 @@ apply plugin: 'com.android.library' ...@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply from : '../maven_push.gradle' apply from: "../publish.gradle"
kapt { kapt {
arguments { arguments {
...@@ -44,7 +44,7 @@ android { ...@@ -44,7 +44,7 @@ android {
} }
dependencies { dependencies {
api fileTree(dir: 'libs', include: ['*.aar','*.jar']) api fileTree(dir: 'libs', include: ['*.aar', '*.jar'])
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.ext:junit:1.1.2'
...@@ -52,18 +52,14 @@ dependencies { ...@@ -52,18 +52,14 @@ dependencies {
kapt 'com.alibaba:arouter-compiler:1.2.2' kapt 'com.alibaba:arouter-compiler:1.2.2'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
implementation "androidx.lifecycle:lifecycle-runtime:2.0.0"
implementation 'io.github.scwang90:refresh-layout-kernel:2.0.5' //核心必须依赖
implementation 'io.github.scwang90:refresh-header-classics:2.0.5' //经典刷新头
api rootProject.ext.dependencies["ydl-user-router"] api rootProject.ext.dependencies["ydl-user-router"]
if (rootProject.ext.dev_mode){
//开发时使用
api project(':ydl-webview') api project(':ydl-webview')
api project(':ydl-platform') api project(':ydl-platform')
implementation project(':ydl-flutter-base') implementation project(':ydl-flutter-base')
}else {
//发布时使用
api rootProject.ext.dependencies["ydl-webview"]
api(rootProject.ext.dependencies["ydl-platform"]) {
transitive = true
}
implementation rootProject.ext.dependencies["ydl-flutter-base"]
}
} }
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
<application> <application>
<activity android:name=".flutter.ArticleActivity" <activity android:name=".flutter.ArticleActivity"
android:screenOrientation="portrait"/> android:screenOrientation="portrait"/>
<activity android:name="activity.ArticleHomeActivity"
android:screenOrientation="portrait"/>
</application> </application>
</manifest> </manifest>
\ No newline at end of file
package activity
import adapter.ArticlePagerAdapter
import android.annotation.SuppressLint
import android.graphics.Typeface
import android.text.SpannableString
import android.text.Spanned
import android.text.style.StyleSpan
import android.widget.ImageView
import androidx.viewpager2.widget.ViewPager2
import com.alibaba.android.arouter.facade.annotation.Route
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.ydl.ydlcommon.base.BaseActivity
import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils
import com.yidianling.article.R
import fragment.ArticleHomeFragment
import http.ArticleHttp
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
@Route(path = "/article/list")
class ArticleHomeActivity : BaseActivity() {
private var TAG_IDS = mutableListOf(0)
private var mTabName = mutableListOf("推荐")
private var mTabLayout: TabLayout? = null
private var mViewPager: ViewPager2? = null
private var mFragments = mutableListOf(ArticleHomeFragment.newInstance(0))
override fun layoutResId(): Int {
return R.layout.article_home_activity_layout
}
override fun initDataAndEvent() {
mTabLayout = findViewById(R.id.tab_layout)
mViewPager = findViewById(R.id.view_pager)
mViewPager?.offscreenPageLimit = 3
findViewById<ImageView>(R.id.iv_back).setOnClickListener {
ActionCountUtils.record("article_list_main_page","article_list_return_click")
finish()
}
loadData()
}
@SuppressLint("CheckResult")
private fun loadData() {
ArticleHttp.getInstance().getArticleCategoryList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { response ->
if (response.code == "200" && response.data != null && !response.data.articleCategoryResponseList.isNullOrEmpty()) {
var tabNameString = StringBuffer("推荐")
response.data.articleCategoryResponseList!!.forEach {
mTabName.add(it.name)
TAG_IDS.add(it.categoryId)
mFragments.add(ArticleHomeFragment.newInstance(it.categoryId))
tabNameString.append("|${it.name}")
}
ActionCountUtils.record(
"article_list_main_page",
"article_list_sort_visit",
tabNameString.toString()
)
mViewPager?.post {
mViewPager?.adapter = ArticlePagerAdapter(this, mFragments)
mTabLayout?.addOnTabSelectedListener(object :
TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
ActionCountUtils.record(
"article_list_main_page",
"article_list_toptitle_click",
tab?.text.toString() ?: ""
)
var text: String? = tab?.text.toString().trim()
val spStr = SpannableString(text)
val styleSpan = StyleSpan(Typeface.BOLD)
spStr.setSpan(
styleSpan,
0,
text?.length ?: 0,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE
)
tab?.text = spStr
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
var text: String? = tab?.text.toString().trim()
val spStr = SpannableString(text)
val styleSpan = StyleSpan(Typeface.NORMAL)
spStr.setSpan(
styleSpan,
0,
text?.length ?: 0,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE
)
tab?.text = spStr
}
override fun onTabReselected(tab: TabLayout.Tab?) {
}
})
TabLayoutMediator(mTabLayout!!, mViewPager!!) { tab, position ->
tab.text = mTabName[position]
}.attach()
}
}
}
}
}
\ No newline at end of file
package adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.AppCompatImageView
import androidx.appcompat.widget.AppCompatTextView
import androidx.recyclerview.widget.RecyclerView
import com.ydl.ydl_image.manager.YDLImageCacheManager
import com.yidianling.article.R
import data.ArticleBean
class ArticleHomeItemAdapter(private val mContext:Context):RecyclerView.Adapter<ArticleHomeItemAdapter.ArticleViewHolder>() {
private var mData = mutableListOf<ArticleBean>()
private var mListener:OnItemClickListener?=null
fun setOnItemClickListener(listener: OnItemClickListener){
mListener = listener
}
fun setData(data:MutableList<ArticleBean>){
mData.clear()
mData.addAll(data)
notifyDataSetChanged()
}
fun addData(data:MutableList<ArticleBean>){
mData.addAll(data)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, position: Int): ArticleViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.article_home_item_layout,parent,false)
return ArticleViewHolder(view)
}
override fun onBindViewHolder(holder: ArticleViewHolder, position: Int) {
holder.tvTitle.text = mData[position].title
holder.tvDesc.text = mData[position].desc
holder.tvAuthorName.text = mData[position].name
holder.tvArticleViewNum.text = "${mData[position].readNum}浏览"
holder.tvArticleLikeNum.text = "${mData[position].zanNum}点赞"
YDLImageCacheManager.showImage(mContext, mData[position]?.imgUrl, holder.ivArticleImage)
YDLImageCacheManager.showImage(mContext, mData[position]?.smallImage, holder.ivAuthorAvatar)
holder.itemView.setOnClickListener {
mListener?.onItemClick(mData[position])
}
}
override fun getItemCount(): Int {
return mData.size
}
inner class ArticleViewHolder(itemView:View):RecyclerView.ViewHolder(itemView){
var tvTitle:AppCompatTextView = itemView.findViewById(R.id.tv_article_title)
var tvDesc:AppCompatTextView = itemView.findViewById(R.id.tv_article_desc)
var ivArticleImage:AppCompatImageView = itemView.findViewById(R.id.iv_article_image)
var ivAuthorAvatar:AppCompatImageView = itemView.findViewById(R.id.iv_author_avatar)
var tvAuthorName:AppCompatTextView = itemView.findViewById(R.id.tv_author_name)
var tvArticleViewNum:AppCompatTextView = itemView.findViewById(R.id.tv_article_view_num)
var tvArticleLikeNum:AppCompatTextView = itemView.findViewById(R.id.tv_article_like_num)
}
interface OnItemClickListener{
fun onItemClick(articleBean: ArticleBean)
}
}
\ No newline at end of file
package adapter
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import fragment.ArticleHomeFragment
class ArticlePagerAdapter constructor(activity: FragmentActivity,list: MutableList<ArticleHomeFragment>):FragmentStateAdapter(activity) {
private var list = mutableListOf<ArticleHomeFragment>()
init {
this.list = list
}
override fun getItemCount(): Int {
return list.size
}
override fun createFragment(position: Int): Fragment {
return list[position]
}
}
\ No newline at end of file
...@@ -9,7 +9,7 @@ import org.json.JSONObject ...@@ -9,7 +9,7 @@ import org.json.JSONObject
* Created by harvie on 2019/9/6. * Created by harvie on 2019/9/6.
*/ */
@Route(path = "/article/list") //@Route(path = "/article/list")
class ArticleActivity : BaseFlutterActivity() { class ArticleActivity : BaseFlutterActivity() {
override fun initialRoute(): String { override fun initialRoute(): String {
......
package data
data class ArticleCategoryListBean(
val articleCategoryResponseList: MutableList<ArticleCategoryBean>?=null
)
data class ArticleCategoryBean(
val categoryId:Int,
val name: String
)
data class ArticleListBean(
val list:MutableList<ArticleBean>?=null,
val totalPage:Int = 0,
val currentPage:Int = 0
)
//"id": 12516,
//"readNum": 215,
//"title": "当你过于敏感焦虑,来试一下系统脱敏训练吧!",
//"desc": "解析阿辰过于敏感失眠的案例,分析过于敏感和外归因的影响,介绍系统脱敏训练方法,鼓励大家用系统脱敏训练来学会放松,缓解敏感焦虑。",
//"imgUrl": "https://img.ydlcdn.com/file/2022/07/05/z5g81dlgbbu6wjq1.jpg!/fw/270",
//"name": "徐姗姗",
//"doctorId": 33094,
//"smallImage": "http://ydl-userprivacy.ydl.com/2022_05_28_63195910000PWTRVQPVQQUQU.772.jpg",
//"pseudonym": "",
//"countOfFavorite": 2,
//"hUrl": "https://h2.yidianling.com/article/12516",
//"mUrl": "https://m.ydl.com/article/12516",
//"createTime": "Jul 5, 2022 9:58:24 AM",
//"createTimeFormat": "2022-07-05",
//"zanNum": 2,
//"url": "https://h2.yidianling.com/article/12516"
data class ArticleBean(
val id:Int,
val readNum:String = "0",
val title:String,
val desc:String,
val imgUrl:String,
val name:String,
val doctorId:Int,
val smallImage:String,
val pseudonym:String,
val countOfFavorite:Int,
val hUrl:String,
val mUrl:String,
val createTime:String,
val createTimeFormat:String,
val zanNum:String = "0",
val categoryId:Int,
val commentTotal:Int,
val label:String,
val content:String,
val status:Int,
val userType:Int,
val userDoctorId:Int,
val listAllUrl:String
)
package fragment
import adapter.ArticleHomeItemAdapter
import android.content.Context
import android.os.Bundle
import android.view.View
import android.widget.LinearLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.scwang.smart.refresh.footer.ClassicsFooter
import com.scwang.smart.refresh.header.ClassicsHeader
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.ydl.ydl_router.manager.YDLRouterManager
import com.ydl.ydl_router.manager.YDLRouterParams
import com.ydl.ydlcommon.base.BaseFragment
import com.ydl.ydlcommon.router.IYDLRouterConstant
import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils
import com.yidianling.article.R
import data.ArticleBean
import http.ArticleHttp
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
class ArticleHomeFragment : BaseFragment() {
private lateinit var mSmartRefreshLayout: SmartRefreshLayout
private lateinit var mRvArticleContent: RecyclerView
private lateinit var mLlEmptyLayout: LinearLayout
private var mCurrentPage = 1
private var mTotalPage = 0
private var mTagId: Int = 0
private lateinit var mAdapter: ArticleHomeItemAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mTagId = arguments?.getInt(KEY_ARTICLE_TAG_ID, 0) ?: 0
}
override fun layoutResId(): Int {
return R.layout.article_fragment_layout
}
override fun initDataAndEventLazy() {
}
override fun initDataAndEvent() {
mSmartRefreshLayout = rootView.findViewById(R.id.smart_refresh_layout)
mRvArticleContent = rootView.findViewById(R.id.rv_article_content)
mLlEmptyLayout = rootView.findViewById(R.id.ll_empty)
mSmartRefreshLayout.setRefreshHeader(ClassicsHeader(activity))
mSmartRefreshLayout.setRefreshFooter(ClassicsFooter(activity))
mAdapter = ArticleHomeItemAdapter(activity as Context)
mAdapter.setOnItemClickListener(object : ArticleHomeItemAdapter.OnItemClickListener {
override fun onItemClick(articleBean: ArticleBean) {
ActionCountUtils.record("article_list_main_page","article_list_detail_click")
YDLRouterManager.router(
IYDLRouterConstant.ROUTER_H5_H5,
YDLRouterParams().putExtra(IYDLRouterConstant.EXTRA_URL, articleBean.listAllUrl!!), ""
)
}
})
mRvArticleContent.layoutManager =
LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
mRvArticleContent.adapter = mAdapter
mSmartRefreshLayout.autoRefresh()
mSmartRefreshLayout.setOnRefreshListener {
if (mTagId == 0) {
getRecommendArticleList(isRefresh = true,isLoadMore = false)
} else {
getArticleList(isRefresh = true,isLoadMore = false)
}
mSmartRefreshLayout.finishRefresh()
}
mSmartRefreshLayout.setOnLoadMoreListener {
if (mTagId == 0) {
getRecommendArticleList(isRefresh = false,isLoadMore = true)
} else {
getArticleList(isRefresh = false,isLoadMore = true)
}
mSmartRefreshLayout.finishLoadMore()
}
}
override fun onResume() {
super.onResume()
mSmartRefreshLayout.autoRefresh()
}
private fun getRecommendArticleList(isRefresh: Boolean = true, isLoadMore: Boolean = false) {
ArticleHttp.getInstance().getRecommendArticleList(
perPageRows = 10, page = if (isRefresh) {
1
} else {
mCurrentPage + 1
}
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
if (it.code == "200" && it.data != null) {
if (it.data.list.isNullOrEmpty()) {
mLlEmptyLayout.visibility = View.VISIBLE
mRvArticleContent.visibility = View.GONE
} else {
mLlEmptyLayout.visibility = View.GONE
mRvArticleContent.visibility = View.VISIBLE
mCurrentPage = it.data.currentPage
mTotalPage = it.data.totalPage
mSmartRefreshLayout.setEnableLoadMore(mCurrentPage<mTotalPage)
val articles = it.data.list
if (articles != null) {
if (isRefresh) {
mAdapter.setData(articles)
}
if (isLoadMore) {
mAdapter.addData(articles)
}
}
}
} else {
mLlEmptyLayout.visibility = View.VISIBLE
mRvArticleContent.visibility = View.GONE
}
}
}
private fun getArticleList(isRefresh: Boolean = true, isLoadMore: Boolean = false) {
ArticleHttp.getInstance().getArticleList(
perPageRows = 10,
page = if (isRefresh) {
1
} else {
mCurrentPage + 1
},
tagId = mTagId
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
if (it.code == "200" && it.data != null) {
if (it.data.list.isNullOrEmpty()) {
mLlEmptyLayout.visibility = View.VISIBLE
mRvArticleContent.visibility = View.GONE
} else {
mLlEmptyLayout.visibility = View.GONE
mRvArticleContent.visibility = View.VISIBLE
mCurrentPage = it.data.currentPage
mTotalPage = it.data.totalPage
mSmartRefreshLayout.setEnableLoadMore(mCurrentPage<mTotalPage)
val articles = it.data.list
if (articles != null) {
if (isRefresh) {
mAdapter.setData(articles)
}
if (isLoadMore) {
mAdapter.addData(articles)
}
}
}
} else {
mLlEmptyLayout.visibility = View.VISIBLE
mRvArticleContent.visibility = View.GONE
}
}, {
mLlEmptyLayout.visibility = View.VISIBLE
mRvArticleContent.visibility = View.GONE
})
}
companion object {
const val KEY_ARTICLE_TAG_ID = "key_article_tag_id"
fun newInstance(tagId: Int): ArticleHomeFragment {
val args = Bundle()
args.putInt(KEY_ARTICLE_TAG_ID, tagId)
val fragment = ArticleHomeFragment()
fragment.arguments = args
return fragment
}
}
}
\ No newline at end of file
package http
import com.ydl.ydlcommon.base.config.YDL_DOMAIN
import com.ydl.ydlcommon.base.config.YDL_DOMAIN_JAVA
import com.ydl.ydlcommon.data.http.BaseAPIResponse
import data.ArticleCategoryListBean
import data.ArticleListBean
import io.reactivex.Observable
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.Query
interface ArticleApi {
//文章标签
@GET("newArticle/ArticleCate")
@Headers(YDL_DOMAIN + YDL_DOMAIN_JAVA)
fun getArticleTagList(): Observable<BaseAPIResponse<ArticleCategoryListBean>>
//文章列表
@GET("newArticle/list/all")
@Headers(YDL_DOMAIN + YDL_DOMAIN_JAVA)
fun getArticleList(
@Query("perPageRows") perPageRows: Int = 10,
@Query("page") page: Int = 1,
@Query("tagId") tagId: Int = 0
): Observable<BaseAPIResponse<ArticleListBean>>
//文章列表 推荐列表
@GET("newArticle/list/recommend")
@Headers(YDL_DOMAIN + YDL_DOMAIN_JAVA)
fun getRecommendArticleList(
@Query("perPageRows") perPageRows: Int = 10,
@Query("page") page: Int = 1
): Observable<BaseAPIResponse<ArticleListBean>>
}
\ No newline at end of file
package http
import com.ydl.ydlcommon.data.http.BaseAPIResponse
import com.ydl.ydlnet.YDLHttpUtils
import data.ArticleCategoryListBean
import data.ArticleListBean
import io.reactivex.Observable
class ArticleHttp {
companion object{
fun getInstance() = Holder.INSTANCE
}
object Holder{
val INSTANCE = ArticleHttp()
}
private var articleApi:ArticleApi?=null
private fun getArticleApi():ArticleApi{
if (articleApi == null){
articleApi = YDLHttpUtils.obtainApi(ArticleApi::class.java)
}
return articleApi!!
}
fun getArticleCategoryList():Observable<BaseAPIResponse<ArticleCategoryListBean>>{
return getArticleApi().getArticleTagList()
}
fun getRecommendArticleList(perPageRows:Int,page:Int):Observable<BaseAPIResponse<ArticleListBean>>{
return getArticleApi().getRecommendArticleList(perPageRows = perPageRows,page = page)
}
fun getArticleList(perPageRows:Int,page:Int,tagId:Int):Observable<BaseAPIResponse<ArticleListBean>>{
return getArticleApi().getArticleList(perPageRows = perPageRows,page = page,tagId = tagId)
}
}
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M15,3l-8,8l8,8"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#10233A"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/smart_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="20dp"
android:clipToPadding="false">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_article_content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<LinearLayout
android:id="@+id/ll_empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="gone"
android:gravity="center"
tools:visibility="visible">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/platform_ydlcommon_blank"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="14dp"
android:text="暂无相应记录"
android:textColor="#b2b2b2"/>
</LinearLayout>
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_back"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_marginStart="9dp"
android:padding="9dp"
android:src="@drawable/article_home_back_icon"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="文章·阅读"
android:textColor="#000000"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#F8F8F8" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
style="@style/ArticleTabLayoutStyle"
android:layout_width="match_parent"
android:layout_height="38dp"
android:paddingTop="10dp"
app:tabBackground="@color/transparent"
app:tabIndicatorFullWidth="false"
app:tabMaxWidth="88dp"
app:tabMinWidth="64dp"
app:tabMode="scrollable"
app:tabRippleColor="@color/transparent"
app:tabTextAppearance="@style/TabLayoutTextStyle" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:paddingHorizontal="16dp"
android:paddingTop="4dp">
<androidx.cardview.widget.CardView
android:id="@+id/card_view_article_image"
android:layout_width="88dp"
android:layout_height="70dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:cardCornerRadius="8dp"
app:cardElevation="0dp">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_article_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
tools:src="@drawable/picture_album_bg"/>
</androidx.cardview.widget.CardView>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_article_title"
android:layout_width="0dp"
app:layout_constraintHorizontal_weight="1"
android:layout_height="wrap_content"
android:maxHeight="44dp"
android:maxLines="2"
app:layout_constraintEnd_toStartOf="@id/card_view_article_image"
android:ellipsize="end"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#1C1F28"
android:layout_marginEnd="18dp"
android:lineSpacingExtra="1dp"
tools:text="最伟大的作品,是魔术啊,最伟大的作品,是魔术啊。"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/card_view_article_image"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_article_desc"
android:layout_width="0dp"
app:layout_constraintHorizontal_weight="1"
android:layout_height="18dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toStartOf="@id/card_view_article_image"
android:maxLines="1"
android:ellipsize="end"
android:textSize="13sp"
android:singleLine="true"
android:textColor="#9D9EA7"
android:layout_marginEnd="18dp"
tools:text="最伟大的作品,是魔术啊,最伟大的作品,是魔术啊。fdasfa"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_article_title"/>
<androidx.cardview.widget.CardView
android:id="@+id/card_view_avatar"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginTop="17dp"
app:layout_constraintStart_toStartOf="@id/tv_article_title"
app:layout_constraintTop_toBottomOf="@id/card_view_article_image"
app:cardElevation="0dp"
app:cardCornerRadius="8dp">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_author_avatar"
android:layout_width="16dp"
android:layout_height="16dp"
tools:src="@drawable/icon_meditation_share_wechat"/>
</androidx.cardview.widget.CardView>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_author_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:textSize="13sp"
android:textColor="#62636F"
tools:text="黄秀章"
app:layout_constraintStart_toEndOf="@id/card_view_avatar"
app:layout_constraintTop_toTopOf="@id/card_view_avatar"
app:layout_constraintBottom_toBottomOf="@id/card_view_avatar"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_article_view_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="2656浏览"
android:textSize="13sp"
android:layout_marginEnd="70dp"
android:textColor="#62636F"
app:layout_constraintBaseline_toBaselineOf="@id/tv_author_name"
app:layout_constraintEnd_toEndOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_article_like_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="3327点赞"
android:textSize="13sp"
android:textColor="#62636F"
app:layout_constraintBaseline_toBaselineOf="@id/tv_author_name"
app:layout_constraintEnd_toEndOf="parent"/>
<View
android:id="@+id/homeModuleArticleItemViewBottomLine"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#EFEFF1"
android:layout_marginTop="20dp"
android:layout_marginBottom="30dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/card_view_avatar"/>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="color_1DA1F2">#1DA1F2</color>
<color name="color_999999">#999999</color>
<color name="color_000000">#000000</color>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="ArticleTabLayoutStyle" parent="TextAppearance.Design.Tab">
<item name="tabIndicatorColor">@color/color_1DA1F2</item>
<item name="tabIndicatorHeight">4dp</item>
<item name="tabIndicatorFullWidth">false</item>
<item name="android:textSize">16sp</item>
<item name="tabSelectedTextColor">@color/color_000000</item>
<item name="android:textColor">@color/color_999999</item>
<item name="android:textStyle">normal</item>
</style>
<style name="TabLayoutTextStyle" parent="TextAppearance.Design.Tab">
<item name="android:textSize">16sp</item>
</style>
</resources>
\ No newline at end of file
...@@ -2,7 +2,7 @@ apply plugin: 'com.android.library' ...@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply from: "../maven_push.gradle" apply from: "../publish.gradle"
kapt { kapt {
arguments { arguments {
...@@ -71,19 +71,8 @@ dependencies { ...@@ -71,19 +71,8 @@ dependencies {
api "com.ydl:ydl-av:1.4.4" api "com.ydl:ydl-av:1.4.4"
implementation 'com.volcengine:apm_insight:1.4.6.cn' implementation 'com.volcengine:apm_insight:1.4.6.cn'
if (rootProject.ext.dev_mode){
//开发时使用
api project(':ydl-platform') api project(':ydl-platform')
api project(':ydl-webview') api project(':ydl-webview')
implementation project(":api:user") implementation project(":api:user")
implementation project(":api:im") implementation project(":api:im")
}else {
//发布时使用
api rootProject.ext.dependencies["ydl-webview"]
compileOnly rootProject.ext.dependencies["ydl-m-user-api"]
compileOnly rootProject.ext.dependencies["ydl-m-im-api"]
api(rootProject.ext.dependencies["ydl-platform"]) {
transitive = true
}
}
} }
...@@ -166,7 +166,7 @@ class YDLavManager { ...@@ -166,7 +166,7 @@ class YDLavManager {
LogUtil.e("[agora]呼叫${response?.calleeId}用户失败:${response?.response}") LogUtil.e("[agora]呼叫${response?.calleeId}用户失败:${response?.response}")
AliYunRichLogsHelper.getInstance().sendRichLog( AliYunRichLogsHelper.getInstance().sendRichLog(
AliYunLogConfig.AGORA, AliYunLogConfig.AGORA,
"呼叫${response?.calleeId}用户失败:${response?.response}" "呼叫${response?.calleeId}用户失败:${response?.response},${errorCode}"
) )
val dimension = hashMapOf( val dimension = hashMapOf(
"call" to "call_fail", "call" to "call_fail",
...@@ -432,7 +432,7 @@ class YDLavManager { ...@@ -432,7 +432,7 @@ class YDLavManager {
override fun onFailure(msg: String?) { override fun onFailure(msg: String?) {
if (msg != "LOGIN_ERR_ALREADY_LOGGED_IN") { if (msg != "LOGIN_ERR_ALREADY_LOGGED_IN") {
Apm.reportCustom("agora_login_error", msg ?: "", Exception(msg)) Apm.reportEvent("rtm_android", "connectionstate_error", msg ?: "")
} }
LogUtil.e("[agora]实时消息登录失败:$msg") LogUtil.e("[agora]实时消息登录失败:$msg")
writeAgoraLog( writeAgoraLog(
...@@ -449,6 +449,7 @@ class YDLavManager { ...@@ -449,6 +449,7 @@ class YDLavManager {
} }
}) })
} else { } else {
Apm.reportEvent("rtm_android", "login_failure", "${it.code},${it.msg}")
LogUtil.e("声网token获取失败uid:" + userId + " error:" + it.msg) LogUtil.e("声网token获取失败uid:" + userId + " error:" + it.msg)
LogHelper.getInstance() LogHelper.getInstance()
.writeLogSync("声网token获取失败uid:" + userId + " error:" + it.msg) .writeLogSync("声网token获取失败uid:" + userId + " error:" + it.msg)
......
...@@ -2,7 +2,7 @@ apply plugin: 'com.android.library' ...@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply from : '../maven_push.gradle' apply from: "../publish.gradle"
kapt { kapt {
arguments { arguments {
...@@ -65,11 +65,10 @@ dependencies { ...@@ -65,11 +65,10 @@ dependencies {
// 注意此处的依赖方式:kotlin中使用和java中使用方式有不同 // 注意此处的依赖方式:kotlin中使用和java中使用方式有不同
kapt "com.alibaba:arouter-compiler:$arouter_compiler" kapt "com.alibaba:arouter-compiler:$arouter_compiler"
implementation 'com.alibaba:fastjson:1.2.38' implementation 'com.alibaba:fastjson:1.2.38'
implementation "com.ydl:jjdxm-ijkplayer:0.0.33" implementation(rootProject.ext.dependencies["ydl-ijkplayer-jjdxm"]) {
exclude group: 'com.android.support', module: 'appcompat-v7'
}
api rootProject.ext.dependencies["ydl-user-router"] api rootProject.ext.dependencies["ydl-user-router"]
if (rootProject.ext.dev_mode){
//开发时使用
api project(':ydl-media') api project(':ydl-media')
api project(':ydl-platform') api project(':ydl-platform')
api project(':m-audioim') api project(':m-audioim')
...@@ -80,18 +79,4 @@ dependencies { ...@@ -80,18 +79,4 @@ dependencies {
implementation project(":api:user") implementation project(":api:user")
implementation project(":api:consultant") implementation project(":api:consultant")
implementation project(':api:confide') implementation project(':api:confide')
}else {
//发布时使用
api rootProject.ext.dependencies["ydl-media"]
api rootProject.ext.dependencies["m-audioim"]
api rootProject.ext.dependencies["ydl-pay"]
api rootProject.ext.dependencies["ydl-webview"]
api(rootProject.ext.dependencies["ydl-platform"]) {
transitive = true
}
compileOnly rootProject.ext.dependencies["ydl-m-im-api"]
compileOnly rootProject.ext.dependencies["ydl-m-user-api"]
compileOnly rootProject.ext.dependencies["ydl-m-confide-api"]
compileOnly rootProject.ext.dependencies["ydl-m-consultant-api"]
}
} }
...@@ -133,15 +133,17 @@ class ConfideHomeEventImpl(context: Context, var confideHomeView: IConfideHomeCo ...@@ -133,15 +133,17 @@ class ConfideHomeEventImpl(context: Context, var confideHomeView: IConfideHomeCo
* @param linkUrl 跳转地址 * @param linkUrl 跳转地址
*/ */
override fun consultantClick(doctorId: String?, confideId: String?, uid: String?,listenFree : Boolean?, expertUrl:String?) { override fun consultantClick(doctorId: String?, confideId: String?, uid: String?,listenFree : Boolean?, expertUrl:String?) {
confideId?.let { doctorId?.let { doctorId ->
confideId?.let {confideId ->
ConfideBottomSheetDialogFragment() ConfideBottomSheetDialogFragment()
.showBottomSheetDialog( .showBottomSheetDialog(
mContext as FragmentActivity, mContext as FragmentActivity,
HttpConfig.MH5_URL + ConfideRoute.h5ConfideIntro(it), HttpConfig.MH5_URL + ConfideRoute.h5ConfideIntro(confideId),
doctorId!!, uid = uid, listenFree = listenFree ?: false,expertUrl = expertUrl?:"" doctorId, uid = uid, listenFree = listenFree ?: false,expertUrl = expertUrl?:""
) )
} }
} }
}
override fun videoShowClick(index: Int, data: List<ConfideHomeBodyBean>?) { override fun videoShowClick(index: Int, data: List<ConfideHomeBodyBean>?) {
......
...@@ -433,7 +433,7 @@ internal fun VideoViewModel.mapOf(bean: ConfideHomeBodyBean): VideoViewModel { ...@@ -433,7 +433,7 @@ internal fun VideoViewModel.mapOf(bean: ConfideHomeBodyBean): VideoViewModel {
avatar.set(bean.confidedIcon) avatar.set(bean.confidedIcon)
linkedUrl.set(bean.linkUrl) linkedUrl.set(bean.linkUrl)
val num = bean.confideNum?.replace("人", "") ?: "0" val num = bean.confideNum?.replace("人", "") ?: "0"
count.set("倾诉人次 $num") count.set("服务人次 $num")
intro.set(bean.confideContent) intro.set(bean.confideContent)
title.set(bean.title) title.set(bean.title)
val sb = StringBuilder() val sb = StringBuilder()
......
...@@ -116,7 +116,7 @@ ...@@ -116,7 +116,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="@dimen/platform_sp_12" android:textSize="@dimen/platform_sp_12"
android:textColor="#69696A" android:textColor="#69696A"
android:text="倾诉人次" android:text="服务人次"
/> />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
......
...@@ -2,7 +2,7 @@ apply plugin: 'com.android.library' ...@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply from: "../maven_push.gradle" apply from: "../publish.gradle"
kapt { kapt {
arguments { arguments {
...@@ -43,26 +43,18 @@ dependencies { ...@@ -43,26 +43,18 @@ dependencies {
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
implementation 'in.xiandan:count-down-timer:1.0.3'
kapt 'com.alibaba:arouter-compiler:1.2.2' kapt 'com.alibaba:arouter-compiler:1.2.2'
implementation rootProject.ext.dependencies["BaseRecyclerViewAdapterHelper"] implementation rootProject.ext.dependencies["BaseRecyclerViewAdapterHelper"]
api rootProject.ext.dependencies["ydl-user-router"] api rootProject.ext.dependencies["ydl-user-router"]
if (rootProject.ext.dev_mode){ implementation(rootProject.ext.dependencies["ydl-ijkplayer-jjdxm"]) {
//开发时使用 exclude group: 'com.android.support', module: 'appcompat-v7'
}
implementation project(":api:user") implementation project(":api:user")
implementation project(":api:im") implementation project(":api:im")
implementation modularPublication('com.ydl:m-home-api') implementation project(":api:home")
implementation project(":api:consultant") implementation project(":api:consultant")
api project(":ydl-webview") api project(":ydl-webview")
api project(":ydl-platform") api project(":ydl-platform")
} else {
//发布时使用
compileOnly rootProject.ext.dependencies["ydl-m-user-api"]
compileOnly rootProject.ext.dependencies["ydl-m-im-api"]
compileOnly rootProject.ext.dependencies["ydl-m-home-api"]
compileOnly rootProject.ext.dependencies["ydl-m-consultant-api"]
api rootProject.ext.dependencies["ydl-webview"]
api(rootProject.ext.dependencies["ydl-platform"]) {
transitive = true
}
}
} }
...@@ -18,6 +18,14 @@ ...@@ -18,6 +18,14 @@
android:name=".ConsultAssistantCenterActivity" android:name=".ConsultAssistantCenterActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/consultant_Transparent"/> android:theme="@style/consultant_Transparent"/>
<activity android:name=".preview.GridPreviewActivity"
android:screenOrientation="portrait"
android:theme="@style/consultant_Transparent"/>
<activity android:name=".preview.GPreviewActivity"
android:screenOrientation="portrait"
android:theme="@style/consultant_Transparent"/>
</application> </application>
</manifest> </manifest>
\ No newline at end of file
...@@ -82,6 +82,9 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres ...@@ -82,6 +82,9 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
YDLImageCacheManager.showImage(this, url, imgView, ops) YDLImageCacheManager.showImage(this, url, imgView, ops)
} }
override fun showPromptPayment(promptPaymentBean: PromptPaymentBean) {
}
override fun showImage( override fun showImage(
url: String?, url: String?,
imgView: ImageView, imgView: ImageView,
......
...@@ -34,9 +34,11 @@ import com.ydl.ydlcommon.base.BaseMvpFragment ...@@ -34,9 +34,11 @@ import com.ydl.ydlcommon.base.BaseMvpFragment
import com.ydl.ydlcommon.base.config.ChannelConfig import com.ydl.ydlcommon.base.config.ChannelConfig
import com.ydl.ydlcommon.base.config.HttpConfig import com.ydl.ydlcommon.base.config.HttpConfig
import com.ydl.ydlcommon.data.PlatformDataManager import com.ydl.ydlcommon.data.PlatformDataManager
import com.ydl.ydlcommon.modular.findRouteService
import com.ydl.ydlcommon.ui.LogoLoadingView import com.ydl.ydlcommon.ui.LogoLoadingView
import com.ydl.ydlcommon.utils.BuryPointUtils import com.ydl.ydlcommon.utils.BuryPointUtils
import com.ydl.ydlcommon.utils.DisplayUtils import com.ydl.ydlcommon.utils.DisplayUtils
import com.ydl.ydlcommon.utils.SharedPreferencesEditor
import com.ydl.ydlcommon.utils.StatusBarUtils import com.ydl.ydlcommon.utils.StatusBarUtils
import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils
import com.ydl.ydlcommon.utils.remind.ToastHelper import com.ydl.ydlcommon.utils.remind.ToastHelper
...@@ -46,16 +48,21 @@ import com.yidianling.common.tools.LogUtil ...@@ -46,16 +48,21 @@ import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.RxImageTool import com.yidianling.common.tools.RxImageTool
import com.yidianling.common.tools.ToastUtil import com.yidianling.common.tools.ToastUtil
import com.yidianling.consultant.adapter.ExpertSearchAdapter import com.yidianling.consultant.adapter.ExpertSearchAdapter
import com.yidianling.consultant.bean.FunctionWordConsultBean
import com.yidianling.consultant.constants.ConsultBIConstants import com.yidianling.consultant.constants.ConsultBIConstants
import com.yidianling.consultant.constants.ConsultBIConstants.ConsultantLocationAuth.Companion.WHETHER_LOCATION_AUTH import com.yidianling.consultant.constants.ConsultBIConstants.ConsultantLocationAuth.Companion.WHETHER_LOCATION_AUTH
import com.yidianling.consultant.listener.* import com.yidianling.consultant.listener.*
import com.yidianling.consultant.dialog.ConsultSubPayDialog
import com.yidianling.consultant.listener.OnCategoriesSelectedListener
import com.yidianling.consultant.listener.OnExpertClickListener
import com.yidianling.consultant.listener.OnFilterConfirmListener
import com.yidianling.consultant.listener.OnSortItemSelectedListener
import com.yidianling.consultant.model.bean.* import com.yidianling.consultant.model.bean.*
import com.yidianling.consultant.modular.singlton.ConsultAssistantDialogUtils import com.yidianling.consultant.modular.singlton.ConsultAssistantDialogUtils
import com.yidianling.consultant.router.ConsultantIn import com.yidianling.consultant.router.ConsultantIn
import com.yidianling.consultant.ui.view.* import com.yidianling.consultant.ui.view.*
import com.yidianling.consultant.ui.view.topView.RecommendListView import com.yidianling.consultant.ui.view.topView.RecommendListView
import com.yidianling.home.api.event.HomeModuleTabEvent import com.yidianling.home.api.event.HomeModuleTabEvent
import com.yidianling.user.api.service.IUserService
import de.greenrobot.event.EventBus import de.greenrobot.event.EventBus
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
...@@ -80,6 +87,7 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres ...@@ -80,6 +87,7 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
var endTime = 0L var endTime = 0L
private var mIdssign1: String = "" // 列表埋点咨询师列表id拼接参数 private var mIdssign1: String = "" // 列表埋点咨询师列表id拼接参数
var bottomWordDisposable: Disposable? = null var bottomWordDisposable: Disposable? = null
var isShow: Boolean = false
private lateinit var bottomWordlist: List<FunctionWordBean> private lateinit var bottomWordlist: List<FunctionWordBean>
override fun layoutResId(): Int { override fun layoutResId(): Int {
return R.layout.consultant_activity_expert_search_list return R.layout.consultant_activity_expert_search_list
...@@ -124,6 +132,19 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres ...@@ -124,6 +132,19 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
} }
} }
var consultSubPayDialog: ConsultSubPayDialog? = null
override fun showPromptPayment(promptPaymentBean: PromptPaymentBean) {
if (promptPaymentBean.toPayTime != 0L) {
//有订单
consultSubPayDialog = activity?.let { ConsultSubPayDialog(it, promptPaymentBean) }
consultSubPayDialog?.show()
consultSubPayDialog?.setOnDismissListener {
consultSubPayDialog = null
}
}
}
override fun showImage( override fun showImage(
url: String?, url: String?,
imgView: ImageView, imgView: ImageView,
...@@ -305,11 +326,10 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres ...@@ -305,11 +326,10 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
override fun setUserVisibleHint(isVisibleToUser: Boolean) { override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser) super.setUserVisibleHint(isVisibleToUser)
isShow = isVisibleToUser
if (isVisibleToUser && isResumed) { if (isVisibleToUser && isResumed) {
startTime = System.currentTimeMillis() startTime = System.currentTimeMillis()
showConsultAssistantDialog()
} else { } else {
hideConsultAssistantDialog()
if (startTime != 0L) { if (startTime != 0L) {
endTime = System.currentTimeMillis() endTime = System.currentTimeMillis()
ActionCountUtils.count( ActionCountUtils.count(
...@@ -1549,6 +1569,22 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres ...@@ -1549,6 +1569,22 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
// //
needRefresh = true needRefresh = true
} }
val orderToPayTime = SharedPreferencesEditor.getString("orderToPayTime")
val timeLimit = if (TextUtils.isEmpty(orderToPayTime)) {
0L
} else {
orderToPayTime.toLong()
}
if (isShow && !(consultSubPayDialog != null && consultSubPayDialog?.isShowing == true)) {
if (findRouteService(IUserService::class.java).isLogin() && System.currentTimeMillis() > timeLimit) {
getPresenter().fetchPromptPayment()
}
}
ActionCountUtils.count(ConsultBIConstants.ConsultEvent.APP_CONSULT_LIST_PAGE_VISIT) ActionCountUtils.count(ConsultBIConstants.ConsultEvent.APP_CONSULT_LIST_PAGE_VISIT)
ActionCountUtils.count("daoyi_advertisement_page|daoyi_advertisement_visit", "6") ActionCountUtils.count("daoyi_advertisement_page|daoyi_advertisement_visit", "6")
} }
......
...@@ -245,6 +245,8 @@ class ExpertSearchPresenter : SimplePresenter<IExpertSearchView>() { ...@@ -245,6 +245,8 @@ class ExpertSearchPresenter : SimplePresenter<IExpertSearchView>() {
fieldsMap["open_chat_agency"] = true fieldsMap["open_chat_agency"] = true
fieldsMap["service_status"] = true fieldsMap["service_status"] = true
fieldsMap["is_free_today"] = true fieldsMap["is_free_today"] = true
fieldsMap["display_region"] = true
fieldsMap["has_servicefree_experience"] = true
map["fields"] = fieldsMap map["fields"] = fieldsMap
val optionsMap = HashMap<String, Any?>() val optionsMap = HashMap<String, Any?>()
...@@ -281,4 +283,18 @@ class ExpertSearchPresenter : SimplePresenter<IExpertSearchView>() { ...@@ -281,4 +283,18 @@ class ExpertSearchPresenter : SimplePresenter<IExpertSearchView>() {
} }
}) })
} }
@SuppressLint("CheckResult")
fun fetchPromptPayment() {
SearchApi.getSearchApi()
.promptPayment()
.compose(RxLifecycleUtils.bindToLifecycle(mView))//使用 Rxlifecycle,使 Disposable 和 Activity 一起销毁
.compose(RxUtils.resultJavaData())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { resp ->
mView.showPromptPayment(resp)
}
}
} }
\ No newline at end of file
...@@ -52,6 +52,8 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon ...@@ -52,6 +52,8 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon
private var historyList: FixSizeLinkedList<String> = FixSizeLinkedList(15) private var historyList: FixSizeLinkedList<String> = FixSizeLinkedList(15)
private val bannerList = ArrayList<String>() private val bannerList = ArrayList<String>()
private var lenovoResultSuccess = false // 联想结果 联想前false 联想成功后true
companion object { companion object {
private const val CACHE_CONSULT_SEARCH_HISTORY_DATA = "cache_consult_search_history_data" private const val CACHE_CONSULT_SEARCH_HISTORY_DATA = "cache_consult_search_history_data"
private const val HOT_SEARCH_DOCTOR_NAME = "hot_search_doctor_name" private const val HOT_SEARCH_DOCTOR_NAME = "hot_search_doctor_name"
...@@ -111,7 +113,11 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon ...@@ -111,7 +113,11 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon
// 搜索的关联词 // 搜索的关联词
var relatedWords = "" var relatedWords = ""
var isRecommendWords = false var isRecommendWords = false
if (searchSuggestList.isNotEmpty() && searchSuggestList.size > 0) { if (!lenovoResultSuccess && !etSearch.text.toString()
.isNullOrEmpty()
) { // 如果每次输入内容后联想词结果还没返回结果则直接进行搜索
doSearch(etSearch.text.toString(), relatedWords, isRecommendWords)
} else if (searchSuggestList.isNotEmpty() && searchSuggestList.size > 0) {
if (searchSuggestList[0].suggest_relations.size > 0) { if (searchSuggestList[0].suggest_relations.size > 0) {
relatedWords = searchSuggestList[0].suggest_relations[0] relatedWords = searchSuggestList[0].suggest_relations[0]
isRecommendWords = true isRecommendWords = true
...@@ -120,7 +126,7 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon ...@@ -120,7 +126,7 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon
relatedWords = searchSuggestList[0].suggest_content relatedWords = searchSuggestList[0].suggest_content
} }
if (searchSuggestList?.get(0)?.suggest_types?.contains(JUMP_WORD)) { if (searchSuggestList[0].suggest_types.contains(JUMP_WORD)) {
NewH5Activity.start(this, H5Params(searchSuggestList[0].jump_url!!, null)) NewH5Activity.start(this, H5Params(searchSuggestList[0].jump_url!!, null))
} else { } else {
if (etSearch.text.toString().isNullOrEmpty()) { if (etSearch.text.toString().isNullOrEmpty()) {
...@@ -231,6 +237,7 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon ...@@ -231,6 +237,7 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon
*/ */
private fun getSearchWords(searchContent: String, isClickWords: Boolean) { private fun getSearchWords(searchContent: String, isClickWords: Boolean) {
if (!TextUtils.isEmpty(searchContent)) { if (!TextUtils.isEmpty(searchContent)) {
lenovoResultSuccess = false
mSearchContent = searchContent mSearchContent = searchContent
val map = HashMap<String, Any>() val map = HashMap<String, Any>()
map["content"] = searchContent map["content"] = searchContent
...@@ -245,6 +252,7 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon ...@@ -245,6 +252,7 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon
searchContent: String, searchContent: String,
isClickWords: Boolean isClickWords: Boolean
) { ) {
lenovoResultSuccess = true
if (isClickWords) { if (isClickWords) {
//判断 suggest_classify_types 有值则通过 jump_url跳转 //判断 suggest_classify_types 有值则通过 jump_url跳转
// 搜索的关联词 // 搜索的关联词
......
...@@ -4,10 +4,7 @@ import android.widget.ImageView ...@@ -4,10 +4,7 @@ import android.widget.ImageView
import com.ydl.ydl_image.config.SimpleImageOpConfiger import com.ydl.ydl_image.config.SimpleImageOpConfiger
import com.ydl.ydlcommon.mvp.base.IView import com.ydl.ydlcommon.mvp.base.IView
import com.yidianling.consultant.bean.FunctionWordConsultBean import com.yidianling.consultant.bean.FunctionWordConsultBean
import com.yidianling.consultant.model.bean.ExpertServiceItem import com.yidianling.consultant.model.bean.*
import com.yidianling.consultant.model.bean.Extras
import com.yidianling.consultant.model.bean.FunctionWordBean
import com.yidianling.consultant.model.bean.HeadData
/** /**
* Created by zqk on 17-9-19. * Created by zqk on 17-9-19.
...@@ -38,4 +35,6 @@ interface IExpertSearchView : IView { ...@@ -38,4 +35,6 @@ interface IExpertSearchView : IView {
*/ */
fun showImage(url : String?, imgView : ImageView, ops : SimpleImageOpConfiger) fun showImage(url : String?, imgView : ImageView, ops : SimpleImageOpConfiger)
fun showPromptPayment(promptPaymentBean: PromptPaymentBean)
} }
\ No newline at end of file
...@@ -177,14 +177,14 @@ class ExpertSearchAdapter( ...@@ -177,14 +177,14 @@ class ExpertSearchAdapter(
//省市 //省市
if (!TextUtils.isEmpty(itemBean.province)) { if (!TextUtils.isEmpty(itemBean.display_region)) {
holder.tvCity.text = itemBean.province + "·" + itemBean.city holder.tvCity.text = itemBean.display_region
} else { } else {
holder.tvCity.text = "" holder.tvCity.text = ""
} }
//公益图标,不与其他图标冲突 //公益图标,不与其他图标冲突
if (1 == itemBean.has_servicefree_consult) { if (1 == itemBean.has_servicefree_experience) {
if (null != itemBean.icons && !TextUtils.isEmpty(itemBean.icons.service_free_icon)) { if (null != itemBean.icons && !TextUtils.isEmpty(itemBean.icons.service_free_icon)) {
expertSearchView.showImage( expertSearchView.showImage(
itemBean.icons.service_free_icon, itemBean.icons.service_free_icon,
......
package com.yidianling.consultant.dialog
import `in`.xiandan.countdowntimer.CountDownTimerSupport
import `in`.xiandan.countdowntimer.OnCountDownTimerListener
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.text.TextUtils
import android.view.Gravity
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import android.widget.TextView
import com.bumptech.glide.Glide
import com.ydl.webview.H5Params
import com.ydl.webview.NewH5Activity
import com.ydl.ydlcommon.utils.SharedPreferencesEditor
import com.yidianling.common.tools.ToastUtil
import com.yidianling.consultant.R
import com.yidianling.consultant.model.bean.PromptPaymentBean
import java.text.DecimalFormat
import java.text.SimpleDateFormat
import java.util.*
/**
* 咨询助理浮层
* Created by xj on 2019/10/30.
*/
class ConsultSubPayDialog(
private val mContext: Context,
private val promptPaymentBean: PromptPaymentBean
) : Dialog(mContext, R.style.dialog_default_style) {
var mTimer: CountDownTimerSupport? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.consultant_expert_consult_sub_pay_dialog)
val params = window.attributes
params.width = WindowManager.LayoutParams.WRAP_CONTENT
params.height = WindowManager.LayoutParams.WRAP_CONTENT
params.gravity = Gravity.CENTER
window.attributes = params
setCanceledOnTouchOutside(false)
initView();
}
private fun initView() {
var titleTv = findViewById<TextView>(R.id.tv_title)
var timeTv = findViewById<TextView>(R.id.tv_time)
titleTv.paint.isFakeBoldText = true
Glide.with(mContext)
.load(promptPaymentBean.smallImage).into(findViewById<ImageView>(R.id.avaterIv))
findViewById<TextView>(R.id.nameTv).text = promptPaymentBean.name
findViewById<TextView>(R.id.desTv).text = promptPaymentBean.productName
val decimalFormat = DecimalFormat("###.##")
val price = decimalFormat.format(promptPaymentBean.price)
findViewById<TextView>(R.id.priceTv).text = "¥$price"
var format = SimpleDateFormat("HH:mm:ss");
format.timeZone = TimeZone.getTimeZone("GMT+0");
var millisInFuture =
promptPaymentBean.toPayTime?.minus(promptPaymentBean.currentTime ?: 0) ?: 0
mTimer = CountDownTimerSupport(millisInFuture, 1000)
mTimer?.setOnCountDownTimerListener(object : OnCountDownTimerListener {
override fun onTick(millisUntilFinished: Long) {
val time = format.format(millisUntilFinished)
timeTv.text = time
}
override fun onFinish() {
var nextShowTime =
System.currentTimeMillis() + ((promptPaymentBean.orderToPayTime ?: 1) * 1000)
SharedPreferencesEditor.putString("orderToPayTime", nextShowTime.toString())
dismiss()
}
override fun onCancel() {
// 倒计时手动停止
}
})
mTimer?.start()
findViewById<TextView>(R.id.tv_close).setOnClickListener {
var nextShowTime =
System.currentTimeMillis() + ((promptPaymentBean.orderToPayTime ?: 1) * 1000)
SharedPreferencesEditor.putString("orderToPayTime", nextShowTime.toString())
mTimer?.stop()
dismiss()
}
findViewById<View>(R.id.pay).setOnClickListener {
if (!TextUtils.isEmpty(promptPaymentBean.orderDetailUrl)) {
val h5Params = H5Params(promptPaymentBean.orderDetailUrl!!, null)
NewH5Activity.start(context, h5Params)
dismiss()
} else {
ToastUtil.toastShort("跳转失败")
dismiss()
}
var nextShowTime =
System.currentTimeMillis() + ((promptPaymentBean.orderToPayTime ?: 1) * 1000)
SharedPreferencesEditor.putString("orderToPayTime", nextShowTime.toString())
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
if (mTimer != null) {
mTimer?.stop()
mTimer = null
}
}
}
\ No newline at end of file
...@@ -10,6 +10,7 @@ import com.yidianling.consultant.bean.* ...@@ -10,6 +10,7 @@ import com.yidianling.consultant.bean.*
import com.yidianling.consultant.model.bean.ExpertBean import com.yidianling.consultant.model.bean.ExpertBean
import com.yidianling.consultant.model.bean.FunctionWordBean import com.yidianling.consultant.model.bean.FunctionWordBean
import com.yidianling.consultant.model.bean.HeadData import com.yidianling.consultant.model.bean.HeadData
import com.yidianling.consultant.model.bean.PromptPaymentBean
import io.reactivex.Observable import io.reactivex.Observable
import retrofit2.http.* import retrofit2.http.*
...@@ -117,4 +118,10 @@ interface SearchApi { ...@@ -117,4 +118,10 @@ interface SearchApi {
fun getCityByIp(): Observable<BaseAPIResponse<ConsultantRegionBean>> fun getCityByIp(): Observable<BaseAPIResponse<ConsultantRegionBean>>
//搜索条件
@GET("consult/user/order/promptPayment")
@Headers(YDL_DOMAIN + YDL_DOMAIN_JAVA)
fun promptPayment(): Observable<BaseAPIResponse<PromptPaymentBean>>
} }
\ No newline at end of file
...@@ -108,11 +108,11 @@ data class ExpertServiceItem( ...@@ -108,11 +108,11 @@ data class ExpertServiceItem(
// */ // */
// var listen_status: Int, // var listen_status: Int,
var open_chat_agency:Int, var open_chat_agency: Int,
var service_status:Int, var service_status: Int,
var is_free_today:Int, var is_free_today: Int,
/** /**
* 私聊人数 * 私聊人数
...@@ -143,26 +143,39 @@ data class ExpertServiceItem( ...@@ -143,26 +143,39 @@ data class ExpertServiceItem(
/** /**
* 是否是头部headView * 是否是头部headView
*/ */
val is_head_view:Boolean=false, val is_head_view: Boolean = false,
/** /**
* 搜索词 * 搜索词
*/ */
val search_content:String, val search_content: String,
/** /**
* 联想词 * 联想词
*/ */
val related_word:String val related_word: String,
/**
* 地区
*/
val display_region: String,
/**
* 是否展示公益图标
*/
val has_servicefree_experience: Int?
) { ) {
constructor(is_head_view: Boolean,search_content: String,related_word:String) : this("","","","","", constructor(is_head_view: Boolean, search_content: String, related_word: String) : this(
1,1,1,"",false,true, "", "", "", "", "",
1f,false,0,"","","",1f,1f, 1, 1, 1, "", false, true,
null,null,1,1,1,1, 1f, false, 0, "", "", "", 1f, 1f,
"","","","",null,is_head_view,search_content,related_word) null, null, 1, 1, 1, 1,
"", "", "", "", null, is_head_view, search_content, related_word, "", 1
)
} }
data class FeatureTag( data class FeatureTag(
val tag_id:String, val tag_id: String,
val tag_name:String, val tag_name: String,
val is_highlight:Boolean, // 是否高亮 val is_highlight: Boolean, // 是否高亮
val type:String // 标签类型 val type: String // 标签类型
) )
\ No newline at end of file
package com.yidianling.consultant.model.bean
data class PromptPaymentBean(
var uid: String? = "",
var orderId: String? = "",
var toPayTime: Long? = 0,
var smallImage: String? = "",
var name: String? = "",
var price: Float? = 0.00f,
var productName: String? = "",
var doctorId: String? = "",
var productId: String? = "",
var createTime: String? = "",
var orderToPayTime: Long? = 0,
var orderDetailUrl: String? = "",
var currentTime: Long? = 0
)
...@@ -40,8 +40,9 @@ class ConsultAssistantDialogUtils private constructor() { ...@@ -40,8 +40,9 @@ class ConsultAssistantDialogUtils private constructor() {
var consultAssistantDialogFromHomePage: ConsultAssistantDialog? = null // 首页展示的dialog var consultAssistantDialogFromHomePage: ConsultAssistantDialog? = null // 首页展示的dialog
var consultAssistantDialogFromMine: ConsultAssistantDialog? = null // 我的展示的dialog var consultAssistantDialogFromMine: ConsultAssistantDialog? = null // 我的展示的dialog
var consultAssistantFragmentDialog: ConsultAssistantDialog? = null //咨询师列表fragment页面展示的dialog var consultAssistantFragmentDialog: ConsultAssistantDialog? = null //咨询师列表fragment页面展示的dialog
var expertSearchPageHasShown: Boolean = false // 专家咨询列表fragment页面是否已经展示
var consultAssistantActivityDialog: ConsultAssistantDialog? = null //咨询师列表activity页面展示的dialog var consultAssistantActivityDialog: ConsultAssistantDialog? = null //咨询师列表activity页面展示的dialog
var expertSearchPageHasShown: Boolean = false // 专家咨询列表fragment页面是否已经展示
var confideListDialog: ConsultAssistantDialog? = null //倾诉列表activity页面展示的dialog var confideListDialog: ConsultAssistantDialog? = null //倾诉列表activity页面展示的dialog
var expertSearchActivityPageHasShown: Boolean = false // 专家咨询列表activity页面是否已经展示 var expertSearchActivityPageHasShown: Boolean = false // 专家咨询列表activity页面是否已经展示
...@@ -73,6 +74,9 @@ class ConsultAssistantDialogUtils private constructor() { ...@@ -73,6 +74,9 @@ class ConsultAssistantDialogUtils private constructor() {
shouldShowDialog(activity, origin) shouldShowDialog(activity, origin)
} }
} }
"other_index" ->{
shouldShowDialog(activity, origin)
}
} }
} }
...@@ -86,20 +90,20 @@ class ConsultAssistantDialogUtils private constructor() { ...@@ -86,20 +90,20 @@ class ConsultAssistantDialogUtils private constructor() {
origin: String, origin: String,
fromActivity: Boolean = false fromActivity: Boolean = false
) { ) {
if (!fromActivity){ // 不是咨询师二级列页的时候再所有的dialog dismiss
// 请求接口判断导医咨询助理按钮是否展示 consultAssistantDialogFromHomePage?.dismiss()
SearchApi.getSearchApi().getConsultAssistantRequest(origin) consultAssistantFragmentDialog?.dismiss()
.subscribeOn(Schedulers.io()) consultAssistantDialogFromMine?.dismiss()
.observeOn(AndroidSchedulers.mainThread()) }
.subscribe { when (origin) {
if (it.data) { "home_index" -> {
if (origin == "home_index") {
showFromYdlHome(activity) showFromYdlHome(activity)
} else if (origin == "doctor_list") { }
"doctor_list" -> {
show(activity, origin, fromActivity) show(activity, origin, fromActivity)
} else if (origin == "mine_index") {
showFromMine(activity)
} }
"mine_index" -> {
showFromMine(activity)
} }
} }
} }
...@@ -109,7 +113,7 @@ class ConsultAssistantDialogUtils private constructor() { ...@@ -109,7 +113,7 @@ class ConsultAssistantDialogUtils private constructor() {
/** /**
* 首页页展示 * 首页页展示
*/ */
fun showFromYdlHome(activity: Activity) { private fun showFromYdlHome(activity: Activity) {
if (!activity.isFinishing) { if (!activity.isFinishing) {
if (consultAssistantDialogFromHomePage == null) { if (consultAssistantDialogFromHomePage == null) {
consultAssistantDialogFromHomePage = ConsultAssistantDialog( consultAssistantDialogFromHomePage = ConsultAssistantDialog(
...@@ -268,7 +272,7 @@ class ConsultAssistantDialogUtils private constructor() { ...@@ -268,7 +272,7 @@ class ConsultAssistantDialogUtils private constructor() {
/** /**
* 咨询师列表页展示浮层 * 咨询师列表页展示浮层
*/ */
fun showDialog(origin: String, activity: Activity, fromActivity: Boolean = false) { private fun showDialog(origin: String, activity: Activity, fromActivity: Boolean = false) {
if (!fromActivity) { if (!fromActivity) {
if (!activity.isFinishing) { if (!activity.isFinishing) {
if (consultAssistantFragmentDialog == null) { if (consultAssistantFragmentDialog == null) {
......
/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
*
* 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.yidianling.consultant.preview;
import android.annotation.TargetApi;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.view.MotionEvent;
import android.view.View;
/**
* @author rainb
*/
public class Compat {
private static final int SIXTY_FPS_INTERVAL = 1000 / 60;
public static void postOnAnimation(View view, Runnable runnable) {
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
postOnAnimationJellyBean(view, runnable);
} else {
view.postDelayed(runnable, SIXTY_FPS_INTERVAL);
}
}
@TargetApi(16)
private static void postOnAnimationJellyBean(View view, Runnable runnable) {
view.postOnAnimation(runnable);
}
public static int getPointerIndex(int action) {
if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB)
return getPointerIndexHoneyComb(action);
else
return getPointerIndexEclair(action);
}
@SuppressWarnings("deprecation")
@TargetApi(VERSION_CODES.ECLAIR)
private static int getPointerIndexEclair(int action) {
return (action & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
}
@TargetApi(VERSION_CODES.HONEYCOMB)
private static int getPointerIndexHoneyComb(int action) {
return (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
}
}
/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
*
* 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.yidianling.consultant.preview;
import android.content.Context;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
/**
* @author rainb
*/
public class CupcakeGestureDetector implements GestureDetector {
protected OnGestureListener mListener;
private static final String LOG_TAG = "CupcakeGestureDetector";
float mLastTouchX;
float mLastTouchY;
final float mTouchSlop;
final float mMinimumVelocity;
@Override
public void setOnGestureListener(OnGestureListener listener) {
this.mListener = listener;
}
public CupcakeGestureDetector(Context context) {
final ViewConfiguration configuration = ViewConfiguration
.get(context);
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
mTouchSlop = configuration.getScaledTouchSlop();
}
private VelocityTracker mVelocityTracker;
private boolean mIsDragging;
float getActiveX(MotionEvent ev) {
return ev.getX();
}
float getActiveY(MotionEvent ev) {
return ev.getY();
}
@Override
public boolean isScaling() {
return false;
}
@Override
public boolean isDragging() {
return mIsDragging;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
mVelocityTracker = VelocityTracker.obtain();
if (null != mVelocityTracker) {
mVelocityTracker.addMovement(ev);
} else {
Log.i(LOG_TAG, "Velocity tracker is null");
}
mLastTouchX = getActiveX(ev);
mLastTouchY = getActiveY(ev);
mIsDragging = false;
break;
}
case MotionEvent.ACTION_MOVE: {
final float x = getActiveX(ev);
final float y = getActiveY(ev);
final float dx = x - mLastTouchX, dy = y - mLastTouchY;
if (!mIsDragging) {
// Use Pythagoras to see if drag length is larger than
// touch slop
mIsDragging = Math.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;
}
if (mIsDragging) {
mListener.onDrag(dx, dy);
mLastTouchX = x;
mLastTouchY = y;
if (null != mVelocityTracker) {
mVelocityTracker.addMovement(ev);
}
}
break;
}
case MotionEvent.ACTION_CANCEL: {
// Recycle Velocity Tracker
if (null != mVelocityTracker) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
case MotionEvent.ACTION_UP: {
if (mIsDragging) {
if (null != mVelocityTracker) {
mLastTouchX = getActiveX(ev);
mLastTouchY = getActiveY(ev);
// Compute velocity within the last 1000ms
mVelocityTracker.addMovement(ev);
mVelocityTracker.computeCurrentVelocity(1000);
final float vX = mVelocityTracker.getXVelocity(), vY = mVelocityTracker
.getYVelocity();
// If the velocity is greater than minVelocity, call
// listener
if (Math.max(Math.abs(vX), Math.abs(vY)) >= mMinimumVelocity) {
mListener.onFling(mLastTouchX, mLastTouchY, -vX,
-vY);
}
}
}
// Recycle Velocity Tracker
if (null != mVelocityTracker) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
}
return true;
}
}
package com.yidianling.consultant.preview;
import android.graphics.RectF;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.ImageView;
/**
* @author rainb
*/
public class DefaultOnDoubleTapListener implements GestureDetector.OnDoubleTapListener {
private PhotoViewAttacher photoViewAttacher;
/**
* Default constructor
*
* @param photoViewAttacher PhotoViewAttacher to bind to
*/
public DefaultOnDoubleTapListener(PhotoViewAttacher photoViewAttacher) {
setPhotoViewAttacher(photoViewAttacher);
}
/**
* Allows to change PhotoViewAttacher within range of single instance
*
* @param newPhotoViewAttacher PhotoViewAttacher to bind to
*/
public void setPhotoViewAttacher(PhotoViewAttacher newPhotoViewAttacher) {
this.photoViewAttacher = newPhotoViewAttacher;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (this.photoViewAttacher == null) {
return false;
}
ImageView imageView = photoViewAttacher.getImageView();
if (null != photoViewAttacher.getOnPhotoTapListener()) {
final RectF displayRect = photoViewAttacher.getDisplayRect();
if (null != displayRect) {
final float x = e.getX(), y = e.getY();
// Check to see if the user tapped on the photo
if (displayRect.contains(x, y)) {
float xResult = (x - displayRect.left)
/ displayRect.width();
float yResult = (y - displayRect.top)
/ displayRect.height();
photoViewAttacher.getOnPhotoTapListener().onPhotoTap(imageView, xResult, yResult);
return true;
} else {
photoViewAttacher.getOnPhotoTapListener().onOutsidePhotoTap();
}
}
}
if (null != photoViewAttacher.getOnViewTapListener()) {
photoViewAttacher.getOnViewTapListener().onViewTap(imageView, e.getX(), e.getY());
}
return false;
}
@Override
public boolean onDoubleTap(MotionEvent ev) {
if (photoViewAttacher == null) {
return false;
}
try {
float scale = photoViewAttacher.getScale();
float x = ev.getX();
float y = ev.getY();
if (scale < photoViewAttacher.getMediumScale()) {
photoViewAttacher.setScale(photoViewAttacher.getMediumScale(), x, y, true);
} else if (scale >= photoViewAttacher.getMediumScale() && scale < photoViewAttacher.getMaximumScale()) {
photoViewAttacher.setScale(photoViewAttacher.getMaximumScale(), x, y, true);
} else {
photoViewAttacher.setScale(photoViewAttacher.getMinimumScale(), x, y, true);
}
} catch (ArrayIndexOutOfBoundsException e) {
// Can sometimes happen when getX() and getY() is called
}
return true;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
// Wait for the confirmed onDoubleTap() instead
return false;
}
}
/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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.yidianling.consultant.preview;
import android.annotation.TargetApi;
import android.content.Context;
import android.view.MotionEvent;
/**
* @author rainb
*/
@TargetApi(5)
public class EclairGestureDetector extends CupcakeGestureDetector {
private static final int INVALID_POINTER_ID = -1;
private int mActivePointerId = INVALID_POINTER_ID;
private int mActivePointerIndex = 0;
public EclairGestureDetector(Context context) {
super(context);
}
@Override
float getActiveX(MotionEvent ev) {
try {
return ev.getX(mActivePointerIndex);
} catch (Exception e) {
return ev.getX();
}
}
@Override
float getActiveY(MotionEvent ev) {
try {
return ev.getY(mActivePointerIndex);
} catch (Exception e) {
return ev.getY();
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = ev.getPointerId(0);
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
mActivePointerId = INVALID_POINTER_ID;
break;
case MotionEvent.ACTION_POINTER_UP:
// Ignore deprecation, ACTION_POINTER_ID_MASK and
// ACTION_POINTER_ID_SHIFT has same value and are deprecated
// You can have either deprecation or lint target api warning
final int pointerIndex = Compat.getPointerIndex(ev.getAction());
final int pointerId = ev.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = ev.getPointerId(newPointerIndex);
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
}
break;
}
mActivePointerIndex = ev
.findPointerIndex(mActivePointerId != INVALID_POINTER_ID ? mActivePointerId
: 0);
try {
return super.onTouchEvent(ev);
} catch (IllegalArgumentException e) {
// Fix for support lib bug, happening when onDestroy is
return true;
}
}
}
/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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.yidianling.consultant.preview;
import android.annotation.TargetApi;
import android.content.Context;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
/**
* @author rainb
*/
@TargetApi(8)
public class FroyoGestureDetector extends EclairGestureDetector {
protected final ScaleGestureDetector mDetector;
public FroyoGestureDetector(Context context) {
super(context);
ScaleGestureDetector.OnScaleGestureListener mScaleListener = new ScaleGestureDetector.OnScaleGestureListener() {
@Override
public boolean onScale(ScaleGestureDetector detector) {
float scaleFactor = detector.getScaleFactor();
if (Float.isNaN(scaleFactor) || Float.isInfinite(scaleFactor)) {
return false;
}
mListener.onScale(scaleFactor,
detector.getFocusX(), detector.getFocusY());
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
// NO-OP
}
};
mDetector = new ScaleGestureDetector(context, mScaleListener);
}
@Override
public boolean isScaling() {
return mDetector.isInProgress();
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
try {
mDetector.onTouchEvent(ev);
return super.onTouchEvent(ev);
} catch (IllegalArgumentException e) {
// Fix for support lib bug, happening when onDestroy is
return true;
}
}
}
package com.yidianling.consultant.preview;
import android.app.Activity;
import android.content.Intent;
import android.os.Parcelable;
import androidx.fragment.app.Fragment;
import java.util.ArrayList;
import java.util.List;
/**
* @author rainb
*/
public class GPreviewBuilder {
private Activity mContext;
private Intent intent;
private Class className;
private GPreviewBuilder(Activity activity) {
mContext = activity;
intent = new Intent();
}
public static GPreviewBuilder form(Activity activity) {
return new GPreviewBuilder(activity);
}
public static GPreviewBuilder from(Fragment fragment) {
return new GPreviewBuilder(fragment.getActivity());
}
/***
* 设置数据源
* @param imgUrls 数据
*@param <T> 你的实体类类型
* @return GPreviewBuilder
* **/
public <T extends IThumbViewInfo> GPreviewBuilder setData(List<T> imgUrls) {
intent.putParcelableArrayListExtra("imagePaths", new ArrayList<Parcelable>(imgUrls));
return this;
}
/***
* 设置默认索引
* @param currentIndex 数据
* @return GPreviewBuilder
* **/
public GPreviewBuilder setCurrentIndex(int currentIndex) {
intent.putExtra("position", currentIndex);
return this;
}
/***
* 设置指示器类型
* @param indicatorType 枚举
* @return GPreviewBuilder
* **/
public GPreviewBuilder setType(IndicatorType indicatorType) {
intent.putExtra("type", indicatorType);
return this;
}
public void start() {
if (className == null) {
intent.setClass(mContext, GPreviewActivity.class);
} else {
intent.setClass(mContext, className);
}
mContext.startActivity(intent);
mContext.overridePendingTransition(0, 0);
intent = null;
mContext = null;
}
public GPreviewBuilder setFullscreen(boolean isFullscreen) {
intent.putExtra("isFullscreen", isFullscreen);
return this;
}
public GPreviewBuilder setToUid(String toUid){
intent.putExtra("toUid", toUid);
return this;
}
public GPreviewBuilder setDoctorId(String doctorId){
intent.putExtra("doctorId", doctorId);
return this;
}
/***
* 指示器类型
* ***/
public enum IndicatorType {
Dot, Number
}
}
/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
*
* 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.yidianling.consultant.preview;
import android.view.MotionEvent;
/**
* @author rainb
*/
public interface GestureDetector {
boolean onTouchEvent(MotionEvent ev);
boolean isScaling();
boolean isDragging();
void setOnGestureListener(OnGestureListener listener);
}
/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
*
* 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.yidianling.consultant.preview;
import android.annotation.TargetApi;
import android.content.Context;
import android.widget.OverScroller;
/**
* @author rainb
*/
@TargetApi(9)
public class GingerScroller extends ScrollerProxy {
protected final OverScroller mScroller;
public GingerScroller(Context context) {
mScroller = new OverScroller(context);
}
@Override
public boolean computeScrollOffset() {
return mScroller.computeScrollOffset();
}
@Override
public void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY,
int overX, int overY) {
mScroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY, overX, overY);
}
@Override
public void forceFinished(boolean finished) {
mScroller.forceFinished(finished);
}
@Override
public boolean isFinished() {
return mScroller.isFinished();
}
@Override
public int getCurrX() {
return mScroller.getCurrX();
}
@Override
public int getCurrY() {
return mScroller.getCurrY();
}
}
\ No newline at end of file
package com.yidianling.consultant.preview;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import com.blankj.utilcode.util.ScreenUtils;
import com.bumptech.glide.Glide;
import com.ydl.ydlcommon.base.BaseActivity;
import com.ydl.ydlcommon.bean.StatusBarOptions;
import com.yidianling.consultant.R;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author fq
*/
public class GridPreviewActivity extends BaseActivity {
private ArrayList<UserViewInfo> mThumbViewInfoList = new ArrayList<>();
MyListAdapter adapter;
private GridView gridView;
@NotNull
@Override
public StatusBarOptions getStatusViewOptions() {
return new StatusBarOptions(true, true);
}
/**
* 查找信息
* 从第一个完整可见item逆序遍历,如果初始位置为0,则不执行方法内循环
*/
private void computeBoundsBackward(int firstCompletelyVisiblePos) {
for (int i = firstCompletelyVisiblePos; i < mThumbViewInfoList.size(); i++) {
View itemView = gridView.getChildAt(i - firstCompletelyVisiblePos);
Rect bounds = new Rect();
bounds.left = ScreenUtils.getScreenWidth() / 2;
bounds.top = ScreenUtils.getScreenHeight() / 2;
bounds.right = ScreenUtils.getScreenWidth() / 2;
bounds.bottom = ScreenUtils.getScreenHeight() / 2;
// if (itemView != null) {
// ImageView thumbView = (ImageView) itemView.findViewById(R.id.iv);
// thumbView.getGlobalVisibleRect(bounds);
// }
mThumbViewInfoList.get(i).setBounds(bounds);
}
}
@Override
protected int layoutResId() {
return R.layout.consultant_picture_preview;
}
@Override
protected void initDataAndEvent() {
gridView = findViewById(R.id.grid_view);
List<String> urls = ImageUrlConfig.getUrls();
for (int i = 0; i < urls.size(); i++) {
mThumbViewInfoList.add(new UserViewInfo(urls.get(i)));
}
// mThumbViewInfoList.add(4, new UserViewInfo("https://pic.ydlcdn.com/GGyHyDwKJ8.MP4", null));
adapter = new MyListAdapter();
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
computeBoundsBackward(gridView.getFirstVisiblePosition());
GPreviewBuilder.form(GridPreviewActivity.this)
.setData(mThumbViewInfoList)
.setCurrentIndex(position)
.setFullscreen(true)
.setType(GPreviewBuilder.IndicatorType.Dot)
.start();
}
});
}
private class MyListAdapter extends BaseAdapter {
@Override
public int getCount() {
return mThumbViewInfoList.size();
}
@Override
public Object getItem(int position) {
return mThumbViewInfoList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = getLayoutInflater().inflate(R.layout.consultant_item_image, null);
ImageView iv = (ImageView) view.findViewById(R.id.iv);
Glide.with(GridPreviewActivity.this)
.load(mThumbViewInfoList.get(position).getUrl())
.into(iv);
iv.setTag(R.id.iv, mThumbViewInfoList.get(position));
return view;
}
}
}
/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
*
* 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.yidianling.consultant.preview;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.view.GestureDetector;
import android.view.View;
import android.widget.ImageView;
/**
* @author rainb
*/
public interface IPhotoView {
float DEFAULT_MAX_SCALE = 3.0f;
float DEFAULT_MID_SCALE = 1.75f;
float DEFAULT_MIN_SCALE = 1.0f;
int DEFAULT_ZOOM_DURATION = 200;
/**
* Returns true if the PhotoView is set to allow zooming of Photos.
*
* @return true if the PhotoView allows zooming.
*/
boolean canZoom();
/**
* Gets the Display Rectangle of the currently displayed Drawable. The Rectangle is relative to
* this View and includes all scaling and translations.
*
* @return - RectF of Displayed Drawable
*/
RectF getDisplayRect();
/**
* Sets the Display Matrix of the currently displayed Drawable. The Rectangle is considered
* relative to this View and includes all scaling and translations.
*
* @param finalMatrix target matrix to set PhotoView to
* @return - true if rectangle was applied successfully
*/
boolean setDisplayMatrix(Matrix finalMatrix);
/**
* Copies the Display Matrix of the currently displayed Drawable. The Rectangle is considered
* relative to this View and includes all scaling and translations.
*
* @param matrix target matrix to copy to
*/
void getDisplayMatrix(Matrix matrix);
/**
* @return The current minimum scale level. What this value represents depends on the current
* {@link ImageView.ScaleType}.
*/
float getMinimumScale();
/**
* @return The current medium scale level. What this value represents depends on the current
* {@link ImageView.ScaleType}.
*/
float getMediumScale();
/**
* @return The current maximum scale level. What this value represents depends on the current
* {@link ImageView.ScaleType}.
*/
float getMaximumScale();
/**
* Returns the current scale value
*
* @return float - current scale value
*/
float getScale();
/**
* Return the current scale type in use by the ImageView.
*
* @return current ImageView.ScaleType
*/
ImageView.ScaleType getScaleType();
/**
* Whether to allow the ImageView's parent to intercept the touch event when the photo is scroll
* to it's horizontal edge.
*
* @param allow whether to allow intercepting by parent element or not
*/
void setAllowParentInterceptOnEdge(boolean allow);
/**
* Sets the minimum scale level. What this value represents depends on the current {@link
* ImageView.ScaleType}.
*
* @param minimumScale minimum allowed scale
*/
void setMinimumScale(float minimumScale);
/**
* Sets the medium scale level. What this value represents depends on the current {@link ImageView.ScaleType}.
*
* @param mediumScale medium scale preset
*/
void setMediumScale(float mediumScale);
/**
* Sets the maximum scale level. What this value represents depends on the current {@link
* ImageView.ScaleType}.
*
* @param maximumScale maximum allowed scale preset
*/
void setMaximumScale(float maximumScale);
/**
* Allows to set all three scale levels at once, so you don't run into problem with setting
* medium/minimum scale before the maximum one
*
* @param minimumScale minimum allowed scale
* @param mediumScale medium allowed scale
* @param maximumScale maximum allowed scale preset
*/
void setScaleLevels(float minimumScale, float mediumScale, float maximumScale);
/**
* Register a callback to be invoked when the Photo displayed by this view is long-pressed.
*
* @param listener - Listener to be registered.
*/
void setOnLongClickListener(View.OnLongClickListener listener);
/**
* Register a callback to be invoked when the Matrix has changed for this View. An example would
* be the user panning or scaling the Photo.
*
* @param listener - Listener to be registered.
*/
void setOnMatrixChangeListener(PhotoViewAttacher.OnMatrixChangedListener listener);
/**
* Register a callback to be invoked when the Photo displayed by this View is tapped with a
* single tap.
*
* @param listener - Listener to be registered.
*/
void setOnPhotoTapListener(PhotoViewAttacher.OnPhotoTapListener listener);
/**
* Register a callback to be invoked when the View is tapped with a single tap.
*
* @param listener - Listener to be registered.
*/
void setOnViewTapListener(PhotoViewAttacher.OnViewTapListener listener);
/**
* Enables rotation via PhotoView internal functions.
*
* @param rotationDegree - Degree to rotate PhotoView to, should be in range 0 to 360
*/
void setRotationTo(float rotationDegree);
/**
* Enables rotation via PhotoView internal functions.
*
* @param rotationDegree - Degree to rotate PhotoView by, should be in range 0 to 360
*/
void setRotationBy(float rotationDegree);
/**
* Changes the current scale to the specified value.
*
* @param scale - Value to scale to
*/
void setScale(float scale);
/**
* Changes the current scale to the specified value.
*
* @param scale - Value to scale to
* @param animate - Whether to animate the scale
*/
void setScale(float scale, boolean animate);
/**
* Changes the current scale to the specified value, around the given focal point.
*
* @param scale - Value to scale to
* @param focalX - X Focus Point
* @param focalY - Y Focus Point
* @param animate - Whether to animate the scale
*/
void setScale(float scale, float focalX, float focalY, boolean animate);
/**
* Controls how the image should be resized or moved to match the size of the ImageView. Any
* scaling or panning will happen within the confines of this {@link
* ImageView.ScaleType}.
*
* @param scaleType - The desired scaling mode.
*/
void setScaleType(ImageView.ScaleType scaleType);
/**
* Allows you to enable/disable the zoom functionality on the ImageView. When disable the
* ImageView reverts to using the FIT_CENTER matrix.
*
* @param zoomable - Whether the zoom functionality is enabled.
*/
void setZoomable(boolean zoomable);
/**
* Extracts currently visible area to Bitmap object, if there is no image loaded yet or the
* ImageView is already destroyed, returns {@code null}
*
* @return currently visible area as bitmap or null
*/
Bitmap getVisibleRectangleBitmap();
/**
* Allows to change zoom transition speed, default value is 200 (PhotoViewAttacher.DEFAULT_ZOOM_DURATION).
* Will default to 200 if provided negative value
*
* @param milliseconds duration of zoom interpolation
*/
void setZoomTransitionDuration(int milliseconds);
/**
* Will return instance of IPhotoView (eg. PhotoViewAttacher), can be used to provide better
* integration
*
* @return IPhotoView implementation instance if available, null if not
*/
IPhotoView getIPhotoViewImplementation();
/**
* Sets custom double tap listener, to intercept default given functions. To reset behavior to
* default, you can just pass in "null" or public field of PhotoViewAttacher.defaultOnDoubleTapListener
*
* @param newOnDoubleTapListener custom OnDoubleTapListener to be set on ImageView
*/
void setOnDoubleTapListener(GestureDetector.OnDoubleTapListener newOnDoubleTapListener);
/**
* Will report back about scale changes
*
* @param onScaleChangeListener OnScaleChangeListener instance
*/
void setOnScaleChangeListener(PhotoViewAttacher.OnScaleChangeListener onScaleChangeListener);
/**
* Will report back about fling(single touch)
*
* @param onSingleFlingListener OnSingleFlingListener instance
*/
void setOnSingleFlingListener(PhotoViewAttacher.OnSingleFlingListener onSingleFlingListener);
}
package com.yidianling.consultant.preview;
import android.graphics.Rect;
import android.os.Parcelable;
/**
* Deprecated: 图片预览接口
*
* @author rainb
*/
public interface IThumbViewInfo extends Parcelable {
/****
* 图片地址
* @return String
* ****/
String getUrl();
/**
* 记录坐标
*
* @return Rect
***/
Rect getBounds();
/**
* 获取视频链接
***/
String getCover();
int getSourcesType();
}
package com.yidianling.consultant.preview;
import android.content.Context;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
/**
* Deprecated: 加载器接口
*
* @author rainb
*/
public interface IZoomMediaLoader {
/***
* @param context 容器
* @param path 图片你的路径
* @param simpleTarget 图片加载状态回调
* ***/
void displayImage(@NonNull Fragment context, @NonNull String path, ImageView imageView, @NonNull MySimpleTarget simpleTarget);
/***
* 加载gif 图
* @param context 容器
* @param path 图片你的路径
* @param simpleTarget 图片加载状态回调
* ***/
void displayGifImage(@NonNull Fragment context, @NonNull String path, ImageView imageView, @NonNull MySimpleTarget simpleTarget);
/**
* 停止
*
* @param context 容器
**/
void onStop(@NonNull Fragment context);
/**
* 停止
*
* @param c 容器
**/
void clearMemory(@NonNull Context c);
}
/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
*
* 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.yidianling.consultant.preview;
import android.annotation.TargetApi;
import android.content.Context;
/**
* @author rainb
*/
@TargetApi(14)
public class IcsScroller extends GingerScroller {
public IcsScroller(Context context) {
super(context);
}
@Override
public boolean computeScrollOffset() {
return mScroller.computeScrollOffset();
}
}
package com.yidianling.consultant.preview;
import android.graphics.drawable.Drawable;
import androidx.annotation.Nullable;
/**
* Deprecated: 图片加载回调状态接口
*
* @author rainb
*/
public interface MySimpleTarget {
/**
* Callback when an image has been successfully loaded.
* <p>
* <strong>Note:</strong> You must not recycle the bitmap.
*/
void onResourceReady();
/**
* Callback indicating the image could not be successfully loaded.
*
* @param errorRes 内容
*/
void onLoadFailed(@Nullable Drawable errorRes);
}
/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
*
* 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.yidianling.consultant.preview;
/**
* @author rainb
*/
public interface OnGestureListener {
void onDrag(float dx, float dy);
void onFling(float startX, float startY, float velocityX,
float velocityY);
void onScale(float scaleFactor, float focusX, float focusY);
}
\ No newline at end of file
/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
*
* 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.yidianling.consultant.preview;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.GestureDetector;
public class PhotoView extends androidx.appcompat.widget.AppCompatImageView implements IPhotoView {
private PhotoViewAttacher mAttacher;
private ScaleType mPendingScaleType;
public PhotoView(Context context) {
this(context, null);
}
public PhotoView(Context context, AttributeSet attr) {
this(context, attr, 0);
}
public PhotoView(Context context, AttributeSet attr, int defStyle) {
super(context, attr, defStyle);
super.setScaleType(ScaleType.MATRIX);
init();
}
protected void init() {
if (null == mAttacher || null == mAttacher.getImageView()) {
mAttacher = new PhotoViewAttacher(this);
}
if (null != mPendingScaleType) {
setScaleType(mPendingScaleType);
mPendingScaleType = null;
}
}
@Override
public void setRotationTo(float rotationDegree) {
mAttacher.setRotationTo(rotationDegree);
}
@Override
public void setRotationBy(float rotationDegree) {
mAttacher.setRotationBy(rotationDegree);
}
@Override
public boolean canZoom() {
return mAttacher.canZoom();
}
@Override
public RectF getDisplayRect() {
return mAttacher.getDisplayRect();
}
@Override
public void getDisplayMatrix(Matrix matrix) {
mAttacher.getDisplayMatrix(matrix);
}
@Override
public boolean setDisplayMatrix(Matrix finalRectangle) {
return mAttacher.setDisplayMatrix(finalRectangle);
}
@Override
public float getMinimumScale() {
return mAttacher.getMinimumScale();
}
@Override
public float getMediumScale() {
return mAttacher.getMediumScale();
}
@Override
public float getMaximumScale() {
return mAttacher.getMaximumScale();
}
@Override
public float getScale() {
return mAttacher.getScale();
}
@Override
public ScaleType getScaleType() {
return mAttacher.getScaleType();
}
@Override
public Matrix getImageMatrix() {
return mAttacher.getImageMatrix();
}
@Override
public void setAllowParentInterceptOnEdge(boolean allow) {
mAttacher.setAllowParentInterceptOnEdge(allow);
}
@Override
public void setMinimumScale(float minimumScale) {
mAttacher.setMinimumScale(minimumScale);
}
@Override
public void setMediumScale(float mediumScale) {
mAttacher.setMediumScale(mediumScale);
}
@Override
public void setMaximumScale(float maximumScale) {
mAttacher.setMaximumScale(maximumScale);
}
@Override
public void setScaleLevels(float minimumScale, float mediumScale, float maximumScale) {
mAttacher.setScaleLevels(minimumScale, mediumScale, maximumScale);
}
@Override
// setImageBitmap calls through to this method
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
if (null != mAttacher) {
mAttacher.update();
}
}
@Override
public void setImageResource(int resId) {
super.setImageResource(resId);
if (null != mAttacher) {
mAttacher.update();
}
}
@Override
public void setImageURI(Uri uri) {
super.setImageURI(uri);
if (null != mAttacher) {
mAttacher.update();
}
}
@Override
protected boolean setFrame(int l, int t, int r, int b) {
boolean changed = super.setFrame(l, t, r, b);
if (null != mAttacher) {
mAttacher.update();
}
return changed;
}
@Override
public void setOnMatrixChangeListener(PhotoViewAttacher.OnMatrixChangedListener listener) {
mAttacher.setOnMatrixChangeListener(listener);
}
@Override
public void setOnLongClickListener(OnLongClickListener l) {
mAttacher.setOnLongClickListener(l);
}
@Override
public void setOnPhotoTapListener(PhotoViewAttacher.OnPhotoTapListener listener) {
mAttacher.setOnPhotoTapListener(listener);
}
@Override
public void setOnViewTapListener(PhotoViewAttacher.OnViewTapListener listener) {
mAttacher.setOnViewTapListener(listener);
}
@Override
public void setScale(float scale) {
mAttacher.setScale(scale);
}
@Override
public void setScale(float scale, boolean animate) {
mAttacher.setScale(scale, animate);
}
@Override
public void setScale(float scale, float focalX, float focalY, boolean animate) {
mAttacher.setScale(scale, focalX, focalY, animate);
}
@Override
public void setScaleType(ScaleType scaleType) {
if (null != mAttacher) {
mAttacher.setScaleType(scaleType);
} else {
mPendingScaleType = scaleType;
}
}
@Override
public void setZoomable(boolean zoomable) {
mAttacher.setZoomable(zoomable);
}
@Override
public Bitmap getVisibleRectangleBitmap() {
return mAttacher.getVisibleRectangleBitmap();
}
@Override
public void setZoomTransitionDuration(int milliseconds) {
mAttacher.setZoomTransitionDuration(milliseconds);
}
@Override
public IPhotoView getIPhotoViewImplementation() {
return mAttacher;
}
@Override
public void setOnDoubleTapListener(GestureDetector.OnDoubleTapListener newOnDoubleTapListener) {
mAttacher.setOnDoubleTapListener(newOnDoubleTapListener);
}
@Override
public void setOnScaleChangeListener(PhotoViewAttacher.OnScaleChangeListener onScaleChangeListener) {
mAttacher.setOnScaleChangeListener(onScaleChangeListener);
}
@Override
public void setOnSingleFlingListener(PhotoViewAttacher.OnSingleFlingListener onSingleFlingListener) {
mAttacher.setOnSingleFlingListener(onSingleFlingListener);
}
@Override
protected void onDetachedFromWindow() {
mAttacher.cleanup();
mAttacher.resetMatrix();
mAttacher = null;
super.onDetachedFromWindow();
}
@Override
protected void onAttachedToWindow() {
init();
super.onAttachedToWindow();
}
public void resetMatrix() {
if (mAttacher != null) {
mAttacher.cleanup();
mAttacher.resetMatrix();
}
}
}
package com.yidianling.consultant.preview;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import androidx.viewpager.widget.ViewPager;
/**
* Issues With ViewGroups
*
* @author rainb
*/
public class PhotoViewPager extends ViewPager {
public PhotoViewPager(Context context) {
super(context);
}
public PhotoViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
try {
return super.onInterceptTouchEvent(ev);
} catch (IllegalArgumentException e) {
e.printStackTrace();
return false;
}
}
}
/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
*
* 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.yidianling.consultant.preview;
import android.content.Context;
import android.widget.Scroller;
/**
* @author rainb
*/
public class PreGingerScroller extends ScrollerProxy {
private final Scroller mScroller;
public PreGingerScroller(Context context) {
mScroller = new Scroller(context);
}
@Override
public boolean computeScrollOffset() {
return mScroller.computeScrollOffset();
}
@Override
public void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY,
int overX, int overY) {
mScroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY);
}
@Override
public void forceFinished(boolean finished) {
mScroller.forceFinished(finished);
}
@Override
public boolean isFinished() {
return mScroller.isFinished();
}
@Override
public int getCurrX() {
return mScroller.getCurrX();
}
@Override
public int getCurrY() {
return mScroller.getCurrY();
}
}
\ No newline at end of file
/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
*
* 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.yidianling.consultant.preview;
import android.content.Context;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
/**
* @author rainb
*/
public abstract class ScrollerProxy {
public static ScrollerProxy getScroller(Context context) {
if (VERSION.SDK_INT < VERSION_CODES.GINGERBREAD) {
return new PreGingerScroller(context);
} else if (VERSION.SDK_INT < VERSION_CODES.ICE_CREAM_SANDWICH) {
return new GingerScroller(context);
} else {
return new IcsScroller(context);
}
}
public abstract boolean computeScrollOffset();
public abstract void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY,
int maxY, int overX, int overY);
public abstract void forceFinished(boolean finished);
public abstract boolean isFinished();
public abstract int getCurrX();
public abstract int getCurrY();
}
package com.yidianling.consultant.preview;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.yidianling.consultant.R;
import org.jetbrains.annotations.NotNull;
/**
* @author rainb
*/
public class TestImageLoader implements IZoomMediaLoader {
@Override
public void displayImage(@NonNull Fragment context, @NonNull String path, final ImageView imageView, @NonNull final MySimpleTarget simpleTarget) {
Glide.with(context).asBitmap().load(path).placeholder(R.drawable.consultant_bg_black).error(R.drawable.consultant_bg_black)
// .placeholder(android.R.color.darker_gray)
.fitCenter()
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull @NotNull Bitmap resource, @Nullable @org.jetbrains.annotations.Nullable Transition<? super Bitmap> transition) {
simpleTarget.onResourceReady();
imageView.setImageBitmap(resource);
}
@Override
public void onLoadFailed(@Nullable @org.jetbrains.annotations.Nullable Drawable errorDrawable) {
simpleTarget.onLoadFailed(errorDrawable);
imageView.setImageDrawable(errorDrawable);
}
});
}
@Override
public void displayGifImage(@NonNull Fragment context, @NonNull String path, ImageView imageView, @NonNull final MySimpleTarget simpleTarget) {
}
@Override
public void onStop(@NonNull Fragment context) {
Glide.with(context).onStop();
}
@Override
public void clearMemory(@NonNull Context c) {
Glide.get(c).clearMemory();
}
}
package com.yidianling.consultant.preview;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Deprecated: 图片预览实体类
*
* @author rainb
*/
public class UserViewInfo implements IThumbViewInfo {
private String url; //图片地址
private Rect mBounds; // 记录坐标
private int sourcesType;
private String cover;
public UserViewInfo(String url) {
this.url = url;
}
public UserViewInfo(String cover, String url, int sourcesType) {
this.url = url;
this.cover = cover;
this.sourcesType = sourcesType;
}
@Override
public String getUrl() {//将你的图片地址字段返回
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public Rect getBounds() {//将你的图片显示坐标字段返回
return mBounds;
}
@Override
public String getCover() {
return cover;
}
@Override
public int getSourcesType() {
return sourcesType;
}
public void setBounds(Rect bounds) {
mBounds = bounds;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.url);
dest.writeParcelable(this.mBounds, flags);
dest.writeString(this.cover);
dest.writeInt(this.sourcesType);
}
protected UserViewInfo(Parcel in) {
this.url = in.readString();
this.mBounds = in.readParcelable(Rect.class.getClassLoader());
this.cover = in.readString();
this.sourcesType = in.readInt();
}
public static final Parcelable.Creator<UserViewInfo> CREATOR = new Parcelable.Creator<UserViewInfo>() {
@Override
public UserViewInfo createFromParcel(Parcel source) {
return new UserViewInfo(source);
}
@Override
public UserViewInfo[] newArray(int size) {
return new UserViewInfo[size];
}
};
}
package com.yidianling.consultant.preview;
/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
*
* 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.
*******************************************************************************/
import android.content.Context;
import android.os.Build;
/**
* @author rainb
*/
public final class VersionedGestureDetector {
public static GestureDetector newInstance(Context context,
OnGestureListener listener) {
final int sdkVersion = Build.VERSION.SDK_INT;
GestureDetector detector;
if (sdkVersion < Build.VERSION_CODES.ECLAIR) {
detector = new CupcakeGestureDetector(context);
} else if (sdkVersion < Build.VERSION_CODES.FROYO) {
detector = new EclairGestureDetector(context);
} else {
detector = new FroyoGestureDetector(context);
}
detector.setOnGestureListener(listener);
return detector;
}
}
\ No newline at end of file
package com.yidianling.consultant.preview;
/**
* Deprecated: 图片加载管理器
*
* @author rainb
*/
public class ZoomMediaLoader {
private volatile IZoomMediaLoader loader;
public static ZoomMediaLoader getInstance() {
return Holder.holder;
}
private ZoomMediaLoader() {
}
private static class Holder {
static ZoomMediaLoader holder = new ZoomMediaLoader();
}
/****
* 初始化加载图片类
* @param loader 自定义
* **/
public void init(IZoomMediaLoader loader) {
this.loader = loader;
}
public IZoomMediaLoader getLoader() {
if (loader == null) {
throw new NullPointerException("ZoomMediaLoader loader no init");
}
return loader;
}
}
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="MissingDefaultResource">
<corners android:radius="@dimen/platform_dp_23" />
<gradient
android:endColor="#48CC95"
android:startColor="#61CEAC" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="MissingDefaultResource">
<corners android:radius="@dimen/platform_dp_23" />
<gradient
android:endColor="#4BAFEC"
android:startColor="#65C4FF" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:shape="oval"
tools:ignore="MissingDefaultResource">
<solid android:color="#FF6565" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/platform_dp_8"/>
<solid android:color="#40000000"/>
</shape>
\ No newline at end of file
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment