Commit ed3f8644 by 刘鹏

Merge branch 'release' into feat/lp/lp_sub_pay

# Conflicts:
#	m-consultant/src/main/res/values/styles.xml
parents 60b36471 e0af8ed2
......@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply from: "../../maven_push_api.gradle"
version = '1.0.2'
version = '1.0.3'
android {
compileSdkVersion rootProject.ext.android["compileSdkVersion"]
......
......@@ -23,6 +23,7 @@ interface IImService : IProvider {
// 直接打开聊天页面,不走分配导医
fun startChatBySessionId(context: Activity, toUid: String)
// 打开信息前置收集页
fun startP2PSession(context: Activity, location: Int, ffrom2: String?)
......@@ -183,4 +184,8 @@ interface IImService : IProvider {
fun initIm(app: Application, activity: Class<out Activity>, imInitBean: IMInitConfigBean)
fun isWifiOr3G(activity: Activity): Boolean
fun showConsultServiceDialog(activity: Activity, toUid: String, doctorId: String)
fun dismissConsultServiceDialog();
}
\ No newline at end of file
......@@ -23,6 +23,8 @@ import com.ydl.ydlcommon.utils.AppProgressUtils;
import com.ydl.ydlcommon.utils.Utils;
import com.yidianling.common.tools.LogUtil;
import com.yidianling.common.tools.ToastUtil;
import com.yidianling.consultant.preview.TestImageLoader;
import com.yidianling.consultant.preview.ZoomMediaLoader;
import com.yidianling.course.lifeCallback.CoursePlayLifecycle;
......@@ -48,7 +50,7 @@ public class ComponentTestApp extends BaseApp {
com.ydl.ydlcommon.utils.LogUtil.debug = BuildConfig.DEBUG;
webviewSetPath(this);
ZoomMediaLoader.getInstance().init(new TestImageLoader());
if (!BuildConfig.DEBUG && Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {//release包去除,debug包不去除,用于检测是否还有反射api的方法
//去掉在Android P上的提醒弹窗 Detected problems with API
......
......@@ -20,8 +20,8 @@ import java.util.List;
*/
public final class DemoGlobalConfig implements IConfigModule {
String APP_DOMAIN = "https://api.github.com/";
public static String appEnv = YDLConstants.ENV_TEST;
// public static String appEnv = YDLConstants.ENV_PROD;
// public static String appEnv = YDLConstants.ENV_TEST;
public static String appEnv = YDLConstants.ENV_PROD;
// public static String appEnv = YDLConstants.ENV_NEW_TEST;//配置未上传到maven库
@Override
......
......@@ -110,7 +110,7 @@ class JsMethod(private val webView: WebView?) {
if (callback.isNullOrBlank()) return true
webView?.post {
when (type) {
1 -> {//检查音频权限能力
1,2 -> {//检查音频权限能力
webView.loadUrl("javascript:$callback(1)")
}
else -> {
......
......@@ -2,8 +2,10 @@ package com.ydl.component.service.web;
import android.app.Activity;
import android.graphics.Rect;
import com.alibaba.android.arouter.launcher.ARouter;
import com.blankj.utilcode.util.ScreenUtils;
import com.ydl.confide.api.IConfideService;
import com.ydl.confide.home.event.ChangeAnotherExpertEvent;
import com.ydl.webview.H5JsBean;
......@@ -13,14 +15,20 @@ import com.ydl.ydl_router.manager.YDLRouterManager;
import com.ydl.ydl_router.manager.YDLRouterParams;
import com.ydl.ydlcommon.modular.ModularServiceManager;
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.muse.activity.ChooseMusicActivity;
//import static com.ydl.ydlcommon.router.IYDLRouterConstant.ROUTER_MUSE_PLAY;
import de.greenrobot.event.EventBus;
import com.yidianling.im.event.CloseBottomWebviewEvent;
import java.util.ArrayList;
import java.util.List;
import de.greenrobot.event.EventBus;
/**
......@@ -296,7 +304,9 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
@Override
public void shareAction(H5JsBean.H5JsCmd.Params params) {
if (mContext instanceof NewH5Activity) {
((NewH5Activity) mContext).showShareMenu(params);
}
}
@Override
......@@ -384,7 +394,7 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
@Override
public void back() {
mContext.finish();
}
@Override
......@@ -495,6 +505,39 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
}
@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,
String buried, String mediaUrl, String mediaCoverUrl,
String title, String desc, int status) {
......@@ -506,9 +549,11 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
businessType, buried, mediaUrl, mediaCoverUrl, title, desc, status);
}
}
@Override
public void chatCloseBottomWebView() {
EventBus.getDefault().post(new CloseBottomWebviewEvent(true));
ModularServiceManager.INSTANCE.provide(IImService.class).dismissConsultServiceDialog();
}
......@@ -521,8 +566,17 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
@Override
public void setWebViewBG(String rgb, String alpha) {
if (mContext instanceof NewH5Activity) {
((NewH5Activity) mContext).setBG(rgb, alpha);
}
}
@Override
public void showCommentArticleDialog(H5JsBean.H5JsCmd.Params params) {
if (mContext instanceof NewH5Activity){
((NewH5Activity)mContext).setBG(rgb, alpha);
((NewH5Activity)mContext).showCommentArticleDialog(params.getTitle());
}
}
}
......@@ -460,6 +460,20 @@ class WebJavascriptHandler(private val webView: WebView?, private val wvEnventPr
wvEnventPro?.switchPushStatus(jsData.cmd?.params)
}
"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,12 @@ public interface WebViewClientClickListener {
//h5页面是否需要打开推送
void switchPushStatus(H5JsBean.H5JsCmd.Params params);
//显示评论弹窗
void showCommentArticleDialog(H5JsBean.H5JsCmd.Params params);
void resourceToPreview(H5JsBean.H5JsCmd.Params params);
void showDocBooking(H5JsBean.H5JsCmd.Params params);
}
ext {
dev_mode = false //组件发布的时候需要设置为false
ydl2PublishVersion = "0.2.0.14"
dev_mode = false//组件发布的时候需要设置为false
ydl2PublishVersion = "0.2.0.17"
ydlPublishVersion = [
// -------------- 业务模块 --------------
//第三步 若干
......@@ -8,10 +8,10 @@ ext {
"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-home" : "0.0.24.09",
"m-im" : "0.0.21.69",
"m-dynamic" : "0.0.7.80",
"m-article" : "0.0.0.10",
"m-article" : "0.0.0.11",
"m-muse" : "0.0.28.87",
"m-tests" : "0.0.24.24",
"m-course" : "0.0.43.39",
......@@ -22,7 +22,7 @@ ext {
"ydl-platform" : "0.0.41.54",
//第二步 若干
"ydl-webview" : "0.0.39.03",
"ydl-webview" : "0.2.0.7",
"ydl-media" : "0.0.21.52",
"ydl-pay" : "0.0.18.21",
"m-audioim" : "0.0.49.30.23",
......@@ -164,7 +164,7 @@ ext {
"systembartint" : "com.readystatesoftware.systembartint:systembartint:1.0.3",
"cube" : "in.srain.cube:cube-sdk:1.0.44@aar",
"support-multidex" : 'androidx.multidex:multidex:2.0.0',
"ydl-ijkplayer-jjdxm" : "com.ydl:jjdxm-ijkplayer:0.0.33",
"ydl-ijkplayer-jjdxm" : "com.ydl:jjdxm-ijkplayer:0.0.35",
"walle" : "com.meituan.android.walle:library:1.1.5",
"jpush" : "cn.jiguang.sdk:jpush:3.3.6",
"jcore" : "cn.jiguang.sdk:jcore:2.1.4",
......@@ -229,7 +229,7 @@ ext {
"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-im-api" : "com.ydl:m-im-api:1.0.3",
"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",
......
......@@ -52,6 +52,12 @@ dependencies {
kapt 'com.alibaba:arouter-compiler:1.2.2'
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"]
if (rootProject.ext.dev_mode){
//开发时使用
......
......@@ -5,6 +5,8 @@
<application>
<activity android:name=".flutter.ArticleActivity"
android:screenOrientation="portrait"/>
<activity android:name="activity.ArticleHomeActivity"
android:screenOrientation="portrait"/>
</application>
</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
* Created by harvie on 2019/9/6.
*/
@Route(path = "/article/list")
//@Route(path = "/article/list")
class ArticleActivity : BaseFlutterActivity() {
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
......@@ -65,8 +65,9 @@ dependencies {
// 注意此处的依赖方式:kotlin中使用和java中使用方式有不同
kapt "com.alibaba:arouter-compiler:$arouter_compiler"
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"]
if (rootProject.ext.dev_mode){
//开发时使用
......
......@@ -133,13 +133,15 @@ class ConfideHomeEventImpl(context: Context, var confideHomeView: IConfideHomeCo
* @param linkUrl 跳转地址
*/
override fun consultantClick(doctorId: String?, confideId: String?, uid: String?,listenFree : Boolean?, expertUrl:String?) {
confideId?.let {
ConfideBottomSheetDialogFragment()
.showBottomSheetDialog(
mContext as FragmentActivity,
HttpConfig.MH5_URL + ConfideRoute.h5ConfideIntro(it),
doctorId!!, uid = uid, listenFree = listenFree ?: false,expertUrl = expertUrl?:""
)
doctorId?.let { doctorId ->
confideId?.let {confideId ->
ConfideBottomSheetDialogFragment()
.showBottomSheetDialog(
mContext as FragmentActivity,
HttpConfig.MH5_URL + ConfideRoute.h5ConfideIntro(confideId),
doctorId, uid = uid, listenFree = listenFree ?: false,expertUrl = expertUrl?:""
)
}
}
}
......
......@@ -433,7 +433,7 @@ internal fun VideoViewModel.mapOf(bean: ConfideHomeBodyBean): VideoViewModel {
avatar.set(bean.confidedIcon)
linkedUrl.set(bean.linkUrl)
val num = bean.confideNum?.replace("人", "") ?: "0"
count.set("倾诉人次 $num")
count.set("服务人次 $num")
intro.set(bean.confideContent)
title.set(bean.title)
val sb = StringBuilder()
......
......@@ -116,7 +116,7 @@
android:layout_height="wrap_content"
android:textSize="@dimen/platform_sp_12"
android:textColor="#69696A"
android:text="倾诉人次"
android:text="服务人次"
/>
</LinearLayout>
<LinearLayout
......
......@@ -47,6 +47,9 @@ dependencies {
kapt 'com.alibaba:arouter-compiler:1.2.2'
implementation rootProject.ext.dependencies["BaseRecyclerViewAdapterHelper"]
api rootProject.ext.dependencies["ydl-user-router"]
implementation(rootProject.ext.dependencies["ydl-ijkplayer-jjdxm"]) {
exclude group: 'com.android.support', module: 'appcompat-v7'
}
if (rootProject.ext.dev_mode){
//开发时使用
implementation project(":api:user")
......
......@@ -18,6 +18,14 @@
android:name=".ConsultAssistantCenterActivity"
android:screenOrientation="portrait"
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>
</manifest>
\ No newline at end of file
......@@ -330,9 +330,7 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
isShow = isVisibleToUser
if (isVisibleToUser && isResumed) {
startTime = System.currentTimeMillis()
showConsultAssistantDialog()
} else {
hideConsultAssistantDialog()
if (startTime != 0L) {
endTime = System.currentTimeMillis()
ActionCountUtils.count(
......
......@@ -240,6 +240,8 @@ class ExpertSearchPresenter : SimplePresenter<IExpertSearchView>() {
fieldsMap["open_chat_agency"] = true
fieldsMap["service_status"] = true
fieldsMap["is_free_today"] = true
fieldsMap["display_region"] = true
fieldsMap["has_servicefree_experience"] = true
map["fields"] = fieldsMap
val optionsMap = HashMap<String, Any?>()
......
......@@ -52,6 +52,8 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon
private var historyList: FixSizeLinkedList<String> = FixSizeLinkedList(15)
private val bannerList = ArrayList<String>()
private var lenovoResultSuccess = false // 联想结果 联想前false 联想成功后true
companion object {
private const val CACHE_CONSULT_SEARCH_HISTORY_DATA = "cache_consult_search_history_data"
private const val HOT_SEARCH_DOCTOR_NAME = "hot_search_doctor_name"
......@@ -111,7 +113,11 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon
// 搜索的关联词
var relatedWords = ""
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) {
relatedWords = searchSuggestList[0].suggest_relations[0]
isRecommendWords = true
......@@ -120,7 +126,7 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon
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))
} else {
if (etSearch.text.toString().isNullOrEmpty()) {
......@@ -231,6 +237,7 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon
*/
private fun getSearchWords(searchContent: String, isClickWords: Boolean) {
if (!TextUtils.isEmpty(searchContent)) {
lenovoResultSuccess = false
mSearchContent = searchContent
val map = HashMap<String, Any>()
map["content"] = searchContent
......@@ -245,6 +252,7 @@ class HotSearchActivity : BaseMvpActivity<IHotSearchContract.View, IHotSearchCon
searchContent: String,
isClickWords: Boolean
) {
lenovoResultSuccess = true
if (isClickWords) {
//判断 suggest_classify_types 有值则通过 jump_url跳转
// 搜索的关联词
......
......@@ -177,14 +177,14 @@ class ExpertSearchAdapter(
//省市
if (!TextUtils.isEmpty(itemBean.province)) {
holder.tvCity.text = itemBean.province + "·" + itemBean.city
if (!TextUtils.isEmpty(itemBean.display_region)) {
holder.tvCity.text = itemBean.display_region
} else {
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)) {
expertSearchView.showImage(
itemBean.icons.service_free_icon,
......
......@@ -108,11 +108,11 @@ data class ExpertServiceItem(
// */
// 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(
/**
* 是否是头部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("","","","","",
1,1,1,"",false,true,
1f,false,0,"","","",1f,1f,
null,null,1,1,1,1,
"","","","",null,is_head_view,search_content,related_word)
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
)
}
data class FeatureTag(
val tag_id:String,
val tag_name:String,
val is_highlight:Boolean, // 是否高亮
val type:String // 标签类型
val tag_id: String,
val tag_name: String,
val is_highlight: Boolean, // 是否高亮
val type: String // 标签类型
)
\ No newline at end of file
......@@ -40,8 +40,9 @@ class ConsultAssistantDialogUtils private constructor() {
var consultAssistantDialogFromHomePage: ConsultAssistantDialog? = null // 首页展示的dialog
var consultAssistantDialogFromMine: ConsultAssistantDialog? = null // 我的展示的dialog
var consultAssistantFragmentDialog: ConsultAssistantDialog? = null //咨询师列表fragment页面展示的dialog
var expertSearchPageHasShown: Boolean = false // 专家咨询列表fragment页面是否已经展示
var consultAssistantActivityDialog: ConsultAssistantDialog? = null //咨询师列表activity页面展示的dialog
var expertSearchPageHasShown: Boolean = false // 专家咨询列表fragment页面是否已经展示
var confideListDialog: ConsultAssistantDialog? = null //倾诉列表activity页面展示的dialog
var expertSearchActivityPageHasShown: Boolean = false // 专家咨询列表activity页面是否已经展示
......@@ -86,22 +87,20 @@ class ConsultAssistantDialogUtils private constructor() {
origin: String,
fromActivity: Boolean = false
) {
// 请求接口判断导医咨询助理按钮是否展示
SearchApi.getSearchApi().getConsultAssistantRequest(origin)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
if (it.data) {
if (origin == "home_index") {
showFromYdlHome(activity)
} else if (origin == "doctor_list") {
show(activity, origin, fromActivity)
} else if (origin == "mine_index") {
showFromMine(activity)
}
}
consultAssistantDialogFromHomePage?.dismiss()
consultAssistantFragmentDialog?.dismiss()
consultAssistantDialogFromMine?.dismiss()
when (origin) {
"home_index" -> {
showFromYdlHome(activity)
}
"doctor_list" -> {
show(activity, origin, fromActivity)
}
"mine_index" -> {
showFromMine(activity)
}
}
}
////////////////////////////////////// 首页的展示隐藏逻辑 代码块start ///////////////////////////////////////////////////
......@@ -109,7 +108,7 @@ class ConsultAssistantDialogUtils private constructor() {
/**
* 首页页展示
*/
fun showFromYdlHome(activity: Activity) {
private fun showFromYdlHome(activity: Activity) {
if (!activity.isFinishing) {
if (consultAssistantDialogFromHomePage == null) {
consultAssistantDialogFromHomePage = ConsultAssistantDialog(
......@@ -268,7 +267,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 (!activity.isFinishing) {
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
<?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_19" />
<solid android:color="#80000000"></solid>
<stroke
android:width="0.5px"
android:color="#40FFFFFF" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<selector>
<item android:state_pressed="true">
<shape>
<corners android:radius="4dp" />
<solid android:color="#59FFFFFF" />
<stroke android:width="1dp" android:color="@color/transparent"/>
</shape>
</item>
<item>
<shape>
<corners android:radius="4dp" />
<solid android:color="#59FFFFFF" />
<stroke android:width="5dp" android:color="@color/transparent"/>
</shape>
</item>
</selector>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="4dp" />
<solid android:color="@color/white" />
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<selector>
<item android:state_pressed="true">
<clip>
<shape>
<corners android:radius="4dp" />
<solid android:color="@color/white" />
<stroke android:width="1dp" android:color="@color/transparent"/>
</shape>
</clip>
</item>
<item>
<clip>
<shape>
<corners android:radius="4dp" />
<solid android:color="@color/white" />
<stroke android:width="5dp" android:color="@color/transparent"/>
</shape>
</clip>
</item>
</selector>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="@color/white" />
<size android:width="6dp" android:height="8dp" />
<corners android:radius="2dp" />
</shape>
</item>
<item android:state_pressed="false">
<shape android:shape="oval">
<solid android:color="@color/white" />
<size android:width="8dp" android:height="8dp" />
<stroke android:width="2dp" android:color="@color/transparent" />
</shape>
</item>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="@android:color/transparent">
<com.yidianling.consultant.preview.PhotoViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent" />
<RelativeLayout
android:id="@+id/btnLL"
android:layout_width="match_parent"
android:layout_height="@dimen/platform_dp_60"
android:layout_alignParentBottom="true"
android:layout_marginBottom="@dimen/platform_dp_40">
<TextView
android:id="@+id/chatBtn"
android:layout_width="148dp"
android:layout_height="47dp"
android:layout_alignParentBottom="true"
android:layout_marginLeft="@dimen/platform_dp_20"
android:background="@drawable/consultant_bg_btn_chat"
android:gravity="center"
android:text="立即私聊"
android:textColor="@color/white"
android:textSize="17sp"
android:textStyle="bold" />
<TextView
android:id="@+id/bookingBtn"
android:layout_width="148dp"
android:layout_height="47dp"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="@dimen/platform_dp_20"
android:background="@drawable/consultant_bg_btn_book"
android:gravity="center"
android:text="立即预约"
android:textColor="@color/white"
android:textSize="17sp"
android:textStyle="bold" />
<RelativeLayout
android:id="@+id/un_read_num_ll"
android:layout_width="@dimen/platform_dp_17"
android:layout_height="@dimen/platform_dp_17"
android:layout_alignTop="@+id/chatBtn"
android:layout_alignRight="@+id/chatBtn"
android:layout_marginTop="-10dp"
android:layout_marginRight="@dimen/platform_dp_10"
android:visibility="gone"
android:background="@drawable/consultant_bg_chat_unread_num">
<TextView
android:id="@+id/un_read_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:textColor="@color/white"
android:textSize="@dimen/sp_12" />
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/titleBar"
android:layout_width="match_parent"
android:layout_height="@dimen/platform_dp_32"
android:layout_marginTop="@dimen/platform_dp_32">
<ImageView
android:id="@+id/ivBack"
android:layout_width="@dimen/platform_dp_28"
android:layout_height="@dimen/platform_dp_28"
android:layout_centerVertical="true"
android:layout_marginLeft="12dp"
android:src="@drawable/consultant_back"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="@dimen/platform_dp_24"
android:layout_centerInParent="true"
android:background="@drawable/consultant_bg_preview_photo_num"
android:gravity="center"
android:paddingLeft="@dimen/platform_dp_10"
android:paddingRight="@dimen/platform_dp_10">
<TextView
android:id="@+id/select_position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="@dimen/platform_sp_14" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/platform_dp_1"
android:text="/"
android:textColor="@color/white"
android:textSize="@dimen/platform_sp_14" />
<TextView
android:id="@+id/total"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/platform_dp_1"
android:textColor="@color/white"
android:textSize="@dimen/platform_sp_14" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:layout_gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/iv"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:clickable="false"
android:contentDescription="@null"
android:focusable="false"
android:scaleType="centerCrop"/>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<GridView
android:id="@+id/grid_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="2"
android:layout_marginLeft="@dimen/platform_dp_10"
android:layout_marginRight="@dimen/platform_dp_10"
android:horizontalSpacing="@dimen/platform_dp_10"
android:verticalSpacing="@dimen/platform_dp_10"/>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
tools:ignore="ResourceName">
<com.yidianling.consultant.preview.SmoothImageView
android:id="@+id/photoView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
android:scaleType="centerInside" />
<RelativeLayout
android:id="@+id/videoContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.dou361.ijkplayer.widget.IjkVideoView
android:id="@+id/videoView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:focusableInTouchMode="true" />
<ImageView
android:id="@+id/ivImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
<ImageView
android:id="@+id/ivPlay"
android:layout_width="76dp"
android:layout_height="76dp"
android:layout_centerInParent="true"
android:src="@drawable/ic_video_play"
android:visibility="gone" />
</RelativeLayout>
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="120dp"
android:maxHeight="10dp"
android:paddingStart="0dp"
android:paddingTop="8dp"
android:paddingEnd="0dp"
android:paddingBottom="8dp"
android:progressDrawable="@drawable/consultant_seekbar_style"
android:splitTrack="false"
android:thumb="@drawable/consultant_seekbar_thumb"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<LinearLayout
android:id="@+id/loading"
android:layout_width="103dp"
android:layout_height="103dp"
android:layout_centerInParent="true"
android:background="@drawable/consultant_bg_loading"
android:gravity="center"
android:orientation="vertical">
<ProgressBar
style="?android:attr/progressBarStyleSmall"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/platform_dp_10"
android:text="正在加载"
android:textColor="@color/white" />
</LinearLayout>
<ImageView
android:id="@+id/btnVideo"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_centerInParent="true"
android:alpha="0"
android:visibility="gone" />
</RelativeLayout>
\ No newline at end of file
......@@ -8,4 +8,7 @@
<string name="consultant_reload_hint">加载失败,换个网络环境试试吧</string>
<item name="consultant_item_image_key" type="id" />
</resources>
<resources>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="consultant_FilterTextViewStyle">
<item name="android:layout_height">40dp</item>
......@@ -38,9 +38,7 @@
<item name="android:backgroundDimEnabled">true</item>
</style>
<style name="consultant_Transparent" parent="@style/Base.Theme.AppCompat">
<item name="colorPrimary">@color/transparent</item>
<item name="colorPrimaryDark">@color/transparent</item>
<style name="consultant_Transparent" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowBackground">@color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
......
......@@ -45,6 +45,7 @@ import com.yidianling.tests.api.service.ITestsApiService
import com.yidianling.user.api.service.IUserService
import de.greenrobot.event.EventBus
import org.json.JSONObject
import java.net.URLDecoder
open class HomeBaseImpl : IHomeBaseEvent {
......@@ -539,11 +540,14 @@ open class HomeBaseImpl : IHomeBaseEvent {
return
}
ActionCountUtils.count(HomeBIConstants.YDL_USER_ARTICLE_CLICK, bean.id.toString())
ActionCountUtils.count(
HomeBIConstants.YDL_USER_ARTICLE_CLICK, bean.id.toString(),
bean.title ?: ""
)
YDLRouterManager.router(
IYDLRouterConstant.ROUTER_H5_H5,
YDLRouterParams().putExtra(IYDLRouterConstant.EXTRA_URL, bean.gethUrl()!!), ""
YDLRouterParams().putExtra(IYDLRouterConstant.EXTRA_URL, bean.listAllUrl!!), ""
)
}
......
......@@ -78,7 +78,7 @@ class HomeBaseHttp {
//首页文章请求
fun getArticleData(): Observable<BaseAPIResponse<HomeArticleBean>> {
articleListSize = if (YdlCommonOut.getApp().packageName == "com.cxzapp.xinlizixun") "6" else "4"
articleListSize = if (YdlCommonOut.getApp().packageName == "com.cxzapp.xinlizixun") "6" else "3"
return getHomePagerApi().getArticleData(perPageRows = articleListSize)
}
......
......@@ -96,10 +96,10 @@ interface HomeBasePagerApi {
@Headers(YDL_DOMAIN + YDL_DOMAIN_JAVA)
fun getFMData(@Query("perPageRows") perPageRows: String = "4"): Observable<BaseAPIResponse<HomeFMBean>>
//首页文章请求
@GET("article/list/all")
//首页文章请求 文章改版需求改为3条
@GET("newArticle/list/all")
@Headers(YDL_DOMAIN + YDL_DOMAIN_JAVA)
fun getArticleData(@Query("perPageRows") perPageRows: String = "4"): Observable<BaseAPIResponse<HomeArticleBean>>
fun getArticleData(@Query("perPageRows") perPageRows: String = "3"): Observable<BaseAPIResponse<HomeArticleBean>>
//首页问答 - 点赞
@FormUrlEncoded
......
......@@ -26,7 +26,7 @@ class HomeArticleBean : HomeItemBaseBean {
/**
* 收藏数
*/
var countOfFavorite: Int = 0
var countOfFavorite: String = "0"
var createTime: String? = null
var createTimeFormat: String? = null
/**
......@@ -55,7 +55,7 @@ class HomeArticleBean : HomeItemBaseBean {
/**
* 阅读次数
*/
var readNum: Int = 0
var readNum: String = "0"
/**
* 120*120小头像
*/
......@@ -72,5 +72,8 @@ class HomeArticleBean : HomeItemBaseBean {
fun sethUrl(hUrl: String) {
this.hUrl = hUrl
}
var listAllUrl:String?=null
}
}
......@@ -491,9 +491,7 @@ open class YdlHomeFragment : BaseMvpFragment<IHomeContract.View, HomePresenterIm
super.setUserVisibleHint(isVisibleToUser)
if (isVisibleToUser && isResumed) {
startTime=System.currentTimeMillis()
showConsultAssistantDialog()
} else {
hideConsultAssistantDialog()
if (startTime!=0L){
endTime=System.currentTimeMillis()
ActionCountUtils.count(HomeBIConstants.YDL_HOME_DWELL_TIME,(endTime-startTime).toString())
......@@ -506,11 +504,6 @@ open class YdlHomeFragment : BaseMvpFragment<IHomeContract.View, HomePresenterIm
}
}
private fun showConsultAssistantDialog() {
ModularServiceManager.provide(IConsultantService::class.java)
.showConsultAssistantDialog(mActivity)
}
private fun getBottomWord() {
ModularServiceManager.provide(IConsultantService::class.java)
.getbottomWord(2, object : OnBottomWordListener {
......@@ -558,7 +551,6 @@ open class YdlHomeFragment : BaseMvpFragment<IHomeContract.View, HomePresenterIm
}
ActionCountUtils.count(HomeBIConstants.YDL_USER_MAIN_PAGE_VISIT)
ActionCountUtils.count("daoyi_advertisement_page|daoyi_advertisement_visit","1")
showConsultAssistantDialog()
video_view?.setOnInfoListener { mp, what, extra ->
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START){
......
......@@ -3,6 +3,7 @@ package com.yidianling.home.ui.view
import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.widget.LinearLayout
import androidx.recyclerview.widget.RecyclerView
import com.ydl.ydl_image.manager.YDLImageCacheManager
......@@ -38,12 +39,12 @@ class HomeArticleItemView(private val mContext: Context, private var homeEvent:
homeModuleArticleItemViewTitle.text = bean?.title
homeModuleArticleItemViewContent.text = bean?.desc
homeModuleArticleItemViewAuthor.text = bean?.name
homeModuleArticleItemViewGreatNum.text = bean?.countOfFavorite.toString()
homeModuleArticleItemViewLookNum.text = bean?.readNum.toString()
homeModuleArticleItemViewGreatNum.text = "${bean?.countOfFavorite}点赞"
homeModuleArticleItemViewLookNum.text = "${bean?.readNum}浏览"
YDLImageCacheManager.showImage(mContext, bean?.imgUrl, homeModuleArticleItemViewImg)
YDLImageCacheManager.showImage(mContext, bean?.smallImage, homeModuleArticleItemViewIcon)
setOnClickListener {
homeEvent?.articleItemClick(bean)
}
}
......
......@@ -5,6 +5,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.recyclerview.widget.RecyclerView
import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils
import com.yidianling.home.R
import com.yidianling.home.constract.HomeViewConfig
import com.yidianling.home.event.IHomeBaseEvent
......@@ -56,6 +57,8 @@ class HomeArticleView(private val mContext: Context, private var homeEvent: IHom
}
}
}
// 文章阅读新增埋点
ActionCountUtils.record("ydl_user_main_page", "ydl_user_article_visit")
}
}
......
......@@ -4,124 +4,128 @@
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:paddingLeft="@dimen/platform_dp_15"
android:paddingRight="@dimen/platform_dp_15"
android:paddingTop="@dimen/platform_dp_15">
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="4dp">
<androidx.cardview.widget.CardView
android:id="@+id/homeModuleArticleItemViewCardImg"
android:layout_width="@dimen/platform_dp_127"
android:layout_height="@dimen/platform_dp_88"
android:layout_width="88dp"
android:layout_height="70dp"
android:layout_alignParentRight="true"
app:cardCornerRadius="@dimen/platform_dp_6"
app:cardCornerRadius="8dp"
app:cardElevation="0dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:id="@+id/homeModuleArticleItemViewImg"
android:background="@drawable/home_image_default_back"/>
tools:src="@drawable/home_image_default_back"/>
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/homeModuleArticleItemViewTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxHeight="44dp"
android:maxLines="2"
android:ellipsize="end"
android:textSize="@dimen/platform_dp_18"
android:textSize="16sp"
android:textStyle="bold"
android:layout_marginTop="-2dp"
android:textColor="@color/platform_color_222222"
android:layout_alignParentTop="true"
android:textColor="#1C1F28"
android:lineSpacingExtra="@dimen/platform_dp_1"
tools:text="喧嚣的世界中,你的重要何以而来?喧嚣的世界中,你的重要何以而来?"
tools:text="喧嚣的世界中,你的重要何以而来?"
android:layout_alignParentLeft="true"
android:layout_alignTop="@id/homeModuleArticleItemViewCardImg"
android:layout_toLeftOf="@+id/homeModuleArticleItemViewCardImg"
android:layout_marginRight="@dimen/platform_dp_20"/>
android:layout_marginRight="18dp"/>
<TextView
android:id="@+id/homeModuleArticleItemViewContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="2"
android:layout_height="18dp"
android:layout_marginTop="8dp"
android:maxLines="1"
android:gravity="center_vertical"
android:ellipsize="end"
android:textSize="@dimen/platform_dp_13"
android:layout_marginTop="@dimen/platform_dp_4"
android:textColor="@color/platform_color_666666"
android:textColor="#9D9EA7"
android:layout_alignParentLeft="true"
android:layout_below="@+id/homeModuleArticleItemViewTitle"
android:lineSpacingExtra="@dimen/platform_dp_3"
tools:text="喧嚣的世界中,你的重要何以而来?当我伫立在我所伫立之处..."
android:layout_toLeftOf="@+id/homeModuleArticleItemViewCardImg"
android:layout_marginRight="@dimen/platform_dp_20"/>
android:layout_below="@id/homeModuleArticleItemViewTitle"
android:layout_marginRight="18dp"/>
<LinearLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/homeModuleArticleItemViewBottomLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_below="@+id/homeModuleArticleItemViewCardImg"
android:layout_marginTop="@dimen/platform_dp_16">
android:layout_marginTop="17dp">
<ImageView
android:id="@+id/homeModuleArticleItemViewIcon"
android:layout_width="@dimen/platform_dp_12"
android:layout_height="@dimen/platform_dp_12"
android:src="@drawable/home_article_item_icon"
android:layout_alignParentLeft="true"/>
<androidx.cardview.widget.CardView
android:id="@+id/card_view_avatar"
android:layout_width="16dp"
android:layout_height="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:cardElevation="0dp"
app:cardCornerRadius="8dp">
<TextView
android:id="@+id/homeModuleArticleItemViewAuthor"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textSize="@dimen/platform_dp_12"
android:textColor="@color/platform_color_242424"
android:layout_marginLeft="@dimen/platform_dp_3"
android:textStyle="bold"
tools:text="赵秀英"/>
<ImageView
android:id="@+id/homeModuleArticleItemViewIcon"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/home_article_item_icon"/>
<TextView
android:id="@+id/homeModuleArticleItemViewGreatNum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="3327"
android:textSize="@dimen/platform_dp_12"
android:textColor="@color/platform_color_242424"/>
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/homeModuleArticleItemViewAuthor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点赞"
android:textSize="@dimen/platform_dp_11"
android:layout_marginRight="@dimen/platform_dp_12"
android:textColor="@color/platform_color_666666"/>
android:textSize="13sp"
android:textColor="#62636F"
android:layout_marginLeft="5dp"
app:layout_constraintStart_toEndOf="@id/card_view_avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="赵秀英"/>
<TextView
android:id="@+id/homeModuleArticleItemViewLookNum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="2656"
android:textSize="@dimen/platform_dp_12"
android:textColor="@color/platform_color_242424"/>
android:layout_marginEnd="70dp"
tools:text="2656浏览"
android:textSize="13sp"
android:textColor="#62636F"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<TextView
android:id="@+id/homeModuleArticleItemViewGreatNum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="浏览"
android:textSize="@dimen/platform_dp_11"
android:textColor="@color/platform_color_666666"/>
tools:text="3327点赞"
android:textSize="13sp"
android:textColor="#62636F"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/homeModuleArticleItemViewBottomLine"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/platform_color_EBEBEB"
android:background="#EFEFF1"
android:layout_centerInParent="true"
android:layout_below="@+id/homeModuleArticleItemViewBottomLayout"
android:layout_marginTop="@dimen/platform_dp_16"/>
android:layout_marginTop="20dp"
android:layout_marginBottom="30dp"/>
</RelativeLayout>
......@@ -121,7 +121,7 @@
android:layout_height="wrap_content"
android:textSize="@dimen/platform_sp_12"
android:textColor="#69696A"
android:text="倾诉人次"
android:text="服务人次"
/>
</LinearLayout>
<LinearLayout
......
......@@ -43,6 +43,7 @@ import com.yidianling.im.ui.page.NewMultiMessageFragment
import com.yidianling.nimbase.common.media.picker.PickImageHelper
import com.yidianling.uikit.api.NimUIKit
import com.yidianling.uikit.business.session.helper.MessageListPanelHelper
import com.yidianling.uikit.custom.widget.expertConsultService.view.ExpertConsultServiceListDialog2
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
......@@ -53,6 +54,8 @@ import io.reactivex.schedulers.Schedulers
@Route(path = "/im/ImService")
class IMServiceImpl : IImService {
private var expertConsultServiceListDialog2: ExpertConsultServiceListDialog2 ?= null
override fun isHasUnread(): Boolean {
return MsgReceiveHelper.isHasUnread
}
......@@ -411,4 +414,21 @@ class IMServiceImpl : IImService {
override fun isWifiOr3G(activity: Activity): Boolean {
return NetworkUtil.isWifiOr3G(activity)
}
override fun showConsultServiceDialog(activity: Activity, toUid: String, doctorId: String) {
// 获取专家是否在繁忙状态
if (activity != null) {
expertConsultServiceListDialog2 =
ExpertConsultServiceListDialog2(
activity, null, false, toUid,
doctorId
)
expertConsultServiceListDialog2?.show()
}
}
override fun dismissConsultServiceDialog() {
expertConsultServiceListDialog2?.changeItem()
}
}
\ No newline at end of file
......@@ -98,12 +98,14 @@ import com.yidianling.uikit.custom.bridge.IP2PCustomActionHandler;
import com.yidianling.uikit.custom.http.ServiceImpl;
import com.yidianling.uikit.custom.http.response.CommonQuestionBean;
import com.yidianling.uikit.custom.http.response.NewUserMesBean;
import com.yidianling.uikit.custom.http.response.ServiceItemBean;
import com.yidianling.uikit.custom.http.response.UserQuestInfoBean;
import com.yidianling.uikit.custom.widget.ConfideOrderInfoView;
import com.yidianling.uikit.custom.widget.ExpertInfoDialog;
import com.yidianling.uikit.custom.widget.TitleBarBottom;
import com.yidianling.uikit.custom.widget.UserInfoDialog;
import com.yidianling.uikit.custom.widget.expertConsultService.view.ExpertConsultServiceListDialog;
import com.yidianling.uikit.custom.widget.expertConsultService.view.ExpertConsultServiceListDialog2;
import com.yidianling.user.api.service.IUserService;
import org.jetbrains.annotations.NotNull;
......@@ -154,6 +156,10 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
private RelativeLayout rl_contain;
private boolean initHeightFinish;
public TitleBarBottom titleBar;
private List<ServiceItemBean> serviceItemBeanList;
public InputPanel getInputPanel() {
return inputPanel;
}
......@@ -208,6 +214,7 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
private ExpertInfoDialog expertInfoDialog;
private ExpertConsultServiceListDialog expertConsultServiceListDialog;
private ExpertConsultServiceListDialog2 expertConsultServiceListDialog2;
private int IN_OUT_DURATION = 400;
......@@ -929,27 +936,27 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
@SuppressLint("CheckResult")
private void initMenu() {
rela_zixun.setOnClickListener(view -> {
if (Utils.isFastClick()) {
//防止连击
return;
}
if (sessionId != null && ActionHandlerStorage.getL(sessionId) != null && ActionHandlerStorage.getL(sessionId).getInfo() != null) {
if (expertConsultServiceListDialog == null) {
ServiceImpl.Companion.getInstance().serviceList(ActionHandlerStorage.getL(sessionId).getInfo().doctorId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(res -> {
if (res.data != null && res.data.size() > 0) {
if (getActivity() != null && expertConsultServiceListDialog == null) {
expertConsultServiceListDialog = new ExpertConsultServiceListDialog(getActivity(), res.data,isBusy,sessionId,
ActionHandlerStorage.getL(sessionId).getInfo().doctorId
);
expertConsultServiceListDialog.show();
if (serviceItemBeanList == null || serviceItemBeanList.size() == 0) {
ServiceImpl.Companion.getInstance().serviceList(ActionHandlerStorage.getL(sessionId).getInfo().doctorId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(res -> {
if (res.data != null && res.data.size() > 0) {
serviceItemBeanList = res.data;
showConsultService(res.data,isBusy,sessionId, ActionHandlerStorage.getL(sessionId).getInfo().doctorId);
} else {
ToastUtil.toastShort("咨询师暂未发布服务");
}
} else {
ToastUtil.toastShort("咨询师暂未发布服务");
}
}, throwable -> {
});
} else {
expertConsultServiceListDialog.show();
}
}, throwable -> {
});
} else {
showConsultService(serviceItemBeanList, isBusy, sessionId, ActionHandlerStorage.getL(sessionId).getInfo().doctorId);
}
} else {
ToastUtil.toastShort("请退出聊天重试");
}
......@@ -1093,6 +1100,10 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
comment_banner_view.onDestory();
EventBus.getDefault().unregister(this);
super.onDestroy();
if (serviceItemBeanList != null) {
serviceItemBeanList.clear();
serviceItemBeanList = null;
}
messageListPanel.onDestroy();
registerObservers(false);
if (inputPanel != null) {
......@@ -1175,7 +1186,7 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
}
}
public void onEvent(CloseBottomWebviewEvent event){
expertConsultServiceListDialog.changeItem();
expertConsultServiceListDialog2.changeItem();
}
private void updateLocalMsg(Integer position,ArrayList<String> selectedPosition) {
IMMessage message=ImIn.INSTANCE.getImMessage();
......@@ -1604,4 +1615,15 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
ActionCountUtils.Companion.count("under_age_alert_page|under_age_alert_page_visit");
}
private void showConsultService(List<ServiceItemBean> list, Boolean mIsBusy,
String toUid, String doctorID) {
if (getActivity() != null) {
expertConsultServiceListDialog2 = new ExpertConsultServiceListDialog2(getActivity(), list, isBusy, sessionId,
ActionHandlerStorage.getL(sessionId).getInfo().doctorId);
expertConsultServiceListDialog2.show();
}
}
}
......@@ -17,6 +17,7 @@ import com.yidianling.uikit.custom.http.response.ServiceItemBean
import com.yidianling.uikit.custom.widget.expertConsultService.callback.ConsultServiceViewCallback
import com.yidianling.user.api.service.IUserService
import kotlinx.android.synthetic.main.im_expert_consult_service_item_view.view.*
import java.text.DecimalFormat
/**
* 咨询服务, 预约item
......@@ -55,20 +56,36 @@ class ExpertConsultServiceItemView : LinearLayout {
View.inflate(mContext, R.layout.im_expert_consult_service_item_view, this)
}
fun updateBusyStatus(isBusy: Boolean) {
mIsBusy = isBusy
if (mIsBusy) {
im_expert_service_list_btn.visibility = View.GONE
tv_add.visibility = View.VISIBLE
tv_add.setOnClickListener {
mListener?.addTime()
}
} else {
im_expert_service_list_btn.visibility = View.VISIBLE
tv_add.visibility = View.GONE
}
}
/**
* 设置数据
*/
@SuppressLint("SetTextI18n")
fun setData(bean: ServiceItemBean.ProductsBean) {
if (mIsBusy) { // 是否繁忙 true繁忙
ll_not_busy.visibility = View.GONE
ll_busy.visibility = View.VISIBLE
im_expert_service_list_btn.visibility = View.GONE
tv_add.visibility = View.VISIBLE
tv_add.setOnClickListener {
mListener?.addTime()
}
} else {
ll_not_busy.visibility = View.VISIBLE
ll_busy.visibility = View.GONE
im_expert_service_list_btn.visibility = View.VISIBLE
tv_add.visibility = View.GONE
}
//是否是套餐
if (bean.productDto.isPackage == 2) {
......@@ -87,6 +104,7 @@ class ExpertConsultServiceItemView : LinearLayout {
//隐藏起售次数限制
service_item_low_buy_time.visibility = View.GONE
}
val mCompare: Comparator<ServiceItemBean.ProductsBean.ProductSpecDtosBean> =
Comparator { o1, o2 ->
val res = o1.price.compareTo(o2.price)
......@@ -100,10 +118,13 @@ class ExpertConsultServiceItemView : LinearLayout {
val mBean: ServiceItemBean.ProductsBean.ProductSpecDtosBean =
bean.productSpecDtos.sortedWith(mCompare).last()
//价格,取productSpecDtos数组最小价格,不保留小数
service_item_price.text = String.format(
"%.0f",
mBean.price
)
// service_item_price.text = String.format(
// "%.0f",
// mBean.price
// )
val decimalFormat = DecimalFormat("###.##")
service_item_price.text = decimalFormat.format(mBean.price)
service_item_price.paint.isFakeBoldText = true
//时间,取productSpecDtos数组最后一个的时间
// service_item_time.text = "/${bean.productDto.minOrderTime}分钟"
......@@ -129,13 +150,20 @@ class ExpertConsultServiceItemView : LinearLayout {
//销量
service_item_saleout_num.text = "销量${bean.productDto.saleAmount}"
// service_item_saleout_num.text = "销量${bean.productDto.saleAmount}"
service_item_saleout_num.text = "${bean.productDto.saleAmount}"
setOnClickListener {
mListener?.onItemClick(bean)
}
im_expert_service_list_btn.setOnClickListener {
mContext?.let {context ->
if (!ImIn.loginByOneKeyLogin(context, true)) {
return@setOnClickListener
}
}
if (ImIn.getUserService().isBindPhone()) {
NewH5Activity.start(
mContext,
......@@ -144,7 +172,7 @@ class ExpertConsultServiceItemView : LinearLayout {
null
)
)
}else{
} else {
//新增需求,如果没有绑定手机号,跳转到绑定手机号页面
bindPhoneDialog()
}
......
......@@ -4,7 +4,6 @@ import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.LinearLayout
import com.yidianling.avchatkit.common.log.LogUtil
import com.yidianling.common.tools.RxDeviceTool
import com.yidianling.im.R
import com.yidianling.uikit.custom.http.response.ServiceItemBean
......@@ -53,7 +52,6 @@ class ExpertConsultServiceView : LinearLayout {
private fun initView() {
val mWidth: Int = RxDeviceTool.getScreenWidth(mContext)
val mHeight: Int = LayoutParams.MATCH_PARENT
......@@ -68,6 +66,15 @@ class ExpertConsultServiceView : LinearLayout {
View.inflate(mContext, R.layout.im_expert_consult_service_view, this)
}
fun setBusyStatus(isBusy: Boolean){
this.mIsBusy = isBusy
for(i in 0 until expert_consult_service_service_list.childCount){
val view = expert_consult_service_service_list.getChildAt(i)
if (view is ExpertConsultServiceItemView) {
view.updateBusyStatus(mIsBusy)
}
}
}
/**
* typeList 类型列表
* serviceList 服务列表
......@@ -78,9 +85,9 @@ class ExpertConsultServiceView : LinearLayout {
listener: ConsultServiceViewCallback?
) {
mListener = listener
consult_service_dialog_close.setOnClickListener {
mListener?.onCloseClick()
}
// consult_service_dialog_close.setOnClickListener {
// mListener?.onCloseClick()
// }
// 设置顶部滚动类型数据
if (typeList == null || typeList.size == 0) {
......@@ -101,7 +108,7 @@ class ExpertConsultServiceView : LinearLayout {
}
}
}
tv_title.paint.isFakeBoldText = true
typeSelectedIndex = 0 // 初始化为全部选中
mServiceList.clear()
mServiceList.addAll(allServiceList)
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#D7D7D7"/>
<corners android:radius="2dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:topLeftRadius="15dp"
android:topRightRadius="15dp" />
<solid android:color="#ffffff"/>
<solid android:color="@color/white"/>
</shape>
\ No newline at end of file
......@@ -2,7 +2,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="14dp" />
<corners android:radius="@dimen/platform_dp_18" />
<gradient android:startColor="#FF7A5C"
android:endColor="#FF406C"/>
......
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