Commit 856dea64 by 刘鹏

Merge branch 'd/v4.0.57_xlzx' into 'release'

D/v4.0.57

See merge request app_android_lib/YDL-Component!364
parents 08dfa5d3 d17f193b
......@@ -14,7 +14,7 @@ buildscript {
ydlrouter_version = '1.2.3'
constrait_support_version = '1.0.2'
componentVersion = "0.3.0.48"
componentVersion = "0.3.0.49.3-SNAPSHOT"
}
repositories {
mavenCentral()
......
......@@ -164,7 +164,7 @@ ext {
"blankUtil" : "com.blankj:utilcode:1.25.9",
"ydl-hnet" : "com.ydl:h-net:0.0.8",
"ydl-user-router" : "com.ydl:router:1.0.0-SNAPSHOT@aar",
"ydl-device" : "com.ydl:device-id:0.0.35",
"ydl-device" : "com.ydl:device-id:0.0.36",
//flutter功能组件升级===>发布ydl-flutter组件===>引用flutter相关的业务模块
"ydl-flutter" : "com.ydl:ydl-flutter:0.0.57@aar", //flutter aar
// "ydl-flutter-sp" : "com.ydl:ydl-flutter-sp:0.0.2@aar", //flutter 缓存 aar
......
......@@ -65,7 +65,7 @@ dependencies {
kapt "com.alibaba:arouter-compiler:$arouter_compiler"
api "com.alibaba:arouter-api:$arouter_api"
api "com.ydl:ydl-av:1.4.8"
api "com.ydl:ydl-av:1.4.9"
implementation 'com.volcengine:apm_insight:1.4.6.cn'
api project(':ydl-platform')
......
......@@ -341,7 +341,7 @@ class AudioHomeActivity :
}
Apm.reportEvent("agora_android", "occur_error", "$err")
AudioApiRequestUtil.reportCallEvent(channelId, RtcEvent(RtcEvent.Event.errorOccurred), errorCode = err)
channelId?.let { YDLavManager.instances.callEndStatusUpdate(it, 60, "频道错误回调$err") }
// channelId?.let { YDLavManager.instances.callEndStatusUpdate(it, 60, "频道错误回调$err") }
}
override fun onApiCallExecuted(error: Int, api: String?, result: String?) {
......
......@@ -2,18 +2,14 @@ package com.ydl.audioim
import android.app.Activity
import android.content.Context
import android.text.TextUtils
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.tencent.mmkv.MMKV
import com.ydl.audioim.http.AudioApiRequestUtil
import com.ydl.audioim.http.RtcEvent
import com.ydl.consultantim.ConsultantAudioHomeActivity
import com.ydl.ydl_av.voice.listener.RtcNetInterface
import com.ydl.ydl_av.voice.manager.YDLVoiceManager
import com.ydl.ydlcommon.utils.log.XLog
import io.agora.rtc.Constants
import io.reactivex.Single
import io.reactivex.schedulers.Schedulers
import java.io.File
......@@ -94,13 +90,13 @@ class NetQuality(
override fun onRemoteAudioStateChanged(uid: Int, state: Int, reason: Int, elapsed: Int) {
XLog.i("NetQuality", "uid:$uid,state:$state,reason:$reason,elapsed:$elapsed")
if (reason == Constants.REMOTE_AUDIO_REASON_NETWORK_CONGESTION && state == Constants.REMOTE_AUDIO_STATE_FROZEN) {
/*if (reason == Constants.REMOTE_AUDIO_REASON_NETWORK_CONGESTION && state == Constants.REMOTE_AUDIO_STATE_FROZEN) {
val qualityValue = MMKV.defaultMMKV().getString("network_quality_config", "0")
if (TextUtils.equals(qualityValue, "1")) {
if (System.currentTimeMillis() - lastOnRemoteNetworkCongestion > 30 * 1000) {
if (System.currentTimeMillis() - lastOnRemoteNetworkCongestion > 2 * 60 * 1000) {
lastOnRemoteNetworkCongestion = System.currentTimeMillis()
voiceManage?.getVoiceApi()
?.playEffect(3001, getNetLowEffect(activity))
?.playEffect(3001, getNetLowEffect(activity), 50.0)
}
if (activity is AudioHomeActivity) {
activity.showNetStatus("对方的网络状况不佳", 0)
......@@ -108,7 +104,7 @@ class NetQuality(
activity.showNetStatus("对方的网络状况不佳", 0)
}
}
}
}*/
}
override fun onRemoteAudioStats(quality: Int, delay: Int, bitrate: Int, audioLossRate: Int) {
......
......@@ -184,20 +184,6 @@ class YDLavManager {
)
onConfideEvent(dimension, response?.ChannelId)
val act = ActivityManager.getInstance().getTopTaskActivity()
//专家离线或者30 秒后仍未收到专家响应,重新再邀请一次
when (errorCode) {
//被叫不在线 呼叫邀请发出 30 秒后被叫仍未 ACK 响应呼叫邀请
RtmStatusCode.LocalInvitationError.LOCAL_INVITATION_ERR_PEER_OFFLINE, RtmStatusCode.LocalInvitationError.LOCAL_INVITATION_ERR_PEER_NO_RESPONSE -> {
if (act is AudioHomeActivity) {
act.runOnUiThread {
act.rtcCall()
}
}
}
RtmStatusCode.LocalInvitationError.LOCAL_INVITATION_ERR_INVITATION_EXPIRE -> {
//呼叫邀请过期。被叫 ACK 响应呼叫邀请后 60 秒呼叫邀请未被取消、接受、拒绝,则呼叫邀请过期。
}
}
//呼叫失败日志输出
if (act is AudioHomeActivity) {
act.runOnUiThread {
......
......@@ -395,9 +395,11 @@ class ConsultantAudioHomeActivity :
//110:生成的 Token 无效
//123:此用户被服务器禁止
runOnUiThread {
var report = false
when (err) {
3, 7, 109, 110 -> {
showToast("请退出应用,重新打开")
report = true
close(RESULT_NOT_ANSWERED_CODE, "咨询师已挂断")
callEventSave(
"80",
......@@ -408,17 +410,20 @@ class ConsultantAudioHomeActivity :
10 -> {
callEventSave("80", "err:${err} 专家网络较差")
showToast("当前网络较差,请更换网络")
report = true
close(RESULT_NOT_ANSWERED_CODE, "专家网络较差")
}
101 -> {
callEventSave("80", "err:${err} 不是有效的 APP ID")
showToast("安装包有问题,请联系技术")
report = true
close(RESULT_NOT_ANSWERED_CODE, "安装包有问题,请联系技术")
}
102 -> {
callEventSave("80", "err:${err} 不是有效的 频道名")
showToast("频道错误,请联系技术")
report = true
close(RESULT_NOT_ANSWERED_CODE, "频道错误,请联系技术")
}
123 -> {
......@@ -433,6 +438,7 @@ class ConsultantAudioHomeActivity :
if (err == 0 || err == 18) {
return@runOnUiThread
}
if (report) {
YDLavManager.instances.callEndStatusUpdate(
mAudioMessageBean?.channelId!!,
60,
......@@ -440,6 +446,7 @@ class ConsultantAudioHomeActivity :
)
}
}
}
//本地音频状态监听
override fun onLocalAudioStateChanged(localVideoState: Int, error: Int) {
......
......@@ -9,7 +9,6 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Typeface
import android.os.Bundle
import android.os.Handler
import android.text.TextUtils
import android.view.View
......@@ -1800,7 +1799,7 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
tv.setCompoundDrawablesWithIntrinsicBounds(
0,
0,
R.drawable.platform_ic_arrow_drop_down_grey_500_18dp,
R.drawable.consult_ic_arrow_drwn_gray,
0
)
}
......@@ -1810,7 +1809,7 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
tv.setCompoundDrawablesWithIntrinsicBounds(
0,
0,
R.drawable.platform_arrow_drop_down_en,
R.drawable.consult_ic_arrow_drwn_en,
0
)
}
......@@ -1820,7 +1819,7 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
tv.setCompoundDrawablesWithIntrinsicBounds(
0,
0,
R.drawable.platform_arrow_drop_down_en,
R.drawable.consult_ic_arrow_drwn_en,
0
)
}
......@@ -1836,7 +1835,7 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
tv.setCompoundDrawablesWithIntrinsicBounds(
0,
0,
R.drawable.filter_up_grey,
R.drawable.filter_up_gray,
0
)
}
......
......@@ -6,9 +6,7 @@ import android.animation.ObjectAnimator
import android.animation.PropertyValuesHolder
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.graphics.Typeface
import android.net.Uri
import android.os.Handler
import android.text.TextUtils
import android.view.View
......@@ -31,9 +29,7 @@ import com.ydl.ydl_image.config.SimpleImageOpConfiger
import com.ydl.ydl_image.listener.YDLImageRecyclerOnScrollListener
import com.ydl.ydl_image.manager.YDLImageCacheManager
import com.ydl.ydlcommon.base.BaseMvpFragment
import com.ydl.ydlcommon.base.config.ChannelConfig
import com.ydl.ydlcommon.base.config.HttpConfig
import com.ydl.ydlcommon.data.PlatformDataManager
import com.ydl.ydlcommon.modular.findRouteService
import com.ydl.ydlcommon.ui.LogoLoadingView
import com.ydl.ydlcommon.utils.BuryPointUtils
......@@ -54,12 +50,8 @@ import com.yidianling.consultant.constants.ConsultBIConstants
import com.yidianling.consultant.constants.ConsultBIConstants.ConsultEvent.Companion.PRICE_TYPE_CLICK
import com.yidianling.consultant.constants.ConsultBIConstants.ConsultantLocationAuth.Companion.REFUSE_ALREADY
import com.yidianling.consultant.constants.ConsultBIConstants.ConsultantLocationAuth.Companion.WHETHER_LOCATION_AUTH
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.listener.*
import com.yidianling.consultant.model.SearchApi
import com.yidianling.consultant.model.bean.*
import com.yidianling.consultant.modular.singlton.ConsultAssistantDialogUtils
......@@ -501,21 +493,21 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
textView.setOnClickListener {
if (textView.isSelected) {
dealHotSelect(hot, false)
textView!!.isSelected = false
textView.paint.isFakeBoldText = false
textView.isSelected = false
} else {
dealHotSelect(hot, true)
textView.isSelected = true
textView.paint.isFakeBoldText = true
// 埋点
hot.value?.let { it1 ->
ActionCountUtils.baiDuCountSign3(
ConsultBIConstants.PART_ID_CONSULT_COUNSELOR_LIST_PAGE,
ConsultBIConstants.ConsultEvent.POSITION_CHOICE_FILTER_CLICK,
hot.value!!,
it1,
"app",
""
)
}
}
filterLabelSet()
//开始筛选数据
refresh()
......@@ -1611,12 +1603,12 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
private fun updateFilterTextViewStatus(tv: TextView, status: Int) {
when (status) {
FILTER_STATUS_NORMAL -> {
tv.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
tv.setTextColor(ContextCompat.getColor(mContext, R.color.platform_colorTextDefault))
tv.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
tv.setTextColor(ContextCompat.getColor(mContext, R.color.platform_color_242424))
tv.setCompoundDrawablesWithIntrinsicBounds(
0,
0,
R.drawable.platform_ic_arrow_drop_down_grey_500_18dp,
R.drawable.consult_ic_arrow_drwn_gray,
0
)
}
......@@ -1626,7 +1618,7 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
tv.setCompoundDrawablesWithIntrinsicBounds(
0,
0,
R.drawable.platform_arrow_drop_down_en,
R.drawable.consult_ic_arrow_drwn_en,
0
)
}
......@@ -1636,7 +1628,7 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
tv.setCompoundDrawablesWithIntrinsicBounds(
0,
0,
R.drawable.platform_arrow_drop_down_en,
R.drawable.consult_ic_arrow_drwn_en,
0
)
}
......@@ -1647,12 +1639,12 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
private fun updateFilterRightTextViewStatus(tv: TextView, status: Int) {
when (status) {
FILTER_STATUS_NORMAL -> {
tv.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
tv.setTextColor(ContextCompat.getColor(mContext, R.color.platform_colorTextDefault))
tv.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
tv.setTextColor(ContextCompat.getColor(mContext, R.color.platform_color_242424))
tv.setCompoundDrawablesWithIntrinsicBounds(
0,
0,
R.drawable.filter_up_grey,
R.drawable.filter_up_gray,
0
)
}
......
......@@ -8,7 +8,6 @@ import com.ydl.ydlcommon.data.http.RxUtils
import com.ydl.ydlcommon.data.http.ThrowableConsumer
import com.ydl.ydlcommon.modular.ModularServiceManager
import com.ydl.ydlcommon.mvp.base.SimplePresenter
import com.ydl.ydlcommon.utils.AnimUtils
import com.ydl.ydlcommon.utils.RxLifecycleUtils
import com.ydl.ydlcommon.utils.remind.HttpErrorUtils
import com.yidianling.common.tools.RxAppTool
......@@ -266,15 +265,28 @@ class ExpertSearchPresenter : SimplePresenter<IExpertSearchView>() {
fieldsMap["is_free_today"] = true
fieldsMap["display_region"] = true
fieldsMap["has_servicefree_experience"] = true
//专家头像下方文案:如 忙碌;现在有空;今日可约;最近可约;已约满;休息中
fieldsMap["consult_display_status_str"] = true
//咨询显示状态:1.忙碌;2.现在有空;3.今日可约;4.最近可约;5.已约满;6.休息中
fieldsMap["consult_display_status"] = true
//私聊下方时间描述:如 最快可约今天19:00
fieldsMap["today_time_des"] = true
//服务方式:如 当面/视频
fieldsMap["attr_combine"] = true
//是否开启代聊:1开启,2关闭
fieldsMap["open_chat_agency"] = true
//年审
fieldsMap["audit_tag"] = true
map["fields"] = fieldsMap
val optionsMap = HashMap<String, Any?>()
optionsMap["search_scene_id"] = "doctor_main_search"
optionsMap["uid"] = ModularServiceManager.provide(IUserService::class.java).getUserInfo()?.uid
optionsMap["uid"] =
ModularServiceManager.provide(IUserService::class.java).getUserInfo()?.uid
optionsMap["ffrom"] = PlatformDataManager.getRam().getChannelName()
optionsMap["version"]= RxAppTool.getAppVersionName(BaseApp.getApp())
optionsMap["os_type"]= 2
if (extras!=null){
optionsMap["version"] = RxAppTool.getAppVersionName(BaseApp.getApp())
optionsMap["os_type"] = 2
if (extras != null) {
optionsMap["extras"] = extras
}
map["options"] = optionsMap
......
package com.yidianling.consultant.model.bean
import com.yidianling.consultant.bean.ExpertSearchProductsBean
import com.yidianling.consultant.bean.ExpertSearchTagsIconBean
/**
* @author yuanWai
* @描述:
......@@ -23,153 +20,97 @@ data class ExpertServiceItem(
* 专家名称
*/
val doctor_name: String?,
/**
* 跳转路由地址(正常为专家主页地址)
*/
/*** 跳转路由地址(正常为专家主页地址)*/
val link_url: String?,
/**
* 专家头像地址
*/
/*** 专家头像地址*/
val head: String?,
/**
* 专家是否在线 1.在线
*/
/*** 私聊状态:1.上线;2.离线;3.忙碌中*/
val chat_status: Int?,
/**
* 能力等级 1.实习 2.新手 3.精英
*/
val abilityLevel: Int?,
/**
* 有免费咨询:1.有,2.无
*/
val has_servicefree_consult: Int?,
/**
* 活动图标
*/
val activityImg: String?,
/**
* 是否参加活动
*/
val joinActivity: Boolean?,
/**
* 是否新入驻:true:是,false:否
*/
var is_new_enter: Boolean?,
/**
* 好评率(倾诉+咨询)
*/
var evaluation_average_score: Float = 0f,
/**
* 是否抗疫先锋图标
*/
var fightEpidemicIconShow: Boolean = false,
/**
* 评价数(咨询订单数)
*/
/*** 评价数(咨询订单数)*/
var evaluate_num: Int = 0,
/**
* 咨询最低价
*/
/*** 咨询最低价*/
val min_price: String?,
/**
* 资质材料
*/
/*** 资质材料*/
val title: String?,
/**
* 已帮助人数(咨询人数)
*/
val help_num: String?,
/**
* 月售时长
*/
var p30d_sold_hour: Float = 0f,
/**
* 服务时长
*/
/*** 服务时长*/
var sum_service_time: Float = 0f,
/**
* 服务
*/
val doctor_products: MutableList<ExpertSearchProductsBean>?,
/**
* 标签图片
*/
val icons: ExpertSearchTagsIconBean?,
// /**
// * 今日是否可约
// */
// val booking_status: Int,
// /**
// * 咨询状态 1-待服务 2-服务中
// */
// var consult_status: Int,
// /**
// * 倾诉状态 1-待服务 2-服务中
// */
// var listen_status: Int,
var open_chat_agency: Int,
/***服务状态:1.空闲,2.忙碌*/
var service_status: Int,
var is_free_today: Int,
/**
* 私聊人数
*/
/*** 私聊人数*/
var chat_num: Int = 0,
/**
* 个人铭言
*/
val famous_remark: String?,
/**
* 省
*/
val province: String?,
/**
* 市
*/
val city: String?,
/**
* 私聊按钮的文案(如果不为空则取这个字段的值,如果为空 则默认为:“私聊”)
*/
/*** 私聊按钮的文案(如果不为空则取这个字段的值,如果为空 则默认为:“私聊”)*/
val chat_btn_text: String?,
/**
* 新标签分类
*/
/*** 新标签分类*/
val feature_tags: ArrayList<FeatureTag>?,
/**
* 是否是头部headView
*/
/*** 是否是头部headView*/
val is_head_view: Boolean = false,
/**
* 搜索词
*/
/*** 搜索词*/
val search_content: String,
/**
* 联想词
*/
/*** 联想词*/
val related_word: String,
/**
* 地区
*/
/*** 地区*/
val display_region: String,
/**
* 是否展示公益图标
*/
val has_servicefree_experience: Int?
/***咨询显示状态:1.忙碌;2.现在有空;3.今日可约;4.最近可约;5.已约满;6.休息中*/
val consult_display_status: Int,
/***专家头像下方文案:如 忙碌;现在有空;今日可约;最近可约;已约满;休息中*/
val consult_display_status_str: String,
/***私聊下方时间描述:如 最快可约今天19:00*/
val today_time_des: String,
/***服务方式:如 当面/视频*/
val attr_combine: String = "",
/***0:关闭代聊,1:开启代聊*/
val open_chat_agency: Int,
/***年审*/
val audit_tag: String,
) {
) {
constructor(is_head_view: Boolean, search_content: String, related_word: String) : this(
"", "", "", "", "",
1, 1, 1, "", false, true,
1f, false, 0, "", "", "", 1f, 1f,
null, null, 1, 1, 1, 1,
"", "", "", "", null, is_head_view, search_content, related_word, "", 1
id = "",
uid = "",
doctor_name = "",
link_url = "",
head = "",
chat_status = 1,
evaluate_num = 0,
min_price = "",
title = "",
sum_service_time = 0f,
service_status = 1,
chat_num = 0,
chat_btn_text = null,
feature_tags = null,
is_head_view = is_head_view,
search_content = search_content,
related_word = related_word,
display_region = "",
consult_display_status = 2,
consult_display_status_str = "",
today_time_des = "",
attr_combine = "",
open_chat_agency = 0,
audit_tag = ""
)
}
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="1dp"/>
<corners android:radius="4dp" />
<solid android:color="@color/color_1AEB892C" />
<stroke android:width="0.5dp" android:color="@color/color_EB892C"/>
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="1dp"/>
<corners android:radius="4dp" />
<solid android:color="@color/platform_white" />
<stroke android:width="0.5dp" android:color="@color/platform_color_E0E0E0"/>
<stroke
android:width="0.5dp"
android:color="@color/color_1c1f28_10" />
</shape>
\ No newline at end of file
......@@ -4,9 +4,9 @@
<shape android:shape="rectangle">
<solid android:color="@color/platform_main_theme_bright" />
<corners android:radius="11dp"/>
<stroke
<!--<stroke
android:width="0.5dp"
android:color="@color/platform_main_theme"/>
android:color="@color/platform_main_theme"/>-->
</shape>
</item>
<item android:state_enabled="true">
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/color_f6f6f7" />
<corners android:radius="2dp" />
<padding
android:bottom="2dp"
android:left="4dp"
android:right="4dp"
android:top="1.5dp" />
</shape>
\ No newline at end of file
......@@ -4,10 +4,13 @@
android:id="@+id/tvTag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:background="@drawable/consultant_bg_radius_line_gray_1"
android:gravity="center"
android:layout_marginEnd="6dp"
android:padding="3dp"
android:textColor="@color/platform_color_666666"
android:textSize="10sp"
android:paddingLeft="4dp"
android:paddingTop="2dp"
android:paddingRight="4dp"
android:paddingBottom="3dp"
android:textColor="@color/color_1c1f28_50"
android:textSize="11dp"
tools:text="恋爱情感" />
......@@ -3,7 +3,6 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:background="@color/platform_white"
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
......@@ -29,12 +28,14 @@
android:id="@+id/tvSubject"
style="@style/consultant_FilterTextViewStyle"
android:layout_width="0dp"
android:drawablePadding="4dp"
android:layout_weight="1"
android:width="0dp"
android:ellipsize="end"
android:textStyle="bold"
android:singleLine="true"
android:drawableEnd="@drawable/platform_ic_arrow_drop_down_grey_500_18dp"
android:drawableRight="@drawable/platform_ic_arrow_drop_down_grey_500_18dp"
android:drawableEnd="@drawable/consult_ic_arrow_drwn_gray"
android:drawableRight="@drawable/consult_ic_arrow_drwn_gray"
android:text="困扰"
android:textColor="@color/platform_color_242424" />
......@@ -44,8 +45,10 @@
android:layout_width="0dp"
android:layout_weight="1"
android:width="0dp"
android:drawableEnd="@drawable/platform_ic_arrow_drop_down_grey_500_18dp"
android:drawableRight="@drawable/platform_ic_arrow_drop_down_grey_500_18dp"
android:textStyle="bold"
android:drawablePadding="4dp"
android:drawableEnd="@drawable/consult_ic_arrow_drwn_gray"
android:drawableRight="@drawable/consult_ic_arrow_drwn_gray"
android:text="城市"
android:textColor="@color/platform_color_242424" />
......@@ -55,8 +58,10 @@
android:layout_width="0dp"
android:layout_weight="1"
android:width="0dp"
android:drawableEnd="@drawable/platform_ic_arrow_drop_down_grey_500_18dp"
android:drawableRight="@drawable/platform_ic_arrow_drop_down_grey_500_18dp"
android:textStyle="bold"
android:drawablePadding="4dp"
android:drawableEnd="@drawable/consult_ic_arrow_drwn_gray"
android:drawableRight="@drawable/consult_ic_arrow_drwn_gray"
android:text="价格"
android:textColor="@color/platform_color_242424" />
......@@ -66,8 +71,10 @@
android:layout_width="0dp"
android:layout_weight="1"
android:width="0dp"
android:drawableEnd="@drawable/filter_up_grey"
android:drawableRight="@drawable/filter_up_grey"
android:textStyle="bold"
android:drawablePadding="4dp"
android:drawableEnd="@drawable/filter_up_gray"
android:drawableRight="@drawable/filter_up_gray"
android:text="@string/platform_filter"
android:textColor="@color/platform_color_242424" />
</LinearLayout>
......
......@@ -26,5 +26,18 @@
<color name="consultant_colorBg">#f5f5f5</color>
<color name="color_EB892C">#EB892C</color>
<color name="color_1AEB892C">#1AEB892C</color>
<color name="color_1c1f28_60">#a61c1f28</color>
<color name="color_1c1f28_50">#801c1f28</color>
<color name="color_1c1f28_40">#661c1f28</color>
<color name="color_1c1f28_20">#331c1f28</color>
<color name="color_1c1f28_10">#1a1c1f28</color>
<color name="color_ef8a4a">#EF8A4A</color>
<color name="color_f6f6f7">#f6f6f7</color>
<color name="color_6ec8f9">#6ec8f9</color>
<color name="color_6ec8f9_90">#E66ec8f9</color>
<color name="color_b6bece">#B6BECE</color>
<color name="color_b6bece_90">#E6B6BECE</color>
<color name="color_f5a082">#F5A082</color>
<color name="color_f5a082_90">#E6F5A082</color>
<color name="color_f28e6b">#F28E6B</color>
</resources>
......@@ -27,7 +27,6 @@ android {
versionName "1.0"
multiDexEnabled true
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
flavorDimensions "versionCode"
vectorDrawables.useSupportLibrary = true
}
......@@ -49,7 +48,9 @@ android {
ydl {}
xlzx {}
}
dataBinding {
enabled true
}
sourceSets {
main {
res.srcDirs = ['src/main/res']
......
package com.yidianling.home.model.bean
import com.google.gson.annotations.SerializedName
import com.yidianling.consultant.bean.Keyworks
import java.io.Serializable
......@@ -18,14 +17,8 @@ class HomeHeaderBean : HomeItemBaseBean {
var activityResponse: ActivityResponse? = null
/**
* 分类数据
*/
var askCategoryData: MutableList<AskCategoryDataBean>? = null
/**
* 新版分类数据
*/
var goldList: MutableList<CategoryGoldListDataBean>? = null
/**
......@@ -73,28 +66,6 @@ class HomeHeaderBean : HomeItemBaseBean {
var goCriteriaMap: HashMap<String, Any>? = null
) : Serializable
class AskCategoryDataBean {
/**
* id
*/
var cateId: Int = 0
/**
* 名称
*/
var cateTitle: String? = null //
/**
* 跳转url
*/
var url: String? = null
/**
* 图片icon
*/
var coverUrl: String? = null
}
class FocusListBean {
/**
* 标题
......
package com.yidianling.home.ui.transform;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import androidx.annotation.NonNull;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import java.security.MessageDigest;
import jp.wasabeef.glide.transformations.BitmapTransformation;
public class CircleCropTransform extends BitmapTransformation {
private final Paint mBorderPaint;
private final float mBorderSize;
public CircleCropTransform() {
this(0, Color.TRANSPARENT);
}
@Override
protected Bitmap transform(@NonNull Context context, @NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
return circleCrop(pool, toTransform);
}
/**
* @param borderSize 边框宽度(px)
* @param borderColor 边框颜色
*/
public CircleCropTransform(float borderSize, int borderColor) {
this(TypedValue.COMPLEX_UNIT_PX, borderSize, borderColor);
}
/**
* @param unit borderSize 单位
* @param borderSize 边框宽度(px)
* @param borderColor 边框颜色
*/
public CircleCropTransform(int unit, float borderSize, int borderColor) {
DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
mBorderSize = TypedValue.applyDimension(unit, borderSize, displayMetrics);
mBorderPaint = new Paint();
mBorderPaint.setDither(true);
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(borderColor);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setStrokeWidth(mBorderSize);
}
private Bitmap circleCrop(BitmapPool pool, Bitmap source) {
if (source == null) return null;
int size = (int) (Math.min(source.getWidth(), source.getHeight()) - (mBorderSize / 2));
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
if (mBorderPaint != null) {
float borderRadius = r - mBorderSize / 2;
canvas.drawCircle(r, r, borderRadius, mBorderPaint);
}
return result;
}
@Override
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
}
@Override
public boolean equals(Object o) {
return false;
}
@Override
public int hashCode() {
return 0;
}
}
package com.yidianling.home.ui.view
import android.content.Context
import android.view.View
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.yidianling.home.R
import com.yidianling.home.databinding.HomeButtonBannerViewBinding
import com.yidianling.home.event.IHomeBaseEvent
import com.yidianling.home.model.bean.HomeHeaderBean
import kotlinx.android.synthetic.xlzx.home_button_banner_view.view.*
/**
* @author <a href="https://www.jianshu.com/u/c1e5310dd724">xujian</a>
......@@ -21,6 +20,7 @@ import kotlinx.android.synthetic.xlzx.home_button_banner_view.view.*
*/
class HomeButtonBannerView(private val mContext: Context, private var homeEvent: IHomeBaseEvent?) :
LinearLayout(mContext) {
private var dataBinding: HomeButtonBannerViewBinding? = null
init {
initView()
......@@ -32,33 +32,37 @@ class HomeButtonBannerView(private val mContext: Context, private var homeEvent:
ViewGroup.LayoutParams.WRAP_CONTENT
)
layoutParams = params
View.inflate(mContext, R.layout.home_button_banner_view, this)
dataBinding = DataBindingUtil.inflate(
LayoutInflater.from(mContext),
R.layout.home_button_banner_view,
this,
true
)
Glide.with(context)
.load(R.drawable.qingsu_new_free_dynamic)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.into(qingsuGif)
homeModuleButtonBannerFirst.setOnClickListener {
dataBinding?.homeModuleButtonBannerFirst?.setOnClickListener {
homeEvent?.reservationExpertsClick()
}
homeModuleButtonBannerSecond.setOnClickListener {
homeEvent?.askMoreClick()
}
homeModuleButtonBannerThird.setOnClickListener {
dataBinding?.homeModuleButtonBannerSecond?.setOnClickListener {
homeEvent?.nowConfideClick(false)
}
homeModuleButtonBannerFourth.setOnClickListener {
dataBinding?.homeModuleButtonBannerThird?.setOnClickListener {
homeEvent?.psychologyClassClick()
}
dataBinding?.homeModuleButtonBannerFourth?.setOnClickListener {
homeEvent?.psychologyTestClick()
}
dataBinding?.loopAvatar?.stopLoop()
dataBinding?.loopAvatar?.startLoop()
}
fun initData(
homeCategory: List<HomeHeaderBean.CategoryGoldListDataBean>?
) {
homeEvent?.let { home_category_view.setEvent(it) }
home_category_view.initData(homeCategory)
homeEvent?.let { dataBinding?.homeCategoryView?.setEvent(it) }
dataBinding?.homeCategoryView?.initData(homeCategory)
}
}
\ No newline at end of file
package com.yidianling.home.ui.view
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.os.Handler
import android.os.Message
import android.util.AttributeSet
import android.util.Log
import android.widget.ImageView
import android.widget.RelativeLayout
import com.blankj.utilcode.util.SizeUtils
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.home.R
import com.yidianling.home.ui.transform.CircleCropTransform
import java.lang.ref.WeakReference
const val START_AVATAR_LOOP = 111
class LoopScrollAvatar @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr) {
//动画播放时长
private val animDuration = 500L
//动画间隔播放时间
private val animIntervalTime = 1500L
//两边头像的缩放程度
private val scaleFrom = 0.7F
//头像大小
private val avatarSize = SizeUtils.dp2px(18F)
//从当前位置滚动到下一位置需要移动的距离
private var scrollLength = 0F
//下次要显示的图片角标
private var index = 0
private val res =
arrayOf(
R.mipmap.home_banner_header1,
R.mipmap.home_banner_header2,
R.mipmap.home_banner_header3,
R.mipmap.home_banner_header4,
R.mipmap.home_banner_header5
)
//缓存复用ImageView
private val ivCache = mutableListOf(
createImageView(),
createImageView(),
createImageView(),
createImageView()
)
private val handler by lazy {
LoopHandler(this)
}
init {
//前三位的头像先addView显示出来
//放左边
addImageView(ALIGN_PARENT_LEFT)
//放中间
addImageView(CENTER_HORIZONTAL)
//默认放右边
addImageView()
}
class LoopHandler() : Handler() {
private var lWeak: WeakReference<LoopScrollAvatar>? = null
constructor(loopScrollAvatar: LoopScrollAvatar) : this() {
lWeak = WeakReference(loopScrollAvatar)
}
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
lWeak?.get()?.apply {
if ((context as? Activity)?.isDestroyed == false) {
startAnimMove()
sendLoopMsg()
}
}
}
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
scrollLength = (width - avatarSize) / 2F
}
/**
* 创建圆形头像ImageView
*/
private fun createImageView(): ImageView {
return ImageView(context)
}
/**
* 摆放头像ImageView
*/
private fun addImageView(rule: Int = ALIGN_PARENT_RIGHT) {
//复用缓存
val iv = if (ivCache.size > 0) {
ivCache[0]
} else {
createImageView()
}
//当前已在屏幕显示的控件不要复用,防止params混乱
ivCache.remove(iv)
//图片资源全部播放完之后要从头重播
index = (index + 1) % res.size
//设置在RelativeLayout中的显示位置
val lp = LayoutParams(avatarSize, avatarSize)
lp.addRule(rule)
iv.layoutParams = lp
addView(iv)
//圆角带描边
GlideApp.with(this).load(res[index]).transform(CircleCropTransform(1f, Color.WHITE))
.into(iv)
}
/**
* 轮播滚动动效
*/
private fun startAnimMove() {
//添加一个即将从右边移进屏幕的ImageView
addImageView()
//上行代码刚添加进来的最右边头像(此时RelativeLayout的mChildrenCount=4)
getChildAt(3)?.apply {
//设置起始的低透明度 和 小size
alpha = 0.6F
scaleX = scaleFrom
scaleY = scaleFrom
//先设置左边部分向左移出控件,即挡住左边不显示(然后才能translationXBy移进屏幕)
translationX = scrollLength
//translationXBy指的是从当前位置开始移动多少距离(区别于translationX)
//alpha是从当前透明度(即0.6F)变为设置的透明度(即1F)
//scaleX是从当前宽度比例(即scaleFrom)变为设置的宽度比例(即1F)
animate().translationXBy(-scrollLength).alpha(1F).scaleX(1F).scaleY(1F)
.setDuration(animDuration).start()
}
//中间俩头像只需设置平移的距离即可
getChildAt(1)?.apply {
animate().translationXBy(-scrollLength).setDuration(animDuration).start()
}
//设置平移的距离
getChildAt(2)?.apply {
animate().translationXBy(-scrollLength).setDuration(animDuration).start()
}
//最左边的头像(从完整显示 到 透明度和大小都变小,并且左移出屏幕)(因为是最先add进来的View,所以index=0)
getChildAt(0)?.let { iv ->
iv.animate().translationXBy(0f).alpha(0F).scaleX(scaleFrom).scaleY(scaleFrom)
.setDuration(animDuration)
.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
super.onAnimationEnd(animation)
//清除ImageView已有属性,并添加进ivCache缓存
iv.animate().setListener(null)
iv.clearAnimation()
iv.translationX = 0F
iv.scaleX = 1.0F
iv.scaleY = 1.0F
iv.alpha = 1F
//从RelativeLayout移出
removeView(iv)
ivCache.add(0, iv as ImageView)
try {
if ((context as Activity).isFinishing) {
stopLoop()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}).start()
}
}
private fun sendLoopMsg() {
handler.sendEmptyMessageDelayed(START_AVATAR_LOOP, animIntervalTime + animDuration)
}
private var looping = false
/**
* 开始轮播
*/
fun startLoop() {
if (looping) {
Log.e("startLoop", "startLoop cannot be called twice")
}
looping = true
sendLoopMsg()
}
/**
* 停止轮播
*/
fun stopLoop() {
looping = false
handler.removeCallbacksAndMessages(null)
}
}
\ No newline at end of file
......@@ -23,9 +23,6 @@ class HomeCategoryAdapter : PagerAdapter {
private var mContext : Context? = null
private var mHomeEvent : IHomeBaseEvent? = null
//源数据
private var mOriginList: MutableList<HomeHeaderBean.AskCategoryDataBean>? = null
//数据
private var list: MutableList<MutableList<HomeHeaderBean.CategoryGoldListDataBean>>? = null
......
......@@ -550,9 +550,10 @@ object IMChatUtil {
val status = chatStatusBean.data.status
actionHandler.setDoctorStatus(status)
actionHandler.setDoctorBusyNum(chatStatusBean.data.busyTotal)
//1.在线,2.离线,3.忙碌 4咨询中, 5倾述中 6咨询前准备
if (status == 2) { //离线
tb.setMinTitleText("离线")
//1.在线,2.离线,3.服务中 4咨询中, 5倾述中 6咨询前准备
when (status) {
3 -> { //服务中
tb.setMinTitleText("服务中")
tb.setMinTitleColor(
ContextCompat.getColor(
context,
......@@ -562,11 +563,12 @@ object IMChatUtil {
tb.setMinTitleDrawable(
ContextCompat.getDrawable(
context,
R.drawable.im_background_chat_top_status_off_line
R.drawable.im_background_chat_top_status_online_server
)
)
} else if (status == 4 || status == 5) { //服务中
tb.setMinTitleText("服务中")
}
2 -> { //离线
tb.setMinTitleText("离线")
tb.setMinTitleColor(
ContextCompat.getColor(
context,
......@@ -576,10 +578,11 @@ object IMChatUtil {
tb.setMinTitleDrawable(
ContextCompat.getDrawable(
context,
R.drawable.im_background_chat_top_status_online_server
R.drawable.im_background_chat_top_status_off_line
)
)
} else { //在线 1,3,6..
}
else -> { //在线 1
tb.setMinTitleText("在线")
tb.setMinTitleColor(
ContextCompat.getColor(
......@@ -594,6 +597,7 @@ object IMChatUtil {
)
)
}
}
initSystemMessage(
chatStatusBean.data.promptRule,
status,
......
......@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.content.Context
import android.os.Build
import android.text.TextUtils
import android.util.Log
import com.google.gson.Gson
import com.ydl.devicesidlib.DeviceIDHelper
import com.ydl.devicesidlib.Utils
......@@ -259,14 +260,32 @@ class HttpConfig {
}
val message = originalResponse.message()
val api = request.url().encodedPath()
ActionCountUtils.baiDuCount("ydl_user_error_business","error_log",api,params,message)
ActionCountUtils.baiDuCount(
"ydl_user_error_business",
"error_log",
api,
params,
message
)
//阿里云忽略埋点接口
if (!api.contains("maidian/writeMaiDianData")){
AliYunRichLogsHelper.getInstance().sendRichLog(AliYunLogConfig.API, "error_log---api:$api---params:$params ---- message:$message")
}else{
AliYunRichLogsHelper.getInstance().sendRichLog(AliYunLogConfig.API, "writeMaiDianDataError:$api---params:$params ---- message:$message")
if (!api.contains("maidian/writeMaiDianData")) {
AliYunRichLogsHelper.getInstance().sendRichLog(
AliYunLogConfig.API,
"error_log---api:$api---params:$params ---- message:$message"
)
} else {
AliYunRichLogsHelper.getInstance().sendRichLog(
AliYunLogConfig.API,
"writeMaiDianDataError:$api---params:$params ---- message:$message"
)
}
}
} else {
Log.e(
"YDL",
"\n---------------------------------------------------------------------------\n" +
"| 请求地址:" + request.url() + " |\n--------------------------------------------------------------------------\n"
)
}
originalResponse
}
......
......@@ -13,9 +13,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/ll_share"
android:layout_marginStart="68dp"
android:layout_marginEnd="68dp"
android:layout_marginBottom="-25dp"
android:layout_marginStart="42dp"
android:layout_marginEnd="42dp"
android:clickable="true"
android:visibility="gone"
app:cardCornerRadius="10dp"
......@@ -31,7 +30,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:scaleType="fitXY"
android:scaleType="fitCenter"
tools:layout_height="100dp" />
<TextView
......
......@@ -204,7 +204,7 @@ class ShareMeditationDialog : DialogFragment() {
fun newInstance(
isDarkMode: Boolean, shareUrl: String, shareTitle: String,
shareContent: String, shareCover: String, miniId: String, miniPath: String
shareContent: String, shareCover: String, miniId: String?, miniPath: String?
): ShareMeditationDialog {
val args = Bundle()
args.putBoolean(KEY_SHARE_DARK_MODE, isDarkMode)
......
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