diff --git a/app/src/main/java/com/xjjk/healthyclients/adapter/HealthConsultationAdapter.kt b/app/src/main/java/com/xjjk/healthyclients/adapter/HealthConsultationAdapter.kt new file mode 100644 index 0000000..e30d0b0 --- /dev/null +++ b/app/src/main/java/com/xjjk/healthyclients/adapter/HealthConsultationAdapter.kt @@ -0,0 +1,27 @@ +package com.xjjk.healthyclients.adapter + +import android.widget.ImageView +import com.chad.library.adapter.base.BaseQuickAdapter +import com.chad.library.adapter.base.viewholder.BaseViewHolder +import com.xjjk.healthyclients.R +import com.xjjk.healthyclients.bean.home.ArticleBean +import com.xjjk.healthyclients.superfuntion.loadRoundedImage +import com.xjjk.healthyclients.superfuntion.orEmptyDefault + +/** + * 健康咨询列表 Adapter + */ +class HealthConsultationAdapter : + BaseQuickAdapter(R.layout.item_health_consultation) { + + override fun convert(holder: BaseViewHolder, item: ArticleBean) { + // 标题 + holder.setText(R.id.tv_title, item.articleTitle.orEmptyDefault()) + // 收藏和分享数 + holder.setText(R.id.tv_meta, "收藏 ${item.favoriteCount} 分享 ${item.likeCount}") + // 封面图片 80x60 圆角8 + holder.getView(R.id.iv_cover)?.loadRoundedImage( + item.articleHeaderimage, 8f,R.mipmap.ic_placeholder_rectangle + ) + } +} diff --git a/app/src/main/java/com/xjjk/healthyclients/adapter/HealthKnowledgeAdapter.kt b/app/src/main/java/com/xjjk/healthyclients/adapter/HealthKnowledgeAdapter.kt new file mode 100644 index 0000000..52529cf --- /dev/null +++ b/app/src/main/java/com/xjjk/healthyclients/adapter/HealthKnowledgeAdapter.kt @@ -0,0 +1,32 @@ +package com.xjjk.healthyclients.adapter + +import android.widget.ImageView +import com.chad.library.adapter.base.BaseQuickAdapter +import com.chad.library.adapter.base.viewholder.BaseViewHolder +import com.sw.healthyclients.utils.DateUtil +import com.xjjk.healthyclients.R +import com.xjjk.healthyclients.bean.home.ArticleBean +import com.xjjk.healthyclients.superfuntion.loadRoundedImage +import com.xjjk.healthyclients.superfuntion.orEmptyDefault + +/** + * 健康知识列表 Adapter + */ +class HealthKnowledgeAdapter : + BaseQuickAdapter(R.layout.item_health_knowledge) { + + override fun convert(holder: BaseViewHolder, item: ArticleBean) { + // 封面图片 100x100 圆角15 + holder.getView(R.id.iv_cover)?.loadRoundedImage( + item.articleHeaderimage, 15f, R.mipmap.ic_placeholder_square, + ) + // 标题 + holder.setText(R.id.tv_title, item.articleTitle.orEmptyDefault()) + // 摘要 + holder.setText(R.id.tv_detail, item.articleSubtitle.orEmptyDefault("")) + // 标签文本 + holder.setText(R.id.tv_tag, item.articleTag.orEmptyDefault()) + // 日期 + holder.setText(R.id.tv_date, DateUtil.long2ShortDateStr(item.createTime)) + } +} diff --git a/app/src/main/java/com/xjjk/healthyclients/bankRequest/HealthInfoRequest.kt b/app/src/main/java/com/xjjk/healthyclients/bankRequest/HealthInfoRequest.kt new file mode 100644 index 0000000..917f091 --- /dev/null +++ b/app/src/main/java/com/xjjk/healthyclients/bankRequest/HealthInfoRequest.kt @@ -0,0 +1,182 @@ +package com.xjjk.healthyclients.bankRequest + +import com.sw.healthyclients.data.local.DataStoreManager +import com.xjjk.healthyclients.bean.home.ArticleBean +import com.xjjk.healthyclients.bean.home.ArticleListBean +import com.xjjk.healthyclients.bean.home.CategoryBean +import com.xjjk.healthyclients.data.api.CategoryListResponse +import com.xjjk.healthyclients.data.api.HealthInfoApi +import com.xjjk.healthyclients.data.api.TokenResponse +import com.xjjk.healthyclients.retrofit.UrlConfig +import com.xjjk.healthyclients.retrofit.getBankRetrofit +import com.xjjk.healthyclients.superfuntion.toJson +import com.xjjk.healthyclients.utils.SignatureUtils +import okhttp3.RequestBody.Companion.toRequestBody +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response + +/** + * 健康资讯网络请求封装类 + * 负责 Token 获取(签名认证)、栏目列表、文章列表的 API 调用 + */ +class HealthInfoRequest { + + private val api: HealthInfoApi = getBankRetrofit() + .create(HealthInfoApi::class.java) + + companion object { + /** 缓存的 Token,避免重复请求 */ + private var cachedToken: String? = null + } + + /** + * 获取 Token(带 HMAC-SHA256 签名) + */ + fun fetchToken( + onSuccess: (String) -> Unit, + onFailure: (Throwable) -> Unit + ) { + // 如果已有缓存 Token,直接返回 + cachedToken?.let { + onSuccess(it) + return + } + + try { + val timestamp = System.currentTimeMillis() / 1000 + val userId = DataStoreManager.getUserId() ?: "" + val workNo = DataStoreManager.getUserInfo()?.workNo ?: "" + val bodyString = """{"userId":"$userId","workNo":"$workNo"}""" + val sign = SignatureUtils.generateSignature(timestamp, bodyString, UrlConfig.SECRET_KEY) + + val headers = mapOf( + "Content-Type" to "application/json; charset=utf-8", + "X-Timestamp" to timestamp.toString(), + "X-Sign" to sign + ) + + val body = mapOf("userId" to userId, "workNo" to workNo) + + api.getToken(headers, body.toJson().toRequestBody()) + .enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + if (response.code() == 200) { + val token = response.body()?.data?.token + if (!token.isNullOrEmpty()) { + cachedToken = token + onSuccess(token) + } else { + onFailure(Exception("Token 为空")) + } + } else { + onFailure(Exception("HTTP ${response.code()}: ${response.message()}")) + } + } + + override fun onFailure( + call: Call, + t: Throwable + ) { + onFailure(t) + } + }) + } catch (e: Exception) { + onFailure(e) + } + } + + /** + * 获取栏目列表 + */ + fun fetchCategoryList( + token: String, + onSuccess: (MutableList) -> Unit, + onFailure: (Throwable) -> Unit + ) { + try { + val headers = mapOf("token" to token) + + api.getCategoryList(headers) + .enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + if (response.code() == 200) { + val data = response.body()?.data ?: mutableListOf() + onSuccess(data) + } else { + onFailure(Exception("HTTP ${response.code()}: ${response.message()}")) + } + } + + override fun onFailure( + call: Call, + t: Throwable + ) { + onFailure(t) + } + }) + } catch (e: Exception) { + onFailure(e) + } + } + + /** + * 分页查询文章列表 + * + * @param token 认证 Token + * @param categoryId 栏目 ID + * @param pageNum 页码 + * @param pageSize 每页数量 + * @param articleType 文章类型,"0"-图文,"1"-视频,不传则全部 + */ + fun fetchArticleList( + token: String, + categoryId: Int, + pageNum: Int = 1, + pageSize: Int = 3, + onSuccess: (MutableList?) -> Unit, + onFailure: (Throwable) -> Unit + ) { + try { + val headers = mapOf("token" to token) + val params = mapOf( + "categoryId" to categoryId.toString(), + "pageNum" to pageNum.toString(), + "pageSize" to pageSize.toString(), + "showAppHomepage" to "Y" + ) + + api.getArticleList(headers, params) + .enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + if (response.code() == 200) { + val body = response.body() + onSuccess(body?.rows) + } else { + onFailure(Exception("HTTP ${response.code()}: ${response.message()}")) + } + } + + override fun onFailure(call: Call, t: Throwable) { + onFailure(t) + } + }) + } catch (e: Exception) { + onFailure(e) + } + } + + /** 清除缓存的 Token(登录态变化时调用) */ + fun clearToken() { + cachedToken = null + } +} diff --git a/app/src/main/java/com/xjjk/healthyclients/bean/home/HealthInfoBean.kt b/app/src/main/java/com/xjjk/healthyclients/bean/home/HealthInfoBean.kt new file mode 100644 index 0000000..ae67495 --- /dev/null +++ b/app/src/main/java/com/xjjk/healthyclients/bean/home/HealthInfoBean.kt @@ -0,0 +1,53 @@ +package com.xjjk.healthyclients.bean.home + +import com.google.gson.annotations.SerializedName + +/** + * 获取 token 响应 + */ +data class TokenBean( + @SerializedName("token") val token: String? = null +) + +/** + * 栏目分类 + */ +data class CategoryBean( + @SerializedName("categoryId") val categoryId: Int = 0, + @SerializedName("categoryName") val categoryName: String? = null, + @SerializedName("categoryStatus") val categoryStatus: String? = null, + @SerializedName("children") val children: MutableList? = null, + @SerializedName("parentId") val parentId: Int = 0, + @SerializedName("sortOrder") val sortOrder: Int = 0 +) + +/** + * 文章 + */ +data class ArticleBean( + @SerializedName("articleId") val articleId: Int = 0, + @SerializedName("articleTitle") val articleTitle: String? = null, + @SerializedName("articleSubtitle") val articleSubtitle: String? = null, + @SerializedName("articleTag") val articleTag: String? = null, + @SerializedName("articleHeaderimage") val articleHeaderimage: String? = null, + @SerializedName("articleType") val articleType: String? = null, + @SerializedName("articleExcerpt") val articleExcerpt: String? = null, + @SerializedName("articleContent") val articleContent: String? = null, + @SerializedName("articleVideo") val articleVideo: String? = null, + @SerializedName("favoriteCount") val favoriteCount: Int = 0, + @SerializedName("likeCount") val likeCount: Int = 0, + @SerializedName("viewCount") val viewCount: Int = 0, + @SerializedName("createTime") val createTime: String? = null, + @SerializedName("categoryId") val categoryId: Int = 0, + @SerializedName("articleScore") val articleScore: Double = 0.0, + @SerializedName("articleStatus") val articleStatus: String? = null, + @SerializedName("showAppHomepage") val showAppHomepage: String? = null +) + +/** + * 文章列表分页响应 + */ +data class ArticleListBean( + @SerializedName("rows") val rows: MutableList? = null, + @SerializedName("total") val total: Int = 0 +) diff --git a/app/src/main/java/com/xjjk/healthyclients/data/api/HealthInfoApi.kt b/app/src/main/java/com/xjjk/healthyclients/data/api/HealthInfoApi.kt new file mode 100644 index 0000000..5a7ec6a --- /dev/null +++ b/app/src/main/java/com/xjjk/healthyclients/data/api/HealthInfoApi.kt @@ -0,0 +1,63 @@ +package com.xjjk.healthyclients.data.api + +import com.xjjk.healthyclients.bean.home.ArticleListBean +import com.xjjk.healthyclients.bean.home.CategoryBean +import com.xjjk.healthyclients.bean.home.TokenBean +import com.xjjk.healthyclients.retrofit.UrlConfig +import okhttp3.RequestBody +import retrofit2.Call +import retrofit2.http.Body +import retrofit2.http.GET +import retrofit2.http.HeaderMap +import retrofit2.http.POST +import retrofit2.http.QueryMap + +/** + * 健康资讯 API 接口(使用银行 Retrofit 实例,baseUrl 为 getDefaultBankBaseUrl()) + */ +interface HealthInfoApi { + + /** + * 获取 Token(带签名认证) + */ + @POST("${UrlConfig.middleCheck}pe/frontend/init") + fun getToken( + @HeaderMap headers: Map, + @Body requestBody: RequestBody + ): Call + + /** + * 获取栏目列表 + */ + @GET("${UrlConfig.middleCheck}cms/frontend/category/list") + fun getCategoryList( + @HeaderMap headers: Map + ): Call + + /** + * 分页查询文章列表 + */ + @GET("${UrlConfig.middleCheck}cms/frontend/articleList") + fun getArticleList( + @HeaderMap headers: Map, + @QueryMap params: Map + ): Call +} + +/** + * Token 接口响应外层 + */ +data class TokenResponse( + val msg: String? = null, + val code: Int = 0, + val data: TokenBean? = null +) + +/** + * 栏目列表接口响应外层 + */ +data class CategoryListResponse( + val msg: String? = null, + val code: Int = 0, + val data: MutableList? = null +) diff --git a/app/src/main/java/com/xjjk/healthyclients/fragment/HomeFragment.kt b/app/src/main/java/com/xjjk/healthyclients/fragment/HomeFragment.kt index 7d7affd..a4ded34 100644 --- a/app/src/main/java/com/xjjk/healthyclients/fragment/HomeFragment.kt +++ b/app/src/main/java/com/xjjk/healthyclients/fragment/HomeFragment.kt @@ -15,8 +15,10 @@ import com.tencent.qcloud.tuikit.tuichat.bean.WorkBean import com.xjjk.healthyclients.R import com.xjjk.healthyclients.adapter.common.MultiItemTypeAdapter import com.xjjk.healthyclients.bankRequest.BankPointRequest +import com.xjjk.healthyclients.bankRequest.HealthInfoRequest import com.xjjk.healthyclients.base.BaseVMBFragment import com.xjjk.healthyclients.bean.guidance.GuidanceListBean +import com.xjjk.healthyclients.bean.home.CategoryBean import com.xjjk.healthyclients.bean.home.WatchInfoBean import com.xjjk.healthyclients.data.api.HomeApi import com.xjjk.healthyclients.databinding.FragmentHomeBinding @@ -67,6 +69,13 @@ class HomeFragment : var noticeTime = REQUEST_DURATION var watchInfo: WatchInfoBean? = null + /** 健康资讯请求 */ + private var mHealthInfoRequest: HealthInfoRequest? = null + /** 健康资讯 Token */ + private var mHealthToken: String? = null + /** 健康知识子栏目列表 */ + private var mKnowledgeCategories: MutableList = mutableListOf() + /** 通知轮播协程 Job,重新启动前先取消旧任务,防止多协程并发叠加 */ private var noticeJob: Job? = null @@ -140,6 +149,7 @@ class HomeFragment : }) mBinding.layoutItem3.fragmentGuidanceRvDoctor.adapter = mGuidanceFragmentDoctorAdapter mBinding.watchView.init(this@HomeFragment) + setupHealthViews() } override fun bindEvent() { @@ -169,9 +179,9 @@ class HomeFragment : } mBinding.watchView.mBinding.watchName.setOnClickListener { if (DataStoreManager.isLogin()) { - if (watchInfo?.hasWatch==true){ - showWatchBindDialog(watchInfo?.watchNo) - } +// if (watchInfo?.hasWatch==true){ +// showWatchBindDialog(watchInfo?.watchNo) +// } } else { toActivity(LoginActivity::class.java) } @@ -457,6 +467,7 @@ class HomeFragment : mViewModel.getHomeWatchInfo(DataStoreManager.getUserId()) mViewModel.getSysEnCryptInfo(UrlConfig.getHomeBankH5Url()) getBankPointDetail() + loadHealthInfoData() } } @@ -484,8 +495,151 @@ class HomeFragment : mViewModel.getHomeWatchInfo(DataStoreManager.getUserId()) mViewModel.getSysEnCryptInfo(UrlConfig.getHomeBankH5Url()) getBankPointDetail() + loadHealthInfoData() } } + // ==================== 健康资讯相关 ==================== + + /** 初始化健康资讯两个 View 的事件回调 */ + private fun setupHealthViews() { + mHealthInfoRequest = HealthInfoRequest() + + // 健康知识 - Tab 切换加载对应栏目文章 + mBinding.healthKnowledgeView.setOnTabSelectedListener { category -> + loadKnowledgeArticles(category.categoryId) + } + + // 健康知识 - 列表项点击 → 跳转文章详情 H5 + mBinding.healthKnowledgeView.setOnItemClickListener { article -> + navigateToArticleDetail(article.articleId) + } + + // 健康知识 - 更多按钮 → 跳转健康知识 H5 页面 + mBinding.healthKnowledgeView.setOnMoreClickListener { + navigateToHealthKnowledgeMore() + } + + // 健康知识 - 搜索 + mBinding.healthKnowledgeView.setOnSearchClickListener { + navigateToHealthKnowledgeSearch() + } + + + // 健康咨询 - 列表项点击 → 跳转文章详情 H5 + mBinding.healthConsultationView.setOnItemClickListener { article -> + navigateToArticleDetail(article.articleId) + } + + // 健康咨询 - 更多按钮 → 跳转健康咨询 H5 页面 + mBinding.healthConsultationView.setOnMoreClickListener { + navigateToHealthConsultationMore() + } + + + } + + /** 加载健康资讯数据(Token → 栏目 → 文章) */ + private fun loadHealthInfoData() { + mHealthInfoRequest?.fetchToken( + onSuccess = { token -> + mHealthToken = token + loadCategories(token) + loadConsultationArticles(token) + }, + onFailure = { /* Token 获取失败,静默处理 */ } + ) + } + + /** 加载栏目列表并设置健康知识 Tab */ + private fun loadCategories(token: String) { + mHealthInfoRequest?.fetchCategoryList( + token, + onSuccess = { categories -> + // 查找健康知识栏目(categoryId=1)的子栏目 + val knowledgeCategory = categories.find { it.categoryId == 1 } + mKnowledgeCategories.clear() + knowledgeCategory?.children?.let { mKnowledgeCategories.addAll(it) } + mBinding.healthKnowledgeView.setupTabs(mKnowledgeCategories) + + // 默认加载第一个子栏目文章 + if (mKnowledgeCategories.isNotEmpty()) { + loadKnowledgeArticles(mKnowledgeCategories[0].categoryId) + } + }, + onFailure = { /* 栏目加载失败,静默处理 */ } + ) + } + + /** 加载健康知识指定栏目下的文章列表 */ + private fun loadKnowledgeArticles(categoryId: Int) { + mHealthToken?.let { token -> + mHealthInfoRequest?.fetchArticleList( + token, categoryId, + onSuccess = { articles -> + mBinding.healthKnowledgeView.setArticles(articles) + }, + onFailure = { /* 文章加载失败,静默处理 */ } + ) + } + } + + /** 加载健康咨询文章列表(categoryId=2) */ + private fun loadConsultationArticles(token: String) { + mHealthInfoRequest?.fetchArticleList( + token, 2, + onSuccess = { articles-> + mBinding.healthConsultationView.setArticles(articles) + }, + onFailure = { /* 文章加载失败,静默处理 */ } + ) + } + + /** 跳转文章详情 H5 */ + private fun navigateToArticleDetail(articleId: Int) { + val param = mViewModel.enCryptInfoUrl.value + if (param.isNullOrEmpty()) { + showToast("网络错误") + return + } + val url = "${UrlConfig.getHealthNewsDetailH5Url()}?param=$param&articleId=$articleId" + requireContext().startWebActivity(url, isFull = true, myTitle = "文章详情", hideStatus = true) + } + + /** 跳转健康知识更多 H5 */ + private fun navigateToHealthKnowledgeMore() { + val param = mViewModel.enCryptInfoUrl.value + if (param.isNullOrEmpty()) { + mViewModel.getSysEnCryptInfo(UrlConfig.getHomeBankH5Url()) + showToast("网络错误") + return + } + val url = "${UrlConfig.getHealthKnowledgeH5Url()}?param=$param" + requireContext().startWebActivity(url, isFull = true, myTitle = "健康知识", hideStatus = true) + } + /** 跳转健康知识 搜索 */ + private fun navigateToHealthKnowledgeSearch() { + val param = mViewModel.enCryptInfoUrl.value + if (param.isNullOrEmpty()) { + mViewModel.getSysEnCryptInfo(UrlConfig.getHomeBankH5Url()) + showToast("网络错误") + return + } + val url = "${UrlConfig.getHealthNewsSearchH5Url()}?param=$param" + requireContext().startWebActivity(url, isFull = true, myTitle = "搜索", hideStatus = true) + } + + /** 跳转健康咨询更多 H5 */ + private fun navigateToHealthConsultationMore() { + val param = mViewModel.enCryptInfoUrl.value + if (param.isNullOrEmpty()) { + mViewModel.getSysEnCryptInfo(UrlConfig.getHomeBankH5Url()) + showToast("网络错误") + return + } + val url = "${UrlConfig.getHealthConsultationH5Url()}?param=$param" + requireContext().startWebActivity(url, isFull = true, myTitle = "健康咨询", hideStatus = true) + } + } diff --git a/app/src/main/java/com/xjjk/healthyclients/retrofit/UrlConfig.kt b/app/src/main/java/com/xjjk/healthyclients/retrofit/UrlConfig.kt index cc9914b..297449f 100644 --- a/app/src/main/java/com/xjjk/healthyclients/retrofit/UrlConfig.kt +++ b/app/src/main/java/com/xjjk/healthyclients/retrofit/UrlConfig.kt @@ -47,8 +47,10 @@ object UrlConfig { val baseUrlType: BaseUrlType = BaseUrlType.PRODUCT // const val middle = "xj_health/" //test +// const val middleCheck = "healthcheck/" //test const val middle = "hb/" //product - + const val middleCheck = "hb/" //product +// var isOpenIm: Boolean = true enum class BaseUrlType(val type: Int) { @@ -122,6 +124,42 @@ object UrlConfig { } } } + + /** + * 健康资讯 H5 页面基础地址 + */ + fun getHealthNewsH5BaseUrl(): String { + return getDefaultBankBaseUrl() + "healthnewsweb/" + } + + /** + * 健康知识 H5 页面地址 + */ + fun getHealthKnowledgeH5Url(): String { + return getHealthNewsH5BaseUrl() + "healthKnow.html" + } + + /** + * 健康咨询 H5 页面地址 + */ + fun getHealthConsultationH5Url(): String { + return getHealthNewsH5BaseUrl() + "healthNews.html" + } + + /** + * 健康资讯详情 H5 页面地址 + */ + fun getHealthNewsDetailH5Url(): String { + return getHealthNewsH5BaseUrl() + "healthNewsDetail.html" + } + + /** + * 健康资讯搜索 H5 页面地址 + */ + fun getHealthNewsSearchH5Url(): String { + return getHealthNewsH5BaseUrl() + "healthSecrch.html" + } + /** * 方便后续加一些其他逻辑 */ diff --git a/app/src/main/java/com/xjjk/healthyclients/superfuntion/ViewExt.kt b/app/src/main/java/com/xjjk/healthyclients/superfuntion/ViewExt.kt index 094d3f9..2dc9459 100644 --- a/app/src/main/java/com/xjjk/healthyclients/superfuntion/ViewExt.kt +++ b/app/src/main/java/com/xjjk/healthyclients/superfuntion/ViewExt.kt @@ -590,6 +590,7 @@ fun TabLayout.attachViewPager( fun getTabStyle(i: Int): Int { return when (i) { 1 -> R.layout.item_tablayout_group_title + 2 -> R.layout.item_tablayout_group_index_theme//有下标线的绿色 else -> R.layout.item_tablayout_group_title } } diff --git a/app/src/main/java/com/xjjk/healthyclients/view/HealthConsultationView.kt b/app/src/main/java/com/xjjk/healthyclients/view/HealthConsultationView.kt new file mode 100644 index 0000000..5e87905 --- /dev/null +++ b/app/src/main/java/com/xjjk/healthyclients/view/HealthConsultationView.kt @@ -0,0 +1,73 @@ +package com.xjjk.healthyclients.view + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.widget.RelativeLayout +import androidx.databinding.DataBindingUtil +import androidx.recyclerview.widget.LinearLayoutManager +import com.xjjk.healthyclients.R +import com.xjjk.healthyclients.adapter.HealthConsultationAdapter +import com.xjjk.healthyclients.bean.home.ArticleBean +import com.xjjk.healthyclients.databinding.LayoutHealthConsultationBinding + +/** + * 健康咨询 View 组件 + * 头部标题 + 列表(左侧标题+收藏分享信息 / 右侧图片) + */ +class HealthConsultationView(context: Context?, attrs: AttributeSet?) : + RelativeLayout(context, attrs, 0) { + + var mContext: Context? = context + var mBinding: LayoutHealthConsultationBinding = DataBindingUtil.inflate( + LayoutInflater.from(context), + R.layout.layout_health_consultation, this, true + ) + + private val mAdapter = HealthConsultationAdapter() + private var mOnItemClickListener: ((ArticleBean) -> Unit)? = null + private var mOnMoreClickListener: (() -> Unit)? = null + + init { + mBinding.rvList.layoutManager = LinearLayoutManager(mContext) + mBinding.rvList.adapter = mAdapter + + // 列表项点击 + mAdapter.setOnItemClickListener { _, _, position -> + mAdapter.getItem(position)?.let { mOnItemClickListener?.invoke(it) } + } + + // 头部更多按钮点击 + mBinding.ivMore.setOnClickListener { + mOnMoreClickListener?.invoke() + } + + } + + /** 设置文章列表数据(替换),最多取前 2 条 */ + fun setArticles(articles: List?) { + if (articles.isNullOrEmpty()) { + mBinding.rvList.visibility = GONE + mBinding.tvEmpty.visibility = VISIBLE + return + } else { + mBinding.rvList.visibility = VISIBLE + mBinding.tvEmpty.visibility = GONE + } + val topTwo = articles.take(2).toMutableList() + mAdapter.setNewInstance(topTwo) + } + + /** 追加文章列表数据(分页加载) */ + fun addArticles(articles: List) { + mAdapter.addData(articles) + } + + fun setOnItemClickListener(listener: (ArticleBean) -> Unit) { + mOnItemClickListener = listener + } + + fun setOnMoreClickListener(listener: () -> Unit) { + mOnMoreClickListener = listener + } +} diff --git a/app/src/main/java/com/xjjk/healthyclients/view/HealthKnowledgeView.kt b/app/src/main/java/com/xjjk/healthyclients/view/HealthKnowledgeView.kt new file mode 100644 index 0000000..8441779 --- /dev/null +++ b/app/src/main/java/com/xjjk/healthyclients/view/HealthKnowledgeView.kt @@ -0,0 +1,109 @@ +package com.xjjk.healthyclients.view + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.widget.RelativeLayout +import androidx.databinding.DataBindingUtil +import androidx.recyclerview.widget.LinearLayoutManager +import com.xjjk.healthyclients.R +import com.xjjk.healthyclients.adapter.HealthKnowledgeAdapter +import com.xjjk.healthyclients.bean.home.ArticleBean +import com.xjjk.healthyclients.bean.home.CategoryBean +import com.xjjk.healthyclients.databinding.LayoutHealthKnowledgeBinding +import com.xjjk.healthyclients.superfuntion.onCreateTab + +/** + * 健康知识 View 组件 + * 头部标题 + 搜索栏 + TabLayout(医生说/体检/保健/药品/疾病) + 列表 + */ +class HealthKnowledgeView(context: Context?, attrs: AttributeSet?) : + RelativeLayout(context, attrs, 0) { + + var mContext: Context? = context + var mBinding: LayoutHealthKnowledgeBinding = DataBindingUtil.inflate( + LayoutInflater.from(context), + R.layout.layout_health_knowledge, this, true + ) + + private val mAdapter = HealthKnowledgeAdapter() + private var mCategoryList: MutableList = mutableListOf() + private var mOnTabSelectedListener: ((CategoryBean) -> Unit)? = null + private var mOnItemClickListener: ((ArticleBean) -> Unit)? = null + private var mOnMoreClickListener: (() -> Unit)? = null + private var mOnSearchClickListener: (() -> Unit)? = null + + init { + mBinding.rvList.layoutManager = LinearLayoutManager(mContext) + mBinding.rvList.adapter = mAdapter + + // 列表项点击 + mAdapter.setOnItemClickListener { _, _, position -> + mAdapter.getItem(position)?.let { mOnItemClickListener?.invoke(it) } + } + + // 头部更多按钮点击 + mBinding.ivMore.setOnClickListener { + mOnMoreClickListener?.invoke() + } + + // 健康知识 - 搜索 + mBinding.searchView.root.setOnClickListener { + mOnSearchClickListener?.invoke() + } + } + + /** + * 根据栏目列表设置 TabLayout + * @param categories 子栏目列表(健康知识 categoryId=1 的 children) + */ + fun setupTabs(categories: MutableList) { + mCategoryList.clear() + mCategoryList.addAll(categories) + + mBinding.tabLayout.removeAllTabs() + val array = Array(categories.size) { + categories[it].categoryName?:"" + } + mBinding.tabLayout.onCreateTab(array,2){index-> + mOnTabSelectedListener?.invoke(categories[index!!.position]) ?: return@onCreateTab + } + } + + /** 设置文章列表数据(替换) */ + fun setArticles(articles: MutableList?) { + if (articles.isNullOrEmpty()) { + mBinding.rvList.visibility = GONE + mBinding.tvEmpty.visibility = VISIBLE + return + } + + mBinding.rvList.visibility = VISIBLE + mBinding.tvEmpty.visibility = GONE + + articles.take(3).let { + mAdapter.setNewInstance(it.toMutableList()) } + } + + /** 追加文章列表数据(分页加载) */ + fun addArticles(articles: List) { + mAdapter.addData(articles) + } + + + fun setOnTabSelectedListener(listener: (CategoryBean) -> Unit) { + mOnTabSelectedListener = listener + } + + fun setOnItemClickListener(listener: (ArticleBean) -> Unit) { + mOnItemClickListener = listener + } + + fun setOnMoreClickListener(listener: () -> Unit) { + mOnMoreClickListener = listener + } + + fun setOnSearchClickListener(listener: () -> Unit) { + mOnSearchClickListener = listener + } +} diff --git a/app/src/main/java/com/xjjk/healthyclients/view/WatchBindDialog.kt b/app/src/main/java/com/xjjk/healthyclients/view/WatchBindDialog.kt index ff6e710..c8d1500 100644 --- a/app/src/main/java/com/xjjk/healthyclients/view/WatchBindDialog.kt +++ b/app/src/main/java/com/xjjk/healthyclients/view/WatchBindDialog.kt @@ -62,7 +62,7 @@ class WatchBindDialog(context: Context, var listener: (String,Int) -> Unit) : Al if (TextUtils.isEmpty(watchId)) { binding.etWatchid.isEnabled = true binding.confirm.setText("绑定") - type = 0 +// type = 0 } else { binding.etWatchid.isEnabled = false binding.confirm.isEnabled = false diff --git a/app/src/main/res/color/color_child_tab_layout_text_index_theme.xml b/app/src/main/res/color/color_child_tab_layout_text_index_theme.xml new file mode 100644 index 0000000..0cd3e25 --- /dev/null +++ b/app/src/main/res/color/color_child_tab_layout_text_index_theme.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_child_tab_layout_item2.xml b/app/src/main/res/drawable/bg_child_tab_layout_item_index.xml similarity index 100% rename from app/src/main/res/drawable/bg_child_tab_layout_item2.xml rename to app/src/main/res/drawable/bg_child_tab_layout_item_index.xml diff --git a/app/src/main/res/drawable/bg_child_tab_layout_item_line.xml b/app/src/main/res/drawable/bg_child_tab_layout_item_line.xml new file mode 100644 index 0000000..3d7ae4e --- /dev/null +++ b/app/src/main/res/drawable/bg_child_tab_layout_item_line.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_theme_background_shape3.xml b/app/src/main/res/drawable/bg_theme_background_shape3.xml new file mode 100644 index 0000000..52c300e --- /dev/null +++ b/app/src/main/res/drawable/bg_theme_background_shape3.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/layout/custom_search_view_home.xml b/app/src/main/res/layout/custom_search_view_home.xml new file mode 100644 index 0000000..c055dd9 --- /dev/null +++ b/app/src/main/res/layout/custom_search_view_home.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 8166e7b..7465415 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -169,7 +169,22 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_health_knowledge.xml b/app/src/main/res/layout/item_health_knowledge.xml new file mode 100644 index 0000000..5745c55 --- /dev/null +++ b/app/src/main/res/layout/item_health_knowledge.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_tablayout_group_index_theme.xml b/app/src/main/res/layout/item_tablayout_group_index_theme.xml new file mode 100644 index 0000000..da29b45 --- /dev/null +++ b/app/src/main/res/layout/item_tablayout_group_index_theme.xml @@ -0,0 +1,25 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_health_consultation.xml b/app/src/main/res/layout/layout_health_consultation.xml new file mode 100644 index 0000000..be518fc --- /dev/null +++ b/app/src/main/res/layout/layout_health_consultation.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/layout_health_knowledge.xml b/app/src/main/res/layout/layout_health_knowledge.xml new file mode 100644 index 0000000..c296525 --- /dev/null +++ b/app/src/main/res/layout/layout_health_knowledge.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ic_home_know_tag.png b/app/src/main/res/mipmap-xhdpi/ic_home_know_tag.png new file mode 100644 index 0000000..3c2bcab Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_home_know_tag.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_placeholder_rectangle.png b/app/src/main/res/mipmap-xhdpi/ic_placeholder_rectangle.png new file mode 100644 index 0000000..2307d29 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_placeholder_rectangle.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_placeholder_square.png b/app/src/main/res/mipmap-xhdpi/ic_placeholder_square.png new file mode 100644 index 0000000..9148c6e Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_placeholder_square.png differ