diff --git a/app/src/main/java/com/cheng/bole/common/EventConstants.kt b/app/src/main/java/com/cheng/bole/common/EventConstants.kt index 2bed46d..c109381 100644 --- a/app/src/main/java/com/cheng/bole/common/EventConstants.kt +++ b/app/src/main/java/com/cheng/bole/common/EventConstants.kt @@ -19,8 +19,6 @@ object EventConstants { const val PAY_PAY = "client.pay.pay" //支付按钮点击 - const val CHALLENGE_TASK_PAY_PAY = "client.challenge.task.pay.pay" //0元挑战支付按钮点击 - const val PAY_SUCCESS = "client.pay.success" //支付成功 const val PAY_CANCEL = "client.pay.cancel" //支付取消 @@ -34,13 +32,15 @@ object EventConstants { const val PKG_CANCEL = "client.pkg.cancel" //升级弹窗点击取消 + const val BID_TYPE_CHECK = "client.bid.type.check" //标讯类型切换 + + const val JUMP_TO_TOOLS = "client.jump.to.tools" //跳转到企业工具 + const val JUMP_TO_BID_DETAIL = "client.jump.to.bid.detail" //跳转到标讯详情页 const val JUMP_TO_BID_SEARCH = "client.jump.to.bid.search" //跳转到搜索 - const val JUMP_TO_TOOLS = "client.jump.to.tools" //跳转到工具 - - const val DIALOG_GO_TO_VIEW = "client.dialog.go.to.view" //前往保存文件的地址查看 + const val JUMP_TO_SUBSCRIBE = "client.jump.to.subscribe" //跳转到订阅 const val JUMP_TO_ABOUT_US = "client.jump.to.about.us" //界面跳转 @@ -60,14 +60,6 @@ object EventConstants { const val JUMP_TO_ACCOUNT_MANAGE = "client.jump.to.account.manage" //跳转到账号管理 - const val JUMP_TO_RECHARGE_DIAMOND = "client.jump.to.recharge.diamond" //跳转到M币充值 - - const val JUMP_TO_COUPON_LIST = "client.jump.to.coupon.list" //跳转优惠券列表 - - const val JUMP_TO_CHALLENGE_TASK = "client.jump.to.challenge.task" //跳转到0元挑战 - - - const val DOWNLOAD_FILE = "client.download.file" //下载文件 const val DOWNLOAD_FILE_SUCCESS = "client.download.file.success" //下载文件成功 @@ -75,19 +67,6 @@ object EventConstants { const val DOWNLOAD_FILE_ERROR = "client.download.file.error" //下载文件失败 const val TRANSPOND_FILE = "client.transpond.file" //转发文件 - - const val MATERIAL_COPY_TEXT = "client.material.copy.text" //复制文字 - - const val MATERIAL_TYPE_CHECK = "client.material.type.check" //素材切换 - - const val MATERIAL_ALL_SELECT = "client.material.all.select" //全部选中素材 - - const val MATERIAL_SELECT = "client.material.select" //选择素材 - - const val TOOLS_VIDEO_EXTRACT_AUDIO = "client.tools.video.audio" //提取音频 - - const val MATERIAL_PLAY_VIDEO = "client.material.play.video" //播发视频 - const val GET_CODE = "client.get.code" //获取验证码 const val LOGIN = "client.login" //登录 @@ -118,110 +97,13 @@ object EventConstants { const val MEMBER_FORCE_LOGIN = "client.member.force.login" //会员强制登录 - const val GET_MATERIAL_TIMES_USE_UP = "client.times.use.up.get.material" //获取素材次数已用完 - - const val PICTURE_HANDLE_TIMES_USE_UP = "client.times.use.up.picture.handle" //图片处理次数已用完 - const val CHECK_LOGIN_TYPE = "client.check.login.type" //切换登录方式 - const val OPEN_SCREEN_AD_SHOW = "client.ad.open.screen.show" //开屏广告展示 - - const val OPEN_SCREEN_AD_SKIP = "client.ad.open.screen.skip" //开屏广告跳过 - - const val OPEN_SCREEN_AD_CLICK = "client.ad.open.screen.click" //开屏广告点击 - - const val BANNER_AD_SHOW = "client.ad.banner.show" //banner广告展示 - - const val BANNER_AD_CLOSE = "client.ad.banner.close" //banner广告关闭 - - const val BANNER_AD_CLICK = "client.ad.banner.click" //banner广告点击 - - const val INSERT_SCREEN_AD_SHOW = "client.ad.insert.screen.show" //插屏广告展示 - - const val INSERT_SCREEN_AD_CLOSE = "client.ad.insert.screen.close" //插屏广告关闭 - - const val INSERT_SCREEN_AD_CLICK = "client.ad.insert.screen.click" //插屏广告点击 - - const val INSERT_SCREEN_AD_SKIP_VIDEO = "client.ad.insert.screen.skip.video" //跳过插屏广告 - - const val INCENTIVE_AD_SHOW = "client.ad.incentive.show" //激励广告展示 - - const val INCENTIVE_AD_CLOSE = "client.ad.incentive.close" //激励广告关闭 - - const val INCENTIVE_AD_REWARD = "client.ad.incentive.reward" //激励广告已获取到奖励 - - const val INCENTIVE_AD_SKIP_VIDEO = "client.ad.incentive.skip.video" //跳过激励广告 - const val ACCOUNT_UNBIND = "client.account.unbind" //解除绑定账号 - const val HISTORY_RECORD_TYPE_CHECK = "client.history.record.type.check" //历史记录切换 - - const val CLOSE_FREE_TIME_USES_UP_DIALOG = - "client.free.time.uses.up.dialog.close" //关闭免费次数用完的提示框 - - const val CHECK_FREE_TIME_USES_UP_DIALOG = - "client.free.time.uses.up.dialog.check" //免费次数用完的提示框切换充值类型 - - const val CONFIRM_FREE_TIME_USES_UP_DIALOG = - "client.free.time.uses.up.dialog.confirm" //确认免费次数用完的提示框 - - const val MULTI_DELETE_FILE = "client.multi.delete.file" //批量删除文件 - - const val MULTI_TRANSMIT_FILE = "client.multi.transmit.file" //批量转发文件 - - const val PREVIEW_DELETE_FILE = "client.preview.delete.file" //预览时删除文件 - - const val PREVIEW_TRANSMIT_FILE = "client.preview.transmit.file" //预览时删除文件 - - const val PREVIEW_HANDLE_IMAGE = "client.preview.handle.image" //预览时进行图片处理 - - const val TOOLS_HANDLE_IMAGE_START = "client.tools.handle.image.start" //图片处理开始 - - const val TOOLS_HANDLE_SAVE_IMAGE = "client.tools.handle.save.image" //保存已处理过的图片至相册 - - const val AUTO_SWITCH_DOWNLOAD_URL = "client.auto.switch.download.url" //自动切换下载链接 - - const val HAND_SWITCH_DOWNLOAD_URL = "client.hand.switch.download.url" //手动切换下载链接立即加速 - - const val HOME_BANNER_CLICK = "client.home.banner.click" - - const val COUPON_ANIMATION_PLAY = "client.coupon.animation.play" //播放优惠券动画 - - const val COUPON_ANIMATION_CLOSE = "client.coupon.animation.close" //关闭优惠券动画 - - const val COUPON_RECEIVE = "client.coupon.receive" //领取优惠券 - - const val COUPON_REDEEM_ENABLE = "client.coupon.redeem.enable" //优惠券兑换按钮点击 - - const val COUPON_REDEEM_INFO = "client.coupon.redeem.info" //优惠券兑换详情 - - const val COUPON_REDEEM = "client.coupon.redeem" //优惠券兑换 - - const val COUPON_REDEEM_SUCCESS = "client.coupon.redeem.success" //优惠券兑换成功 - - const val COUPON_REDEEM_SUCCESS_CONFIRM = "client.coupon.redeem.success.confirm" //优惠券兑换成功 - - const val COUPON_VIEW = "client.coupon.view" //查看优惠券 - - const val COUPON_DIALOG_CHECK = "client.coupon.dialog.check" //切换优惠券 - - const val COUPON_DIALOG_CLOSE = "client.coupon.dialog.close" //关闭优惠券 - - const val COUPON_DIALOG_CONFIRM = "client.coupon.dialog.confirm" //确认优惠券 - const val COPY_USER_ID = "client.copy_user_id" //复制用户id - const val SHOW_PALYBACK_HINT_DIALOG = "client.show.playback.hint.dialog" - const val EXIT_APP = "client.exit.app" //退出APP const val SHOW_DIALOG = "client.show.dialog" //弹出退出app的弹框 - - const val START_COUPON_ANIMATION = "client.start.coupon.animation" - - const val CHALLENGE_TASK_SIGN_IN = "client.challenge.tasK.sign.in" //签到 - - const val CHALLENGE_TASK_SIGN_IN_SUCCESS = "client.challenge.tasK.sign.in.success" //签到成功 - - const val CHALLENGE_TASK_SIGN_IN_FAIL = "client.challenge.tasK.sign.in.fail" //签到失败 } \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/event/SourceDataEvent.kt b/app/src/main/java/com/cheng/bole/event/SourceDataEvent.kt new file mode 100644 index 0000000..a33fe66 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/event/SourceDataEvent.kt @@ -0,0 +1,6 @@ +package com.cheng.bole.event + +import com.cheng.bole.bean.SourceBean + +class SourceDataEvent(val list: List) { +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/event/SubscriptionEvent.kt b/app/src/main/java/com/cheng/bole/event/SubscriptionEvent.kt new file mode 100644 index 0000000..e430d86 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/event/SubscriptionEvent.kt @@ -0,0 +1,4 @@ +package com.cheng.bole.event + +class SubscriptionEvent { +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/home/zzdb/detail/ZZDBDetailFragment.kt b/app/src/main/java/com/cheng/bole/ui/fragment/home/zzdb/detail/ZZDBDetailFragment.kt index 0a04963..4590357 100644 --- a/app/src/main/java/com/cheng/bole/ui/fragment/home/zzdb/detail/ZZDBDetailFragment.kt +++ b/app/src/main/java/com/cheng/bole/ui/fragment/home/zzdb/detail/ZZDBDetailFragment.kt @@ -7,6 +7,7 @@ import androidx.constraintlayout.widget.ConstraintLayout import com.cheng.bole.R import com.cheng.bole.bean.AreaBean import com.cheng.bole.bean.ZZDBInfoBean +import com.cheng.bole.common.Constants import com.cheng.bole.databinding.FragmentZzdbDetailBinding import com.cheng.bole.ui.dialog.SelectAreaDialog import com.example.base.extensions.gone @@ -34,6 +35,11 @@ class ZZDBDetailFragment : BaseFragment() { + private val tabText = mutableListOf() + private val fragmentList by lazy { mutableListOf() } + private val pageAdapter by lazy { + BasePageAdapter( + childFragmentManager, + tabText, + fragmentList, + FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT + ) + } + override fun initView() { + super.initView() + binding.viewPager.adapter = pageAdapter + ViewPager1Delegate.install(binding.viewPager, binding.tabLayout) + + binding.emptyView.setNoDataLogo(R.mipmap.ic_empty_data) + binding.emptyView.setNoDataText("没有订阅相关商机,请前往订阅设置添加") + binding.emptyView.setBtnText("前往订阅设置") + binding.emptyView.setBtnVisible(true) + binding.emptyView.setStatus(PageStatus.NO_DATA) + binding.emptyView.noDataBtn { + PublicActivity.start(requireContext(), SubscribeFragment::class.java) + } + } + + override fun initData() { + super.initData() + if (UserConfigManager.getBidTypes().isEmpty()) { + mViewModel.getBidTypeList() + } else { + mViewModel.getSubscriptionList() + } + } + + override fun initListener() { + super.initListener() + binding.ivAdd.onClick { + PublicActivity.start(requireContext(), SubscribeFragment::class.java) + EventReportManager.eventReport(EventConstants.JUMP_TO_SUBSCRIBE, "home", "") + } + + binding.tabLayout.observeIndexChange { fromIndex, toIndex, _, _ -> + if (fromIndex != -1) { + (binding.tabLayout.getChildAt(fromIndex) as TextView).typeface = Typeface.DEFAULT + } + (binding.tabLayout.getChildAt(toIndex) as TextView).typeface = Constants.almmsht + } + } + + override fun initObserve() { + super.initObserve() + mViewModel.subscribeLiveData.observe(this) { + fragmentList.clear() + binding.tabLayout.removeAllViews() + if (it.isNotEmpty()) { + if (it.size == 1) { + binding.tabLayout.addView(createTab("专业招标平台")) + fragmentList.add(PushListFragment.newInstance(it[0].id)) + } else { + it.forEach { item -> + binding.tabLayout.addView(createTab(item.name)) + fragmentList.add(PushListFragment.newInstance(item.id)) + } + } + binding.emptyView.setStatus(PageStatus.GONG) + } else { + binding.emptyView.setStatus(PageStatus.NO_DATA) + } + pageAdapter.notifyDataSetChanged() + } + + mViewModel.typeLiveData.observe(this) { + UserConfigManager.saveBidTypes(it) + mViewModel.getSubscriptionList() + } + + val homeRefreshEvent = RxBus.defaultInstance.toObservable(HomeRefreshEvent::class.java).subscribe { + if (UserConfigManager.getBidTypes().isEmpty()) { + mViewModel.getBidTypeList() + } else { + mViewModel.getSubscriptionList() + } + } + addDisposable(homeRefreshEvent) + + val subscriptionEvent = RxBus.defaultInstance.toObservable(SubscriptionEvent::class.java).subscribe { + if (UserConfigManager.getBidTypes().isEmpty()) { + mViewModel.getBidTypeList() + } else { + mViewModel.getSubscriptionList() + } + } + addDisposable(subscriptionEvent) + } + + private fun createTab(name: String): TextView { + tabText.add(name) + + val tvTab = TextView(requireContext()) + tvTab.text = name + tvTab.typeface = Constants.almmsht + tvTab.gravity = Gravity.CENTER + + val lp = DslTabLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, DensityUtils.dp2px(26f)) + lp.marginStart = DensityUtils.dp2px(12f) + lp.marginEnd = DensityUtils.dp2px(12f) + tvTab.layoutParams = lp + + return tvTab + } } \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/PushViewModel.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/PushViewModel.kt index aec3b64..da8fc6c 100644 --- a/app/src/main/java/com/cheng/bole/ui/fragment/push/PushViewModel.kt +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/PushViewModel.kt @@ -1,7 +1,45 @@ package com.cheng.bole.ui.fragment.push +import androidx.lifecycle.MutableLiveData +import com.cheng.bole.bean.BidTypeBean +import com.cheng.bole.bean.SubscriptionBean +import com.cheng.bole.net.ApiFactory +import com.example.base.extensions.toast +import com.example.base.utils.L import com.example.base.viewmodel.BaseViewModel class PushViewModel : BaseViewModel() { + val subscribeLiveData = MutableLiveData>() + val typeLiveData = MutableLiveData>() + + fun getSubscriptionList() { + showDialog() + launchOnUiTryCatch({ + val response = ApiFactory.apiService.getSubscriptionList() + if (response.status) { + subscribeLiveData.postValue(response.data.items) + } else toast(response.message, true) + dismissDialog() + }, { + dismissDialog() + setError(it) + L.d(it) + }) + } + + fun getBidTypeList() { + showDialog() + launchOnUiTryCatch({ + val response = ApiFactory.apiService.getBidTypeList() + if (response.status) { + typeLiveData.postValue(response.data) + } else toast(response.message, true) + dismissDialog() + }, { + dismissDialog() + setError(it) + L.d(it) + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/list/PushListFragment.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/list/PushListFragment.kt new file mode 100644 index 0000000..22535c0 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/list/PushListFragment.kt @@ -0,0 +1,116 @@ +package com.cheng.bole.ui.fragment.push.list + +import android.graphics.Typeface +import android.os.Bundle +import android.view.Gravity +import android.widget.TextView +import com.angcyo.tablayout.DslTabLayout +import com.cheng.bole.R +import com.cheng.bole.bean.BidItemBean +import com.cheng.bole.bean.BidTypeBean +import com.cheng.bole.common.Constants +import com.cheng.bole.common.EventConstants +import com.cheng.bole.databinding.FragmentPushListBinding +import com.cheng.bole.manager.EventReportManager +import com.cheng.bole.manager.UserConfigManager +import com.cheng.bole.ui.activity.PublicActivity +import com.cheng.bole.ui.fragment.bid.BidAdapter +import com.cheng.bole.ui.fragment.bid.detail.BidDetailFragment +import com.cheng.bole.ui.fragment.mine.vip.VipFragment +import com.cheng.bole.ui.fragment.push.subscribe.SubscribeFragment +import com.example.base.decoration.FirstItemOffsetDecoration +import com.example.base.ui.list.ListFragment +import com.example.base.utils.DensityUtils +import com.example.base.widget.PageStatus + +class PushListFragment : ListFragment() { + private val subId by lazy { arguments?.getString("subId") ?: "" } + private val bidType by lazy { UserConfigManager.getBidTypes() } + + private var item: BidItemBean? = null + + companion object { + fun newInstance(subId: String): PushListFragment { + val args = Bundle() + args.putString("subId", subId) + val fragment = PushListFragment() + fragment.arguments = args + return fragment + } + } + + override fun bindAdapter() = BidAdapter() + + override fun noDataClick() { + PublicActivity.start(requireContext(), SubscribeFragment::class.java) + } + + override fun initView() { + super.initView() + mEmptyView.setNoDataLogo(R.mipmap.ic_empty_data) + mEmptyView.setNoDataText("暂无数据") + mEmptyView.setBtnVisible(false) + mEmptyView.setStatus(PageStatus.NO_DATA) + + binding.mRecyclerView.addItemDecoration(FirstItemOffsetDecoration(DensityUtils.dp2px(7f), FirstItemOffsetDecoration.top)) + } + + override fun initData() { + super.initData() + bidType.forEach { + binding.tabLayout.addView(createTab(it)) + } + } + + override fun initListener() { + super.initListener() + binding.tabLayout.observeIndexChange { fromIndex, toIndex, _, _ -> + val type = bidType[toIndex] + mViewModel.params["subId"] = subId + mViewModel.params["typeId"] = type.id + if (fromIndex != -1) { + (binding.tabLayout.getChildAt(fromIndex) as TextView).typeface = Typeface.DEFAULT + (binding.tabLayout.getChildAt(fromIndex) as TextView).setBackgroundResource(R.drawable.shape_push_bid_type_default) + } + (binding.tabLayout.getChildAt(toIndex) as TextView).typeface = Constants.douyinsansB + (binding.tabLayout.getChildAt(toIndex) as TextView).setBackgroundResource(R.drawable.shape_push_bid_type_checked) + EventReportManager.eventReport(EventConstants.BID_TYPE_CHECK, "home", (binding.tabLayout.getChildAt(toIndex) as TextView).text.toString()) + firstLoad() + } + + mAdapter.setOnItemClickListener { _, _, i -> + item = mAdapter.getItem(i) + mViewModel.checkAuth() + } + } + + override fun initObserve() { + super.initObserve() + mViewModel.authLiveData.observe(this) { + if (it.auth) { + PublicActivity.start( + requireContext(), + BidDetailFragment::class.java, + Pair("id", item!!.id), + Pair("info_source", item!!.info_source) + ) + } else { + PublicActivity.start(requireContext(), VipFragment::class.java, Pair("origin", "view_bid")) + } + } + } + + private fun createTab(type: BidTypeBean): TextView { + val tvTab = TextView(requireContext()) + tvTab.text = type.name + tvTab.gravity = Gravity.CENTER + tvTab.setBackgroundResource(R.drawable.shape_push_bid_type_default) + + val lp = DslTabLayout.LayoutParams(DensityUtils.dp2px(84f), DensityUtils.dp2px(34f)) + lp.marginStart = if (binding.tabLayout.childCount != 0) DensityUtils.dp2px(5f) else DensityUtils.dp2px(12f) + lp.marginEnd = if (binding.tabLayout.childCount < bidType.size - 1) DensityUtils.dp2px(5f) else DensityUtils.dp2px(12f) + tvTab.layoutParams = lp + + return tvTab + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/list/PushListViewModel.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/list/PushListViewModel.kt new file mode 100644 index 0000000..29655d9 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/list/PushListViewModel.kt @@ -0,0 +1,31 @@ +package com.cheng.bole.ui.fragment.push.list + +import androidx.collection.ArrayMap +import androidx.lifecycle.MutableLiveData +import com.cheng.bole.bean.BidItemBean +import com.cheng.bole.bean.UserAuthBean +import com.cheng.bole.net.ApiFactory +import com.cheng.bole.net.model.toListResult +import com.example.base.extensions.toast +import com.example.base.utils.L +import com.example.base.viewmodel.ListViewModel + +class PushListViewModel: ListViewModel() { + override suspend fun requestApi(params: ArrayMap): Result> { + return ApiFactory.apiService.getRecommendList(params).toListResult() + } + + val authLiveData = MutableLiveData() + + fun checkAuth() { + launchOnUiTryCatch({ + val response = ApiFactory.apiService.checkAuth() + if (response.status) { + authLiveData.postValue(response.data) + } else toast(response.message, true) + }, { + setError(it) + L.d(it) + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/SubscribeAdapter.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/SubscribeAdapter.kt new file mode 100644 index 0000000..d8eb33f --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/SubscribeAdapter.kt @@ -0,0 +1,51 @@ +package com.cheng.bole.ui.fragment.push.subscribe + +import androidx.recyclerview.widget.RecyclerView +import com.chad.library.adapter.base.BaseQuickAdapter +import com.chad.library.adapter.base.viewholder.BaseViewHolder +import com.cheng.bole.R +import com.cheng.bole.bean.SubscriptionBean +import com.cheng.bole.manager.UserConfigManager + +class SubscribeAdapter: BaseQuickAdapter(R.layout.listitem_subscribe) { + + init { + addChildClickViewIds(R.id.tv_delete, R.id.tv_edit) + } + + override fun convert(holder: BaseViewHolder, item: SubscriptionBean) { + holder.setText(R.id.tv_name, item.name) + + val rvKeyword = holder.getView(R.id.rv_keywords) + val keywordAdapter = KeywordAdapter() + rvKeyword.adapter = keywordAdapter + keywordAdapter.setList(item.keyword) + + val rvCity = holder.getView(R.id.rv_area) + val cityAdapter = CityAdapter() + rvCity.adapter = cityAdapter + if (item.type == 1) { + if (item.city_name.size == UserConfigManager.getCityList().size) { + cityAdapter.setList(listOf("全国")) + } else { + cityAdapter.setList(item.city_name) + } + } else { + cityAdapter.setList(item.source_name) + } + } + + inner class KeywordAdapter: BaseQuickAdapter(R.layout.listitem_subscribe_keyword) { + override fun convert(holder: BaseViewHolder, item: String) { + holder.setText(R.id.tv_name, item) + } + + } + + inner class CityAdapter: BaseQuickAdapter(R.layout.listitem_subscribe_area) { + override fun convert(holder: BaseViewHolder, item: String) { + holder.setText(R.id.tv_name, item) + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/SubscribeFragment.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/SubscribeFragment.kt new file mode 100644 index 0000000..9ff0f16 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/SubscribeFragment.kt @@ -0,0 +1,95 @@ +package com.cheng.bole.ui.fragment.push.subscribe + +import android.text.TextUtils +import com.cheng.bole.R +import com.cheng.bole.common.Constants +import com.cheng.bole.databinding.FragmentSubscribeBinding +import com.cheng.bole.event.SubscriptionEvent +import com.cheng.bole.manager.DialogEnum +import com.cheng.bole.ui.activity.PublicActivity +import com.cheng.bole.ui.dialog.TipDialog +import com.cheng.bole.ui.fragment.push.subscribe.add.AddSubscribeFragment +import com.example.base.common.RxBus +import com.example.base.decoration.FirstItemOffsetDecoration +import com.example.base.extensions.onClick +import com.example.base.extensions.toast +import com.example.base.ui.BaseFragment +import com.example.base.utils.DensityUtils +import com.example.base.widget.EmptyView +import com.example.base.widget.PageStatus + +class SubscribeFragment: BaseFragment() { + private val mAdapter by lazy { SubscribeAdapter() } + private val mEmptyView by lazy { EmptyView(requireContext()) } + + override fun initView() { + super.initView() + mTitleBar?.background = null + + binding.tvTitle.typeface = Constants.pmzdbt + + binding.mRecyclerView.adapter = mAdapter + binding.mRecyclerView.addItemDecoration(FirstItemOffsetDecoration(DensityUtils.dp2px(7f), FirstItemOffsetDecoration.top)) + mEmptyView.setNoDataText("暂无订阅") + mEmptyView.setNoDataLogo(R.mipmap.ic_empty_subscribe) + mEmptyView.setBtnVisible(false) + mAdapter.setEmptyView(mEmptyView) + } + + override fun initData() { + super.initData() + mViewModel.getSubscriptionList() + } + + override fun initListener() { + super.initListener() + + binding.layoutArea.onClick { + PublicActivity.start(requireContext(), AddSubscribeFragment::class.java, Pair("type", 1)) + } + + binding.layoutSource.onClick { + PublicActivity.start(requireContext(), AddSubscribeFragment::class.java, Pair("type", 2)) + } + + mAdapter.setOnItemChildClickListener { _, view, i -> + val item = mAdapter.getItem(i) + when(view.id) { + R.id.tv_delete -> { + val f = TipDialog.newInstance("温馨提示", "您确定要删除订阅吗?") + f.setOnSelectListener { + if (it == DialogEnum.CLICK_OK) { + mViewModel.deleteSubscription(item.id) + } + } + f.show(childFragmentManager, TipDialog::class.java.simpleName) + } + + R.id.tv_edit -> { + PublicActivity.start(requireContext(), AddSubscribeFragment::class.java, Pair("type", item.type), Pair("item", item)) + } + } + } + } + + override fun initObserve() { + super.initObserve() + mViewModel.subscribeLiveData.observe(this) { + mAdapter.setList(it) + if (it.isNotEmpty()) { + mEmptyView.setStatus(PageStatus.GONG) + } else { + mEmptyView.setStatus(PageStatus.NO_DATA) + } + } + + mViewModel.deleteLiveData.observe(this) { + RxBus.defaultInstance.post(SubscriptionEvent()) + toast("删除成功") + } + val subscriptionEvent = RxBus.defaultInstance.toObservable(SubscriptionEvent::class.java).subscribe { + mViewModel.getSubscriptionList() + } + addDisposable(subscriptionEvent) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/SubscribeViewModel.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/SubscribeViewModel.kt new file mode 100644 index 0000000..16b4436 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/SubscribeViewModel.kt @@ -0,0 +1,43 @@ +package com.cheng.bole.ui.fragment.push.subscribe + +import androidx.lifecycle.MutableLiveData +import com.cheng.bole.bean.SubscriptionBean +import com.cheng.bole.net.ApiFactory +import com.example.base.extensions.toast +import com.example.base.utils.L +import com.example.base.viewmodel.BaseViewModel + +class SubscribeViewModel: BaseViewModel() { + val subscribeLiveData = MutableLiveData>() + val deleteLiveData = MutableLiveData() + + fun getSubscriptionList() { + showDialog() + launchOnUiTryCatch({ + val response = ApiFactory.apiService.getSubscriptionList() + if (response.status) { + subscribeLiveData.postValue(response.data.items) + } else toast(response.message, true) + dismissDialog() + }, { + dismissDialog() + setError(it) + L.d(it) + }) + } + + fun deleteSubscription(id: String) { + showDialog() + launchOnUiTryCatch({ + val response = ApiFactory.apiService.deleteSubscription(id) + if (response.status) { + deleteLiveData.postValue(Any()) + } else toast(response.message, true) + dismissDialog() + }, { + dismissDialog() + setError(it) + L.d(it) + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/add/AddSubscribeFragment.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/add/AddSubscribeFragment.kt new file mode 100644 index 0000000..a7941d2 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/add/AddSubscribeFragment.kt @@ -0,0 +1,391 @@ +package com.cheng.bole.ui.fragment.push.subscribe.add + +import android.annotation.SuppressLint +import android.graphics.Color +import android.os.Build +import android.text.TextUtils +import android.view.View +import android.view.animation.RotateAnimation +import com.cheng.bole.R +import com.cheng.bole.bean.AreaBean +import com.cheng.bole.bean.HotWordBean +import com.cheng.bole.bean.SourceBean +import com.cheng.bole.bean.SubscriptionBean +import com.cheng.bole.databinding.FragmentAddSubscribeBinding +import com.cheng.bole.event.SourceDataEvent +import com.cheng.bole.event.SubscriptionEvent +import com.cheng.bole.manager.NotificationHelper +import com.cheng.bole.manager.UserConfigManager +import com.cheng.bole.ui.activity.PublicActivity +import com.cheng.bole.ui.dialog.SelectAreaDialog +import com.cheng.bole.ui.fragment.mine.vip.VipFragment +import com.cheng.bole.ui.fragment.push.subscribe.source.SourceSearchFragment +import com.cheng.bole.utils.PermissionUtils +import com.example.base.common.RxBus +import com.example.base.decoration.GridSpaceItemDecoration +import com.example.base.extensions.getColor +import com.example.base.extensions.gone +import com.example.base.extensions.invisible +import com.example.base.extensions.onClick +import com.example.base.extensions.toast +import com.example.base.extensions.visible +import com.example.base.ui.BaseFragment +import com.example.base.utils.DensityUtils +import com.example.base.utils.SpanUtils +import com.google.android.flexbox.FlexDirection +import com.google.android.flexbox.FlexWrap +import com.google.android.flexbox.FlexboxLayoutManager +import com.google.android.flexbox.JustifyContent +import com.google.gson.Gson +import com.google.gson.JsonObject +import okhttp3.RequestBody.Companion.toRequestBody + +class AddSubscribeFragment : BaseFragment() { + private val type by lazy { arguments?.getInt("type") ?: 1 } // 1 地区 2 数据源 + private var subscription: SubscriptionBean? = null + + private val selectedKeywordAdapter by lazy { SelectedKeywordAdapter() } + private val keywordAdapter by lazy { RecommendKeywordAdapter() } + + private val selectedCity = arrayListOf() + private val selectedSource = arrayListOf() + + private var pushType = 3 //1 短信 2 邮箱 3 app推送 + + override fun initView() { + super.initView() + mTitleBar?.setBackgroundColor(Color.WHITE) + + val layoutManager = FlexboxLayoutManager(requireContext()) + layoutManager.flexDirection = FlexDirection.ROW + layoutManager.flexWrap = FlexWrap.WRAP + layoutManager.justifyContent = JustifyContent.FLEX_START + binding.rvSelectedKeywords.layoutManager = layoutManager + binding.rvSelectedKeywords.adapter = selectedKeywordAdapter + + binding.rvKeywords.adapter = keywordAdapter + binding.rvKeywords.addItemDecoration(GridSpaceItemDecoration(3, DensityUtils.dp2px(10f), DensityUtils.dp2px(10f))) + } + + override fun initData() { + super.initData() + subscription = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + arguments?.getSerializable("item", SubscriptionBean::class.java) + } else { + arguments?.getSerializable("item") as? SubscriptionBean + } + setData() + + mViewModel.getKeywords("") + } + + @SuppressLint("NotifyDataSetChanged") + override fun initListener() { + super.initListener() + + binding.tvArea.onClick { + val f = SelectAreaDialog.newInstance(selectedCity) + f.setOnSelectListener { list -> + selectedCity.clear() + list.forEach { item -> selectedCity.add(item) } + binding.tvArea.text = + if (selectedCity.size == UserConfigManager.getCityList().size) "全国" else selectedCity.joinToString(",") { it.name } + } + f.show(childFragmentManager, SelectAreaDialog::class.java.simpleName) + } + + binding.tvSource.onClick { + PublicActivity.start(requireContext(), SourceSearchFragment::class.java, Pair("list", Gson().toJson(selectedSource))) + } + + binding.tvNotificationState.onClick { + if (!NotificationHelper.isNotificationEnabled(requireContext())) { + PermissionUtils.checkNotificationPermission(requireActivity()) { + updatePushType() + } + } + } + + binding.layoutRefresh.onClick { + startRotate() + mViewModel.getKeywords(if (keywordAdapter.data.isNotEmpty()) keywordAdapter.data.last().name else "") + } + + binding.tvAddKeywords.onClick { + val keyword = binding.etKeyword.text.toString().trim() + if (TextUtils.isEmpty(keyword)) { + toast("请输入关键词") + return@onClick + } + if (selectedKeywordAdapter.data.size == 5) { + toast("最多添加5个关键词") + return@onClick + } + selectedKeywordAdapter.addData(keyword) + SpanUtils.with(binding.tvKeywordsCount) + .append("${selectedKeywordAdapter.data.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/5") + .create() + binding.etKeyword.setText("") + binding.rvSelectedKeywords.visible() + } + + selectedKeywordAdapter.setOnItemChildClickListener { _, view, i -> + when (view.id) { + R.id.iv_delete -> { + selectedKeywordAdapter.removeAt(i) + if (selectedKeywordAdapter.data.isEmpty()) { + binding.rvSelectedKeywords.gone() + } + SpanUtils.with(binding.tvKeywordsCount) + .append("${selectedKeywordAdapter.data.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/5") + .create() + } + } + } + + keywordAdapter.setOnItemClickListener { _, _, i -> + val item = keywordAdapter.getItem(i) + + if (selectedKeywordAdapter.data.size == 5) { + toast("最多添加5个关键词") + return@setOnItemClickListener + } + if (selectedKeywordAdapter.data.contains(item.name)) { + toast("关键词已存在") + return@setOnItemClickListener + } + + selectedKeywordAdapter.addData(item.name) + SpanUtils.with(binding.tvKeywordsCount) + .append("${selectedKeywordAdapter.data.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/5") + .create() + binding.rvSelectedKeywords.visible() + } + + binding.rgPushType.setOnCheckedChangeListener { group, checkedId -> + when (checkedId) { + R.id.rb1 -> pushType = 1 + + R.id.rb2 -> pushType = 2 + + R.id.rb3 -> pushType = 3 + } + updatePushType() + } + + binding.tv1.onClick { + binding.rb1.isChecked = true + } + + binding.tv2.onClick { + binding.rb2.isChecked = true + } + + binding.tv3.onClick { + binding.rb3.isChecked = true + } + + binding.btnNext.onClick { + val phone = binding.etPhone.text.toString() + val email = binding.etEmail.text.toString() + if ((!TextUtils.isEmpty(phone) && pushType == 1) || (!TextUtils.isEmpty(email) && pushType == 2) || type == 2) { + mViewModel.checkAuth() + } else { + commit() + } + } + } + + override fun initObserve() { + super.initObserve() + mViewModel.keywordsLiveData.observe(this) { + val list = mutableListOf() + it.forEach { keyword -> + list.add(HotWordBean.Child(name = keyword)) + } + keywordAdapter.setList(list) + } + + mViewModel.authLiveData.observe(this) { + if (it.auth) { + commit() + } else { + PublicActivity.start(requireContext(), VipFragment::class.java, Pair("origin", "subscribe")) + } + } + + mViewModel.addLiveData.observe(this) { + toast(if (subscription == null) "添加成功" else "修改成功") + RxBus.defaultInstance.post(SubscriptionEvent()) + requireActivity().finish() + } + + val sourceEvent = RxBus.defaultInstance.toObservable(SourceDataEvent::class.java).subscribe { + selectedSource.clear() + selectedSource.addAll(it.list) + SpanUtils.with(binding.tvSource) + .append("已增加 (") + .append("${selectedSource.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/5)") + .create() + } + addDisposable(sourceEvent) + } + + private fun commit() { + val name = binding.etName.text.toString().trim() + val phone = binding.etPhone.text.toString() + val email = binding.etEmail.text.toString() + if (type == 1 && selectedCity.isEmpty()) { + toast("请选择订阅地区") + return + } + if (type == 2 && selectedSource.isEmpty()) { + toast("请选择数据源") + return + } + if (selectedKeywordAdapter.data.isEmpty()) { + toast("请添加关键词") + return + } + if (pushType == 1 && TextUtils.isEmpty(phone)) { + toast("请输入订阅手机号") + return + } + if (pushType == 2 && TextUtils.isEmpty(email)) { + toast("请输入订阅邮箱") + return + } + + val jsonObject = JsonObject() + jsonObject.addProperty("name", if (!TextUtils.isEmpty(name)) name else "默认订阅") + jsonObject.addProperty("keyword", selectedKeywordAdapter.data.joinToString(",")) + jsonObject.addProperty("push_type", "$pushType") + jsonObject.addProperty("push_receiver", if (pushType == 1) phone else if (pushType == 2) email else "") + if (type == 1) { + jsonObject.addProperty("type", "1") + jsonObject.addProperty("city_id", selectedCity.joinToString(",") { it.id.toString() }) + jsonObject.addProperty("source_id", "") + + } else { + jsonObject.addProperty("type", "2") + jsonObject.addProperty("source_id", selectedSource.joinToString(",") { it.id }) + jsonObject.addProperty("city_id", "") + } + if (subscription != null) { + jsonObject.addProperty("id", subscription!!.id) + mViewModel.updateSubscription(jsonObject.toString().toRequestBody()) + } else { + mViewModel.addSubscription(jsonObject.toString().toRequestBody()) + } + } + + private fun setData() { + if (type == 1) { + binding.tvTitle.text = "地区订阅" + binding.ivVipTag.gone() + binding.layoutArea.visible() + binding.layoutSource.invisible() + binding.ivVipTag1.visible() + binding.ivVipTag2.visible() + } else { + binding.tvTitle.text = "数据源订阅" + binding.ivVipTag.visible() + binding.layoutArea.invisible() + binding.layoutSource.visible() + binding.ivVipTag1.gone() + binding.ivVipTag2.gone() + } + + if (subscription != null) { + binding.etName.setText(subscription!!.name) + + val cityList = UserConfigManager.getCityList() + subscription!!.city_id.forEach { id -> + val city = cityList.find { it.id == id.toInt() } + if (city != null) selectedCity.add(city) + } + binding.tvArea.text = + if (subscription!!.city_name.size == UserConfigManager.getCityList().size) "全国" else subscription!!.city_name.joinToString(",") + + selectedSource.addAll(subscription!!.source) + SpanUtils.with(binding.tvSource) + .append("已增加 (") + .append("${subscription!!.source.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/5)") + .create() + + selectedKeywordAdapter.setList(subscription!!.keyword) + SpanUtils.with(binding.tvKeywordsCount) + .append("${subscription!!.keyword.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/5") + .create() + binding.rvSelectedKeywords.visibility = if (subscription!!.keyword.isNotEmpty()) View.VISIBLE else View.GONE + + pushType = if (!TextUtils.isEmpty(subscription!!.push_type)) subscription!!.push_type.toInt() else 3 + updatePushType(subscription!!.push_receiver) + } else { + SpanUtils.with(binding.tvSource) + .append("已增加 (") + .append("0") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/5)") + .create() + + SpanUtils.with(binding.tvKeywordsCount) + .append("0") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/5") + .create() + + updatePushType() + } + } + + private fun updatePushType(receiver: String? = null) { + when (pushType) { + 1 -> { + binding.etPhone.setText(receiver) + + binding.etPhone.visible() + binding.etEmail.gone() + binding.layoutNotificationState.gone() + } + 2 -> { + binding.etEmail.setText(receiver) + binding.etPhone.gone() + binding.etEmail.visible() + binding.layoutNotificationState.gone() + } + 3 -> { + if (NotificationHelper.isNotificationEnabled(requireContext())) { + binding.tvNotificationState.text = "已授权" + } else { + binding.tvNotificationState.text = "" + } + + binding.etPhone.gone() + binding.etEmail.gone() + binding.layoutNotificationState.visible() + } + } + } + + private fun startRotate() { + if (binding.ivRefreshKeywords.animation != null) { + binding.ivRefreshKeywords.animation.cancel() + } + val anim = RotateAnimation(0f, 360f, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f) + anim.duration = 1000 + binding.ivRefreshKeywords.startAnimation(anim) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/add/AddSubscribeViewModel.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/add/AddSubscribeViewModel.kt new file mode 100644 index 0000000..fd93528 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/add/AddSubscribeViewModel.kt @@ -0,0 +1,73 @@ +package com.cheng.bole.ui.fragment.push.subscribe.add + +import androidx.lifecycle.MutableLiveData +import com.cheng.bole.bean.UserAuthBean +import com.cheng.bole.net.ApiFactory +import com.example.base.extensions.toast +import com.example.base.utils.L +import com.example.base.viewmodel.BaseViewModel +import okhttp3.RequestBody + +class AddSubscribeViewModel : BaseViewModel() { + val keywordsLiveData = MutableLiveData>() + val addLiveData = MutableLiveData() + + fun getKeywords(query: String) { + launchOnUiTryCatch({ + val params = mutableMapOf() + params["query"] = query + params["size"] = "9" + val response = ApiFactory.apiService.getHotKeywords(params) + if (response.status) { + keywordsLiveData.postValue(response.data) + } else toast(response.message, true) + }, { + setError(it) + L.d(it) + }) + } + + fun addSubscription(requestBody: RequestBody) { + showDialog() + launchOnUiTryCatch({ + val response = ApiFactory.apiService.addSubscription(requestBody) + if (response.status) { + addLiveData.postValue(Any()) + } else toast(response.message, true) + dismissDialog() + }, { + dismissDialog() + setError(it) + L.d(it) + }) + } + + fun updateSubscription(requestBody: RequestBody) { + showDialog() + launchOnUiTryCatch({ + val response = ApiFactory.apiService.updateSubscription(requestBody) + if (response.status) { + addLiveData.postValue(Any()) + } else toast(response.message, true) + dismissDialog() + }, { + dismissDialog() + setError(it) + L.d(it) + }) + } + + val authLiveData = MutableLiveData() + + fun checkAuth() { + launchOnUiTryCatch({ + val response = ApiFactory.apiService.checkAuth() + if (response.status) { + authLiveData.postValue(response.data) + } else toast(response.message, true) + }, { + setError(it) + L.d(it) + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/add/RecommendKeywordAdapter.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/add/RecommendKeywordAdapter.kt new file mode 100644 index 0000000..fc744a6 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/add/RecommendKeywordAdapter.kt @@ -0,0 +1,12 @@ +package com.cheng.bole.ui.fragment.push.subscribe.add + +import com.chad.library.adapter.base.BaseQuickAdapter +import com.chad.library.adapter.base.viewholder.BaseViewHolder +import com.cheng.bole.R +import com.cheng.bole.bean.HotWordBean + +class RecommendKeywordAdapter: BaseQuickAdapter(R.layout.listitem_recommend_keywords) { + override fun convert(holder: BaseViewHolder, item: HotWordBean.Child) { + holder.setText(R.id.tv_name, item.name) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/add/SelectedKeywordAdapter.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/add/SelectedKeywordAdapter.kt new file mode 100644 index 0000000..fb0345b --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/add/SelectedKeywordAdapter.kt @@ -0,0 +1,16 @@ +package com.cheng.bole.ui.fragment.push.subscribe.add + +import com.chad.library.adapter.base.BaseQuickAdapter +import com.chad.library.adapter.base.viewholder.BaseViewHolder +import com.cheng.bole.R + +class SelectedKeywordAdapter: BaseQuickAdapter(R.layout.listitem_selected_keywords) { + + init { + addChildClickViewIds(R.id.iv_delete) + } + + override fun convert(holder: BaseViewHolder, item: String) { + holder.setText(R.id.tv_name, item) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/RecommendSourceAdapter.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/RecommendSourceAdapter.kt new file mode 100644 index 0000000..2580607 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/RecommendSourceAdapter.kt @@ -0,0 +1,38 @@ +package com.cheng.bole.ui.fragment.push.subscribe.source + +import com.chad.library.adapter.base.BaseQuickAdapter +import com.chad.library.adapter.base.viewholder.BaseViewHolder +import com.cheng.bole.R +import com.cheng.bole.bean.SourceBean + +class RecommendSourceAdapter: BaseQuickAdapter(R.layout.listitem_recommend_source) { + override fun convert(holder: BaseViewHolder, item: SourceBean) { + holder.setText(R.id.tv_name, item.name) + when(holder.layoutPosition) { + 0 -> { + holder.setImageResource(R.id.iv_tag1, R.mipmap.ic_recommend_source_tag1) + holder.setVisible(R.id.iv_tag1, true) + holder.setVisible(R.id.iv_tag2, true) + holder.setGone(R.id.tv_index, true) + } + 1 -> { + holder.setImageResource(R.id.iv_tag1, R.mipmap.ic_recommend_source_tag2) + holder.setVisible(R.id.iv_tag1, true) + holder.setVisible(R.id.iv_tag2, true) + holder.setGone(R.id.tv_index, true) + } + 2 -> { + holder.setImageResource(R.id.iv_tag1, R.mipmap.ic_recommend_source_tag3) + holder.setVisible(R.id.iv_tag1, true) + holder.setVisible(R.id.iv_tag2, true) + holder.setGone(R.id.tv_index, true) + } + else -> { + holder.setText(R.id.tv_index, "${holder.layoutPosition + 1}") + holder.setVisible(R.id.tv_index, true) + holder.setGone(R.id.iv_tag1, true) + holder.setVisible(R.id.iv_tag2, false) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/SearchSourceAdapter.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/SearchSourceAdapter.kt new file mode 100644 index 0000000..fd66d82 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/SearchSourceAdapter.kt @@ -0,0 +1,33 @@ +package com.cheng.bole.ui.fragment.push.subscribe.source + +import com.chad.library.adapter.base.BaseQuickAdapter +import com.chad.library.adapter.base.viewholder.BaseViewHolder +import com.cheng.bole.R +import com.cheng.bole.bean.SourceBean +import com.example.base.extensions.getColor +import com.example.base.utils.SpanUtils + +class SearchSourceAdapter: BaseQuickAdapter(R.layout.listitem_search_source_result) { + private var keyword: String = "" + + override fun convert(holder: BaseViewHolder, item: SourceBean) { + val name = item.name + val index = name.indexOf(keyword) + if (index != -1) { + val startText = name.take(index) + val endText = name.substring(index + keyword.length, name.length) + SpanUtils.with(holder.getView(R.id.tv_name)) + .append(startText) + .append(keyword) + .setForegroundColor(getColor(R.color.color_ff493c)) + .append(endText) + .create() + } else { + holder.setText(R.id.tv_name, name) + } + } + + fun setKeyword(keyword: String) { + this.keyword = keyword + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/SelectedSourceAdapter.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/SelectedSourceAdapter.kt new file mode 100644 index 0000000..40fcfd0 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/SelectedSourceAdapter.kt @@ -0,0 +1,17 @@ +package com.cheng.bole.ui.fragment.push.subscribe.source + +import com.chad.library.adapter.base.BaseQuickAdapter +import com.chad.library.adapter.base.viewholder.BaseViewHolder +import com.cheng.bole.R +import com.cheng.bole.bean.SourceBean + +class SelectedSourceAdapter: BaseQuickAdapter(R.layout.listitem_selected_source) { + + init { + addChildClickViewIds(R.id.iv_delete) + } + + override fun convert(holder: BaseViewHolder, item: SourceBean) { + holder.setText(R.id.tv_name, item.name) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/SourceSearchFragment.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/SourceSearchFragment.kt new file mode 100644 index 0000000..e243d25 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/SourceSearchFragment.kt @@ -0,0 +1,170 @@ +package com.cheng.bole.ui.fragment.push.subscribe.source + +import android.text.TextUtils +import com.cheng.bole.R +import com.cheng.bole.bean.SourceBean +import com.cheng.bole.databinding.FragmentSourceSearchBinding +import com.cheng.bole.event.SourceDataEvent +import com.cheng.bole.impl.TextWatcherImpl +import com.example.base.common.RxBus +import com.example.base.decoration.DividerItemDecoration +import com.example.base.extensions.getColor +import com.example.base.extensions.gone +import com.example.base.extensions.onClick +import com.example.base.extensions.toast +import com.example.base.extensions.visible +import com.example.base.ui.BaseFragment +import com.example.base.utils.DensityUtils +import com.example.base.utils.SpanUtils +import com.example.base.widget.EmptyView +import com.example.base.widget.PageStatus +import com.google.android.flexbox.FlexDirection +import com.google.android.flexbox.FlexWrap +import com.google.android.flexbox.FlexboxLayoutManager +import com.google.android.flexbox.JustifyContent +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken + +class SourceSearchFragment: BaseFragment() { + private val selectedAdapter by lazy { SelectedSourceAdapter() } + private val recommendAdapter by lazy { RecommendSourceAdapter() } + private val resultAdapter by lazy { SearchSourceAdapter() } + + private val resultEmptyView by lazy { EmptyView(requireContext()) } + + override fun initView() { + super.initView() + val layoutManager = FlexboxLayoutManager(requireContext()) + layoutManager.flexDirection = FlexDirection.ROW + layoutManager.flexWrap = FlexWrap.WRAP + layoutManager.justifyContent = JustifyContent.FLEX_START + binding.rvSelected.layoutManager = layoutManager + binding.rvSelected.adapter = selectedAdapter + + binding.rvRecommend.adapter = recommendAdapter + binding.rvRecommend.addItemDecoration(DividerItemDecoration(DensityUtils.dp2px(14f), DensityUtils.dp2px(14f), color = getColor(R.color.color_eeeeee))) + + binding.rvResult.adapter = resultAdapter + resultEmptyView.setNoDataLogo(R.mipmap.ic_empty_data) + resultEmptyView.setNoDataText("暂无数据") + resultAdapter.setEmptyView(resultEmptyView) + } + + override fun initData() { + super.initData() + mViewModel.getHotSources() + + val listStr = arguments?.getString("list") + if (!TextUtils.isEmpty(listStr)) { + selectedAdapter.setList(Gson().fromJson(listStr, object : TypeToken>() {}.type)) + if (selectedAdapter.data.isNotEmpty()) { + SpanUtils.with(binding.tvSelectedCount) + .append("(") + .append("${selectedAdapter.data.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/5)") + .create() + binding.layoutSelected.visible() + } + } + } + + override fun initListener() { + super.initListener() + binding.layoutResult.onClick { + binding.layoutResult.gone() + } + + binding.etSearch.addTextChangedListener(object : TextWatcherImpl() { + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + super.onTextChanged(s, start, before, count) + resultAdapter.setKeyword(s.toString()) + if (!TextUtils.isEmpty(s?.trim())) { + mViewModel.search(s.toString()) + binding.layoutResult.visible() + } else { + binding.layoutResult.gone() + } + } + }) + + recommendAdapter.setOnItemClickListener { _, _, i -> + val item = recommendAdapter.getItem(i) + if (selectedAdapter.data.size == 5) { + toast("最多添加5个数据源") + return@setOnItemClickListener + } + if (selectedAdapter.data.find { it.id == item.id } != null){ + toast("数据源已存在") + return@setOnItemClickListener + } + selectedAdapter.addData(item) + SpanUtils.with(binding.tvSelectedCount) + .append("(") + .append("${selectedAdapter.data.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/5)") + .create() + binding.layoutSelected.visible() + } + + resultAdapter.setOnItemClickListener { _, _, i -> + val item = resultAdapter.getItem(i) + if (selectedAdapter.data.size == 5) { + toast("最多添加5个数据源") + return@setOnItemClickListener + } + if (selectedAdapter.data.find { it.id == item.id } != null){ + toast("数据源已存在") + return@setOnItemClickListener + } + selectedAdapter.addData(item) + SpanUtils.with(binding.tvSelectedCount) + .append("(") + .append("${selectedAdapter.data.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/5)") + .create() + binding.layoutSelected.visible() + binding.layoutResult.gone() + } + + selectedAdapter.setOnItemChildClickListener { _, view, i -> + when(view.id) { + R.id.iv_delete -> { + selectedAdapter.removeAt(i) + SpanUtils.with(binding.tvSelectedCount) + .append("(") + .append("${selectedAdapter.data.size}") + .setForegroundColor(getColor(R.color.color_ff493c)) + .append("/5)") + .create() + if (selectedAdapter.data.isEmpty()) { + binding.layoutSelected.gone() + } + } + } + } + } + + override fun initObserve() { + super.initObserve() + mViewModel.hotLiveData.observe(this) { + recommendAdapter.setList(it) + } + + mViewModel.searchLiveData.observe(this) { + resultAdapter.setList(it) + if (it.isNotEmpty()) { + resultEmptyView.setStatus(PageStatus.GONG) + } else { + resultEmptyView.setStatus(PageStatus.NO_DATA) + } + } + } + + override fun onDestroy() { + RxBus.defaultInstance.post(SourceDataEvent(selectedAdapter.data)) + super.onDestroy() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/SourceSearchViewModel.kt b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/SourceSearchViewModel.kt new file mode 100644 index 0000000..b0362f8 --- /dev/null +++ b/app/src/main/java/com/cheng/bole/ui/fragment/push/subscribe/source/SourceSearchViewModel.kt @@ -0,0 +1,40 @@ +package com.cheng.bole.ui.fragment.push.subscribe.source + +import androidx.lifecycle.MutableLiveData +import com.cheng.bole.bean.SourceBean +import com.cheng.bole.net.ApiFactory +import com.example.base.extensions.toast +import com.example.base.utils.L +import com.example.base.viewmodel.BaseViewModel + +class SourceSearchViewModel: BaseViewModel() { + val hotLiveData = MutableLiveData>() + val searchLiveData = MutableLiveData>() + + fun getHotSources() { + showDialog() + launchOnUiTryCatch({ + val response = ApiFactory.apiService.getHotSources() + if (response.status) { + hotLiveData.postValue(response.data.items) + } else toast(response.message, true) + dismissDialog() + }, { + dismissDialog() + setError(it) + L.d(it) + }) + } + + fun search(keyword: String) { + launchOnUiTryCatch({ + val response = ApiFactory.apiService.searchSource(keyword) + if (response.status) { + searchLiveData.postValue(response.data.items) + } else toast(response.message, true) + }, { + setError(it) + L.d(it) + }) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/selector_rb.xml b/app/src/main/res/drawable/selector_rb.xml new file mode 100644 index 0000000..7ed0278 --- /dev/null +++ b/app/src/main/res/drawable/selector_rb.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_dddddd_line_cor8.xml b/app/src/main/res/drawable/shape_dddddd_line_cor8.xml new file mode 100644 index 0000000..6519ea5 --- /dev/null +++ b/app/src/main/res/drawable/shape_dddddd_line_cor8.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_dde2eb_dash_divider_h.xml b/app/src/main/res/drawable/shape_dde2eb_dash_divider_h.xml new file mode 100644 index 0000000..46717bd --- /dev/null +++ b/app/src/main/res/drawable/shape_dde2eb_dash_divider_h.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_f8f9fa_cor10.xml b/app/src/main/res/drawable/shape_f8f9fa_cor10.xml new file mode 100644 index 0000000..7c9f5b4 --- /dev/null +++ b/app/src/main/res/drawable/shape_f8f9fa_cor10.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_f8f9fa_cor6.xml b/app/src/main/res/drawable/shape_f8f9fa_cor6.xml new file mode 100644 index 0000000..e28a99a --- /dev/null +++ b/app/src/main/res/drawable/shape_f8f9fa_cor6.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_keyword_checked.xml b/app/src/main/res/drawable/shape_keyword_checked.xml new file mode 100644 index 0000000..d86c0c5 --- /dev/null +++ b/app/src/main/res/drawable/shape_keyword_checked.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_keyword_default.xml b/app/src/main/res/drawable/shape_keyword_default.xml new file mode 100644 index 0000000..642a5ea --- /dev/null +++ b/app/src/main/res/drawable/shape_keyword_default.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_push_bid_type_checked.xml b/app/src/main/res/drawable/shape_push_bid_type_checked.xml new file mode 100644 index 0000000..14bbbd0 --- /dev/null +++ b/app/src/main/res/drawable/shape_push_bid_type_checked.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_push_bid_type_default.xml b/app/src/main/res/drawable/shape_push_bid_type_default.xml new file mode 100644 index 0000000..27f5d35 --- /dev/null +++ b/app/src/main/res/drawable/shape_push_bid_type_default.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_selected_keyword_bg.xml b/app/src/main/res/drawable/shape_selected_keyword_bg.xml new file mode 100644 index 0000000..0218a4a --- /dev/null +++ b/app/src/main/res/drawable/shape_selected_keyword_bg.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_white_cor14.xml b/app/src/main/res/drawable/shape_white_cor14.xml new file mode 100644 index 0000000..88f14dc --- /dev/null +++ b/app/src/main/res/drawable/shape_white_cor14.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_zzdb_btn_bg.xml b/app/src/main/res/drawable/shape_zzdb_btn_bg.xml new file mode 100644 index 0000000..6a99f39 --- /dev/null +++ b/app/src/main/res/drawable/shape_zzdb_btn_bg.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_add_subscribe.xml b/app/src/main/res/layout/fragment_add_subscribe.xml new file mode 100644 index 0000000..26e4186 --- /dev/null +++ b/app/src/main/res/layout/fragment_add_subscribe.xml @@ -0,0 +1,611 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_push.xml b/app/src/main/res/layout/fragment_push.xml index 77d9ef6..efdd582 100644 --- a/app/src/main/res/layout/fragment_push.xml +++ b/app/src/main/res/layout/fragment_push.xml @@ -1,6 +1,50 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_push_list.xml b/app/src/main/res/layout/fragment_push_list.xml new file mode 100644 index 0000000..e4e7137 --- /dev/null +++ b/app/src/main/res/layout/fragment_push_list.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_source_search.xml b/app/src/main/res/layout/fragment_source_search.xml new file mode 100644 index 0000000..3c5a327 --- /dev/null +++ b/app/src/main/res/layout/fragment_source_search.xml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_subscribe.xml b/app/src/main/res/layout/fragment_subscribe.xml new file mode 100644 index 0000000..da08c90 --- /dev/null +++ b/app/src/main/res/layout/fragment_subscribe.xml @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_zzdb_detail.xml b/app/src/main/res/layout/fragment_zzdb_detail.xml index 7469c72..7210059 100644 --- a/app/src/main/res/layout/fragment_zzdb_detail.xml +++ b/app/src/main/res/layout/fragment_zzdb_detail.xml @@ -142,6 +142,7 @@ android:layout_marginStart="@dimen/dp_20" android:layout_marginTop="@dimen/dp_30" android:layout_marginEnd="@dimen/dp_20" + android:weightSum="3" android:orientation="horizontal" app:layout_constraintTop_toTopOf="parent"> @@ -679,23 +680,30 @@ android:background="@color/color_ebebeb" app:layout_constraintTop_toBottomOf="@id/et_code" /> - + app:layout_constraintTop_toBottomOf="@id/view_line4" + android:layout_marginEnd="@dimen/dp_12"> + + + diff --git a/app/src/main/res/layout/listitem_recommend_keywords.xml b/app/src/main/res/layout/listitem_recommend_keywords.xml new file mode 100644 index 0000000..28c0e1b --- /dev/null +++ b/app/src/main/res/layout/listitem_recommend_keywords.xml @@ -0,0 +1,21 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/listitem_recommend_source.xml b/app/src/main/res/layout/listitem_recommend_source.xml new file mode 100644 index 0000000..a37ea18 --- /dev/null +++ b/app/src/main/res/layout/listitem_recommend_source.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/listitem_search_source_result.xml b/app/src/main/res/layout/listitem_search_source_result.xml new file mode 100644 index 0000000..5729ce4 --- /dev/null +++ b/app/src/main/res/layout/listitem_search_source_result.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/listitem_selected_keywords.xml b/app/src/main/res/layout/listitem_selected_keywords.xml new file mode 100644 index 0000000..1a94b21 --- /dev/null +++ b/app/src/main/res/layout/listitem_selected_keywords.xml @@ -0,0 +1,31 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/listitem_selected_source.xml b/app/src/main/res/layout/listitem_selected_source.xml new file mode 100644 index 0000000..2d532a4 --- /dev/null +++ b/app/src/main/res/layout/listitem_selected_source.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/listitem_subscribe.xml b/app/src/main/res/layout/listitem_subscribe.xml new file mode 100644 index 0000000..b7726f2 --- /dev/null +++ b/app/src/main/res/layout/listitem_subscribe.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/listitem_subscribe_area.xml b/app/src/main/res/layout/listitem_subscribe_area.xml new file mode 100644 index 0000000..ebedc96 --- /dev/null +++ b/app/src/main/res/layout/listitem_subscribe_area.xml @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/listitem_subscribe_keyword.xml b/app/src/main/res/layout/listitem_subscribe_keyword.xml new file mode 100644 index 0000000..2911aa7 --- /dev/null +++ b/app/src/main/res/layout/listitem_subscribe_keyword.xml @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-xxhdpi/ic_add_subscribe_keyword.webp b/app/src/main/res/mipmap-xxhdpi/ic_add_subscribe_keyword.webp new file mode 100644 index 0000000..722f849 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_add_subscribe_keyword.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_delete.webp b/app/src/main/res/mipmap-xxhdpi/ic_delete.webp new file mode 100644 index 0000000..c1a9c28 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_delete.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_delete_subscribe_keyword.webp b/app/src/main/res/mipmap-xxhdpi/ic_delete_subscribe_keyword.webp new file mode 100644 index 0000000..07b3583 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_delete_subscribe_keyword.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_edit.webp b/app/src/main/res/mipmap-xxhdpi/ic_edit.webp index 09f2fc5..5fed6fa 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_edit.webp and b/app/src/main/res/mipmap-xxhdpi/ic_edit.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_empty_data.webp b/app/src/main/res/mipmap-xxhdpi/ic_empty_data.webp index 9bebdc5..d9dc0e8 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_empty_data.webp and b/app/src/main/res/mipmap-xxhdpi/ic_empty_data.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_empty_subscribe.webp b/app/src/main/res/mipmap-xxhdpi/ic_empty_subscribe.webp new file mode 100644 index 0000000..8bf7a95 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_empty_subscribe.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_new_tag.webp b/app/src/main/res/mipmap-xxhdpi/ic_new_tag.webp new file mode 100644 index 0000000..f713359 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_new_tag.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_push_float_icon.webp b/app/src/main/res/mipmap-xxhdpi/ic_push_float_icon.webp new file mode 100644 index 0000000..db1ed9b Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_push_float_icon.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_push_top_bg.webp b/app/src/main/res/mipmap-xxhdpi/ic_push_top_bg.webp new file mode 100644 index 0000000..82db0aa Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_push_top_bg.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_rb_checked.webp b/app/src/main/res/mipmap-xxhdpi/ic_rb_checked.webp new file mode 100644 index 0000000..0090918 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_rb_checked.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_rb_default.webp b/app/src/main/res/mipmap-xxhdpi/ic_rb_default.webp new file mode 100644 index 0000000..c27d2ff Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_rb_default.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_recommend_fire.webp b/app/src/main/res/mipmap-xxhdpi/ic_recommend_fire.webp new file mode 100644 index 0000000..347d89c Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_recommend_fire.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_recommend_source_tag1.webp b/app/src/main/res/mipmap-xxhdpi/ic_recommend_source_tag1.webp new file mode 100644 index 0000000..a764c20 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_recommend_source_tag1.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_recommend_source_tag2.webp b/app/src/main/res/mipmap-xxhdpi/ic_recommend_source_tag2.webp new file mode 100644 index 0000000..f70bc9b Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_recommend_source_tag2.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_recommend_source_tag3.webp b/app/src/main/res/mipmap-xxhdpi/ic_recommend_source_tag3.webp new file mode 100644 index 0000000..b829db1 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_recommend_source_tag3.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_recommend_source_top_bg.webp b/app/src/main/res/mipmap-xxhdpi/ic_recommend_source_top_bg.webp new file mode 100644 index 0000000..55ffc67 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_recommend_source_top_bg.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_refresh3.webp b/app/src/main/res/mipmap-xxhdpi/ic_refresh3.webp new file mode 100644 index 0000000..41c6b3b Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_refresh3.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_selected_source_tag.webp b/app/src/main/res/mipmap-xxhdpi/ic_selected_source_tag.webp new file mode 100644 index 0000000..e2e5ac9 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_selected_source_tag.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_subscribe_area_icon.webp b/app/src/main/res/mipmap-xxhdpi/ic_subscribe_area_icon.webp new file mode 100644 index 0000000..f463b0a Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_subscribe_area_icon.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_subscribe_source_icon.webp b/app/src/main/res/mipmap-xxhdpi/ic_subscribe_source_icon.webp new file mode 100644 index 0000000..e1ecd66 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_subscribe_source_icon.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_subscribe_title_icon.webp b/app/src/main/res/mipmap-xxhdpi/ic_subscribe_title_icon.webp new file mode 100644 index 0000000..73e51bf Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_subscribe_title_icon.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_subscribe_top_bg.webp b/app/src/main/res/mipmap-xxhdpi/ic_subscribe_top_bg.webp new file mode 100644 index 0000000..e279cc2 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_subscribe_top_bg.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_tab_indicator.webp b/app/src/main/res/mipmap-xxhdpi/ic_tab_indicator.webp new file mode 100644 index 0000000..0950da3 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_tab_indicator.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_vip_auth_icon.webp b/app/src/main/res/mipmap-xxhdpi/ic_vip_auth_icon.webp new file mode 100644 index 0000000..ae0caa0 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_vip_auth_icon.webp differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 9975174..03bd433 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -82,4 +82,6 @@ #4A53D5 #0391F5 #2A80FC + #F8F9FA + #3BBF0F \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 3ec0c1d..f6619ad 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -87,5 +87,6 @@ 170dp 132dp 116dp + 52dp \ No newline at end of file diff --git a/base/src/main/res/values/styles.xml b/base/src/main/res/values/styles.xml index 2b863b9..f65b5b5 100644 --- a/base/src/main/res/values/styles.xml +++ b/base/src/main/res/values/styles.xml @@ -2,12 +2,12 @@