添加推送相关页面

This commit is contained in:
wangyu 2026-01-04 17:42:23 +08:00
parent 1b5fd50613
commit 5e9e7e3ea5
73 changed files with 2818 additions and 136 deletions

View File

@ -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" //签到失败
}

View File

@ -0,0 +1,6 @@
package com.cheng.bole.event
import com.cheng.bole.bean.SourceBean
class SourceDataEvent(val list: List<SourceBean>) {
}

View File

@ -0,0 +1,4 @@
package com.cheng.bole.event
class SubscriptionEvent {
}

View File

@ -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<FragmentZzdbDetailBinding, ZZDBDetailVie
override fun initView() {
super.initView()
binding.rb1.typeface = Constants.douyinsansB
binding.rb2.typeface = Constants.douyinsansB
binding.rb3.typeface = Constants.douyinsansB
binding.tvNext.typeface = Constants.almmsht
binding.rvDevice.adapter = deviceAdapter
(binding.layoutBaseInfo.layoutParams as ConstraintLayout.LayoutParams).topMargin = BarUtils.getStatusBarHeight() + actionBarHeight + DensityUtils.dp2px(12f)

View File

@ -1,12 +1,145 @@
package com.cheng.bole.ui.fragment.push
import android.graphics.Typeface
import android.view.Gravity
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentStatePagerAdapter
import com.angcyo.tablayout.DslTabLayout
import com.angcyo.tablayout.delegate.ViewPager1Delegate
import com.cheng.bole.R
import com.cheng.bole.common.Constants
import com.cheng.bole.common.EventConstants
import com.cheng.bole.databinding.FragmentPushBinding
import com.cheng.bole.event.HomeRefreshEvent
import com.cheng.bole.event.SubscriptionEvent
import com.cheng.bole.manager.EventReportManager
import com.cheng.bole.manager.UserConfigManager
import com.cheng.bole.ui.activity.PublicActivity
import com.cheng.bole.ui.base.BasePageAdapter
import com.cheng.bole.ui.fragment.push.list.PushListFragment
import com.cheng.bole.ui.fragment.push.subscribe.SubscribeFragment
import com.example.base.common.RxBus
import com.example.base.extensions.onClick
import com.example.base.ui.BaseFragment
import com.example.base.utils.DensityUtils
import com.example.base.widget.PageStatus
/**
* 推送
*/
class PushFragment : BaseFragment<FragmentPushBinding, PushViewModel>() {
private val tabText = mutableListOf<String>()
private val fragmentList by lazy { mutableListOf<Fragment>() }
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
}
}

View File

@ -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<List<SubscriptionBean>>()
val typeLiveData = MutableLiveData<List<BidTypeBean>>()
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)
})
}
}

View File

@ -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<FragmentPushListBinding, PushListViewModel, BidItemBean>() {
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
}
}

View File

@ -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<BidItemBean>() {
override suspend fun requestApi(params: ArrayMap<String, String>): Result<List<BidItemBean>> {
return ApiFactory.apiService.getRecommendList(params).toListResult()
}
val authLiveData = MutableLiveData<UserAuthBean>()
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)
})
}
}

View File

@ -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<SubscriptionBean, BaseViewHolder>(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<RecyclerView>(R.id.rv_keywords)
val keywordAdapter = KeywordAdapter()
rvKeyword.adapter = keywordAdapter
keywordAdapter.setList(item.keyword)
val rvCity = holder.getView<RecyclerView>(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<String, BaseViewHolder>(R.layout.listitem_subscribe_keyword) {
override fun convert(holder: BaseViewHolder, item: String) {
holder.setText(R.id.tv_name, item)
}
}
inner class CityAdapter: BaseQuickAdapter<String, BaseViewHolder>(R.layout.listitem_subscribe_area) {
override fun convert(holder: BaseViewHolder, item: String) {
holder.setText(R.id.tv_name, item)
}
}
}

View File

@ -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<FragmentSubscribeBinding, SubscribeViewModel>() {
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)
}
}

View File

@ -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<List<SubscriptionBean>>()
val deleteLiveData = MutableLiveData<Any>()
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)
})
}
}

View File

@ -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<FragmentAddSubscribeBinding, AddSubscribeViewModel>() {
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<AreaBean>()
private val selectedSource = arrayListOf<SourceBean>()
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<HotWordBean.Child>()
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)
}
}

View File

@ -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<List<String>>()
val addLiveData = MutableLiveData<Any>()
fun getKeywords(query: String) {
launchOnUiTryCatch({
val params = mutableMapOf<String, String>()
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<UserAuthBean>()
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)
})
}
}

View File

@ -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<HotWordBean.Child, BaseViewHolder>(R.layout.listitem_recommend_keywords) {
override fun convert(holder: BaseViewHolder, item: HotWordBean.Child) {
holder.setText(R.id.tv_name, item.name)
}
}

View File

@ -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<String, BaseViewHolder>(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)
}
}

View File

@ -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<SourceBean, BaseViewHolder>(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)
}
}
}
}

View File

@ -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<SourceBean, BaseViewHolder>(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
}
}

View File

@ -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<SourceBean, BaseViewHolder>(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)
}
}

View File

@ -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<FragmentSourceSearchBinding, SourceSearchViewModel>() {
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<List<SourceBean>>() {}.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()
}
}

View File

@ -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<List<SourceBean>>()
val searchLiveData = MutableLiveData<List<SourceBean>>()
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)
})
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/ic_rb_checked" android:state_checked="true" />
<item android:drawable="@mipmap/ic_rb_default" android:state_checked="false" />
</selector>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_8" />
<stroke
android:width="@dimen/dp_1"
android:color="@color/color_dddddd" />
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">
<stroke
android:width="@dimen/dp_1"
android:color="#DDE2EB"
android:dashWidth="@dimen/dp_3"
android:dashGap="@dimen/dp_3" />
<size android:height="@dimen/dp_1" />
</shape>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_10"/>
<solid android:color="@color/color_f8f9fa"/>
</shape>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_6"/>
<solid android:color="@color/color_f8f9fa"/>
</shape>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_6" />
<solid android:color="#1aff493c" />
<stroke
android:width="@dimen/dp_1"
android:color="@color/color_ff493c" />
</shape>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_6" />
<solid android:color="@color/color_f8f9fa" />
</shape>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_6" />
<solid android:color="#E6EEFF" />
<stroke
android:width="@dimen/dp_1"
android:color="@color/color_125ffe" />
</shape>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners android:radius="@dimen/dp_6" />
</shape>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_25" />
<solid android:color="#EAF2FF" />
<stroke
android:width="@dimen/dp_1"
android:color="#2D81FF" />
</shape>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/white" />
<corners android:radius="@dimen/dp_14" />
</shape>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_50" />
<gradient
android:angle="270"
android:endColor="#3A70F7"
android:startColor="#4B96F6" />
</shape>

View File

@ -0,0 +1,611 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.base.widget.TitleBar
android:id="@+id/mTitleBar"
style="@style/Custom.TitleBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="@drawable/ic_back_black"
app:title=" ">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:text="订阅"
android:textColor="@color/color_212226"
android:textSize="@dimen/sp_17"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_vip_tag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="-9dp"
android:src="@mipmap/ic_vip_auth_icon"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/tv_title"
app:layout_constraintStart_toEndOf="@+id/tv_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.example.base.widget.TitleBar>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/layout_bottom"
app:layout_constraintTop_toBottomOf="@id/mTitleBar">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.lihang.ShadowLayout
android:id="@+id/layout_base_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_9"
android:layout_marginTop="@dimen/dp_9"
android:layout_marginEnd="@dimen/dp_9"
app:hl_cornerRadius="@dimen/dp_10"
app:hl_shadowColor="#0d4a4f5b"
app:hl_shadowLimit="@dimen/dp_7"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="@dimen/dp_12"
android:paddingEnd="@dimen/dp_12">
<TextView
android:id="@+id/tv_base_info_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_16"
android:fontFamily="sans-serif-medium"
android:text="基本信息"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_16"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_2"
android:text="*"
android:textColor="@color/color_ff493c"
android:textSize="@dimen/sp_15"
app:layout_constraintStart_toEndOf="@id/tv_base_info_title"
app:layout_constraintTop_toTopOf="@id/tv_base_info_title" />
<LinearLayout
android:id="@+id/layout_name"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_52"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@id/tv_base_info_title">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="订阅名称"
android:textColor="@color/color_666666"
android:textSize="@dimen/sp_14" />
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_34"
android:background="@null"
android:hint="请输入"
android:maxLength="50"
android:maxLines="1"
android:singleLine="true"
android:textColorHint="@color/color_bcbcbc"
android:textSize="@dimen/sp_14" />
</LinearLayout>
<View
android:id="@+id/view_line1"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_1"
android:background="@color/color_eeeeee"
app:layout_constraintTop_toBottomOf="@id/layout_name" />
<LinearLayout
android:id="@+id/layout_area"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_52"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@id/layout_name">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="订阅地区"
android:textColor="@color/color_666666"
android:textSize="@dimen/sp_14" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_2"
android:text="*"
android:textColor="@color/color_ff493c"
android:textSize="@dimen/sp_15" />
<TextView
android:id="@+id/tv_area"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_26"
android:drawableEnd="@mipmap/ic_arrow_dp16"
android:ellipsize="end"
android:hint="请选择"
android:maxLines="1"
android:singleLine="true"
android:textColor="@color/color_1a1a1a"
android:textColorHint="@color/color_bcbcbc"
android:textSize="@dimen/sp_14" />
</LinearLayout>
<LinearLayout
android:id="@+id/layout_source"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_52"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="invisible"
app:layout_constraintTop_toBottomOf="@id/layout_name">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="数据源"
android:textColor="@color/color_666666"
android:textSize="@dimen/sp_14" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_2"
android:text="*"
android:textColor="@color/color_ff493c"
android:textSize="@dimen/sp_15" />
<TextView
android:id="@+id/tv_source"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_40"
android:drawableEnd="@mipmap/ic_arrow_dp16"
android:hint="请选择"
android:maxLines="1"
android:text="0"
android:textColor="@color/color_1a1a1a"
android:textColorHint="@color/color_bcbcbc"
android:textSize="@dimen/sp_14" />
</LinearLayout>
<View
android:id="@+id/view_line2"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_1"
android:background="@color/color_eeeeee"
app:layout_constraintTop_toBottomOf="@id/layout_area" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_push_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/layout_source">
<TextView
android:id="@+id/tv_push_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_16"
android:text="推送方式"
android:textColor="@color/color_666666"
android:textSize="@dimen/sp_14"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<RadioGroup
android:id="@+id/rg_push_type"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_34"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="@id/tv_push_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_push_title"
app:layout_constraintTop_toTopOf="@id/tv_push_title">
<RadioButton
android:id="@+id/rb1"
android:layout_width="@dimen/dp_18"
android:layout_height="@dimen/dp_18"
android:background="@drawable/selector_rb"
android:button="@null" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_6">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="短信"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_14"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_vip_tag1"
android:layout_width="@dimen/dp_23"
android:layout_height="@dimen/dp_10"
android:layout_marginStart="-10dp"
android:src="@mipmap/ic_vip_auth_icon"
app:layout_constraintBottom_toTopOf="@id/tv1"
app:layout_constraintStart_toEndOf="@id/tv1" />
</androidx.constraintlayout.widget.ConstraintLayout>
<RadioButton
android:id="@+id/rb2"
android:layout_width="@dimen/dp_18"
android:layout_height="@dimen/dp_18"
android:layout_marginStart="@dimen/dp_16"
android:background="@drawable/selector_rb"
android:button="@null" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_6">
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="邮箱"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_14"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_vip_tag2"
android:layout_width="@dimen/dp_23"
android:layout_height="@dimen/dp_10"
android:layout_marginStart="-10dp"
android:src="@mipmap/ic_vip_auth_icon"
app:layout_constraintBottom_toTopOf="@id/tv2"
app:layout_constraintStart_toEndOf="@id/tv2" />
</androidx.constraintlayout.widget.ConstraintLayout>
<RadioButton
android:id="@+id/rb3"
android:layout_width="@dimen/dp_18"
android:layout_height="@dimen/dp_18"
android:layout_marginStart="@dimen/dp_16"
android:background="@drawable/selector_rb"
android:button="@null"
android:checked="true" />
<TextView
android:id="@+id/tv3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_6"
android:text="APP推送"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_14" />
</RadioGroup>
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/et_phone"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_16"
android:layout_marginBottom="@dimen/dp_16"
android:background="@null"
android:hint="请输入手机号"
android:inputType="number"
android:maxLength="11"
android:textColor="@color/color_1a1a1a"
android:textColorHint="@color/color_bcbcbc"
android:textSize="@dimen/sp_14"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/rg_push_type"
app:layout_constraintTop_toBottomOf="@id/tv_push_title" />
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/et_email"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_16"
android:layout_marginBottom="@dimen/dp_16"
android:background="@null"
android:hint="请输入邮箱地址"
android:inputType="textEmailAddress"
android:textColor="@color/color_1a1a1a"
android:textColorHint="@color/color_bcbcbc"
android:textSize="@dimen/sp_14"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/rg_push_type"
app:layout_constraintTop_toBottomOf="@id/tv_push_title" />
<View
android:id="@+id/view_line3"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_1"
android:layout_marginTop="@dimen/dp_16"
android:background="@color/color_eeeeee"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/tv_push_title" />
<LinearLayout
android:id="@+id/layout_notification_state"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_52"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/view_line3">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="消息推送"
android:textColor="@color/color_666666"
android:textSize="@dimen/sp_14" />
<TextView
android:id="@+id/tv_notification_state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_34"
android:drawableEnd="@mipmap/ic_arrow_dp16"
android:hint="点击授权"
android:maxLines="1"
android:textColor="@color/color_3bbf0f"
android:textColorHint="@color/color_bcbcbc"
android:textSize="@dimen/sp_14" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.lihang.ShadowLayout>
<com.lihang.ShadowLayout
android:id="@+id/layout_keywords"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_9"
android:layout_marginEnd="@dimen/dp_9"
app:hl_cornerRadius="@dimen/dp_10"
app:hl_shadowColor="#0d4a4f5b"
app:hl_shadowLimit="@dimen/dp_7"
app:layout_constraintTop_toBottomOf="@id/layout_base_info">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/dp_12">
<TextView
android:id="@+id/tv_keywords_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:text="关键词"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_16"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_2"
android:text="*"
android:textColor="@color/color_ff493c"
android:textSize="@dimen/sp_15"
app:layout_constraintStart_toEndOf="@id/tv_keywords_title"
app:layout_constraintTop_toTopOf="@id/tv_keywords_title" />
<TextView
android:id="@+id/tv_keywords_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0/5"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_16"
app:layout_constraintBottom_toBottomOf="@id/tv_keywords_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_keywords_title" />
<LinearLayout
android:id="@+id/layout_add_keyword"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_44"
android:layout_marginTop="@dimen/dp_16"
android:background="@drawable/shape_f8f9fa_cor10"
android:gravity="center"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@id/tv_keywords_title">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/et_keyword"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@null"
android:hint="请输入您经营的产品或主营业务"
android:maxLines="1"
android:paddingStart="@dimen/dp_12"
android:paddingEnd="@dimen/dp_12"
android:singleLine="true"
android:textColor="@color/color_1a1a1a"
android:textColorHint="@color/color_bcbcbc"
android:textSize="@dimen/sp_14" />
<com.cheng.bole.widget.CommonShapeView
android:id="@+id/tv_add_keywords"
android:layout_width="@dimen/dp_70"
android:layout_height="@dimen/dp_36"
android:drawableStart="@mipmap/ic_add_subscribe_keyword"
android:text="添加"
android:textColor="@color/white"
app:csb_cornerRadius="@dimen/dp_10"
app:csb_drawablePosition="left"
app:csb_fillColor="@color/color_125ffe" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_selected_keywords"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never"
android:paddingTop="@dimen/dp_6"
android:paddingBottom="@dimen/dp_16"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:layout_constraintTop_toBottomOf="@id/layout_add_keyword"
app:spanCount="3"
tools:itemCount="5"
tools:listitem="@layout/listitem_selected_keywords" />
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_2"
android:layout_marginTop="@dimen/dp_16"
android:background="@drawable/shape_dde2eb_dash_divider_h"
app:layout_constraintTop_toBottomOf="@id/rv_selected_keywords" />
<TextView
android:id="@+id/tv_recommend_keywords_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_16"
android:text="推荐"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_14"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/divider" />
<LinearLayout
android:id="@+id/layout_refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_dddddd_line_cor8"
android:gravity="center"
android:orientation="horizontal"
android:paddingStart="@dimen/dp_6"
android:paddingTop="@dimen/dp_2"
android:paddingEnd="@dimen/dp_6"
android:paddingBottom="@dimen/dp_2"
app:layout_constraintBottom_toBottomOf="@id/tv_recommend_keywords_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_recommend_keywords_title">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="换一批"
android:textColor="@color/color_666666"
android:textSize="@dimen/sp_10" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_refresh_keywords"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_2"
android:src="@mipmap/ic_refresh3" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_keywords"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_12"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:layout_constraintTop_toBottomOf="@id/tv_recommend_keywords_title"
app:spanCount="3"
tools:itemCount="9"
tools:listitem="@layout/listitem_recommend_keywords" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.lihang.ShadowLayout>
<View
android:layout_width="match_parent"
android:layout_height="@dimen/dp_15"
app:layout_constraintTop_toBottomOf="@id/layout_keywords" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:paddingStart="@dimen/dp_16"
android:paddingTop="@dimen/dp_9"
android:paddingEnd="@dimen/dp_16"
android:paddingBottom="@dimen/dp_30"
app:layout_constraintBottom_toBottomOf="parent">
<com.cheng.bole.widget.CommonShapeView
android:id="@+id/btn_next"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_46"
android:fontFamily="sans-serif-medium"
android:text="立即订阅"
android:textColor="@color/white"
android:textSize="@dimen/sp_16"
app:csb_cornerRadius="@dimen/dp_10"
app:csb_fillColor="@color/color_125ffe"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,6 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_top_bg"
android:layout_width="match_parent"
android:layout_height="0dp"
android:src="@mipmap/ic_push_top_bg"
app:layout_constraintDimensionRatio="h,1125:467"
app:layout_constraintTop_toTopOf="parent" />
<com.angcyo.tablayout.DslTabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_40"
android:layout_marginTop="@dimen/dp_54"
app:layout_constraintTop_toTopOf="parent"
app:tab_deselect_color="@color/color_1a1a1a"
app:tab_enable_gradient_text_size="false"
app:tab_enable_text_bold="true"
app:tab_item_auto_equ_width="false"
app:tab_select_color="@color/color_1a1a1a"
app:tab_text_max_size="@dimen/sp_18"
app:tab_text_min_size="@dimen/sp_14" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/tabLayout" />
<com.example.base.widget.EmptyView
android:id="@+id/emptyView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_push_float_icon"
android:layout_marginBottom="@dimen/dp_100"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.angcyo.tablayout.DslTabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_50"
android:paddingTop="@dimen/dp_8"
android:paddingBottom="@dimen/dp_8"
app:layout_constraintTop_toTopOf="parent"
app:tab_deselect_color="@color/color_1a1a1a"
app:tab_draw_indicator="false"
app:tab_enable_gradient_text_size="false"
app:tab_enable_text_bold="false"
app:tab_item_auto_equ_width="false"
app:tab_select_color="@color/color_125ffe"
app:tab_text_max_size="@dimen/sp_16"
app:tab_text_min_size="@dimen/sp_14" />
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/mRefreshLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/tabLayout">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/mRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/listitem_bid" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,214 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.base.widget.TitleBar
android:id="@+id/mTitleBar"
style="@style/Custom.TitleBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="@drawable/ic_back_black"
app:title=" " />
<FrameLayout
android:id="@+id/layout_search"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:layout_marginStart="@dimen/dp_50"
android:layout_marginEnd="@dimen/dp_16"
app:layout_constraintBottom_toBottomOf="@id/mTitleBar">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="@dimen/dp_36"
android:layout_gravity="center_vertical"
android:background="@drawable/shape_white_cor10"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="@dimen/dp_12"
android:paddingEnd="@dimen/dp_12">
<TextView
android:id="@+id/tv_city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableEnd="@mipmap/ic_option_arrow_down"
android:drawablePadding="@dimen/dp_4"
android:gravity="center"
android:text="全国"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_14" />
<View
android:layout_width="@dimen/dp_1"
android:layout_height="@dimen/dp_24"
android:layout_marginStart="@dimen/dp_12"
android:background="@color/color_eeeeee" />
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/et_search"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_10"
android:layout_weight="1"
android:background="@null"
android:drawableStart="@mipmap/ic_search"
android:drawablePadding="@dimen/dp_11"
android:hint="输入关键词"
android:maxLines="1"
android:singleLine="true"
android:textColor="@color/color_1a1a1a"
android:textColorHint="@color/color_bcbcbc"
android:textSize="@dimen/sp_14" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_clear_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_10"
android:src="@mipmap/ic_clear_text"
android:visibility="gone" />
</androidx.appcompat.widget.LinearLayoutCompat>
</FrameLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/mTitleBar">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_selected"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tv_selected_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_16"
android:layout_marginTop="@dimen/dp_16"
android:drawableStart="@mipmap/ic_selected_source_tag"
android:drawablePadding="@dimen/dp_4"
android:gravity="center"
android:text="已选择数据源"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_16"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_selected_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_4"
android:text="(0/5)"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_14"
app:layout_constraintBottom_toBottomOf="@id/tv_selected_title"
app:layout_constraintStart_toEndOf="@id/tv_selected_title"
app:layout_constraintTop_toTopOf="@id/tv_selected_title" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_selected"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_9"
android:layout_marginTop="@dimen/dp_1"
android:layout_marginEnd="@dimen/dp_9"
android:orientation="horizontal"
android:overScrollMode="never"
app:layoutManager="com.google.android.flexbox.FlexboxLayoutManager"
app:layout_constraintTop_toBottomOf="@id/tv_selected_title"
tools:listitem="@layout/listitem_selected_source" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_recommend_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_16"
android:layout_marginTop="@dimen/dp_16"
android:drawableStart="@mipmap/ic_recommend_fire"
android:drawablePadding="@dimen/dp_4"
android:gravity="center"
android:text="热门推荐"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_16"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/layout_selected" />
<com.lihang.ShadowLayout
android:id="@+id/layout_recommend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_9"
android:layout_marginTop="@dimen/dp_5"
android:layout_marginEnd="@dimen/dp_9"
app:hl_cornerRadius="@dimen/dp_10"
app:hl_shadowColor="#0f000000"
app:hl_shadowLimit="@dimen/dp_7"
app:layout_constraintTop_toBottomOf="@id/tv_recommend_title">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="@mipmap/ic_recommend_source_top_bg" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_recommend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="10"
tools:listitem="@layout/listitem_recommend_source" />
</com.lihang.ShadowLayout>
<Space
android:layout_width="match_parent"
android:layout_height="@dimen/dp_15"
app:layout_constraintTop_toBottomOf="@id/layout_recommend" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_result"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#cc000000"
android:clickable="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/mTitleBar">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_white_bottom_cor10"
android:overScrollMode="never"
android:paddingTop="@dimen/dp_8"
android:paddingBottom="@dimen/dp_8"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/listitem_search_source_result" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:src="@mipmap/ic_subscribe_top_bg"
app:layout_constraintDimensionRatio="h,1125:661"
app:layout_constraintTop_toTopOf="parent" />
<com.example.base.widget.TitleBar
android:id="@+id/mTitleBar"
style="@style/Custom.TitleBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="@drawable/ic_back_black"
app:title="订阅" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_area"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_16"
android:layout_marginTop="@dimen/dp_12"
android:background="@drawable/shape_white_cor14"
app:layout_constraintEnd_toStartOf="@id/layout_source"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/mTitleBar">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_area_icon"
android:layout_width="@dimen/dp_40"
android:layout_height="@dimen/dp_40"
android:layout_marginStart="@dimen/dp_12"
android:layout_marginTop="@dimen/dp_20"
android:layout_marginBottom="@dimen/dp_20"
android:src="@mipmap/ic_subscribe_area_icon"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_area_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_10"
android:fontFamily="sans-serif-medium"
android:text="地区订阅"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_16"
app:layout_constraintStart_toEndOf="@id/iv_area_icon"
app:layout_constraintTop_toTopOf="@id/iv_area_icon" />
<TextView
android:id="@+id/tv_area_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="精准触达同城"
android:textColor="@color/color_999999"
android:textSize="@dimen/sp_12"
app:layout_constraintBottom_toBottomOf="@id/iv_area_icon"
app:layout_constraintStart_toStartOf="@id/tv_area_title"
app:layout_constraintTop_toBottomOf="@id/tv_area_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_source"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_11"
android:layout_marginTop="@dimen/dp_12"
android:layout_marginEnd="@dimen/dp_16"
android:background="@drawable/shape_white_cor14"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/layout_area"
app:layout_constraintTop_toBottomOf="@id/mTitleBar">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_source_icon"
android:layout_width="@dimen/dp_40"
android:layout_height="@dimen/dp_40"
android:layout_marginStart="@dimen/dp_12"
android:layout_marginTop="@dimen/dp_20"
android:layout_marginBottom="@dimen/dp_20"
android:src="@mipmap/ic_subscribe_source_icon"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_20"
android:layout_marginTop="-10dp"
android:src="@mipmap/ic_vip_auth_icon"
app:layout_constraintStart_toStartOf="@id/iv_source_icon"
app:layout_constraintTop_toTopOf="@id/iv_source_icon" />
<TextView
android:id="@+id/tv_source_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_10"
android:fontFamily="sans-serif-medium"
android:text="数据源订阅"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_16"
app:layout_constraintStart_toEndOf="@id/iv_source_icon"
app:layout_constraintTop_toTopOf="@id/iv_source_icon" />
<TextView
android:id="@+id/tv_source_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取关键信息"
android:textColor="@color/color_999999"
android:textSize="@dimen/sp_12"
app:layout_constraintBottom_toBottomOf="@id/iv_source_icon"
app:layout_constraintStart_toStartOf="@id/tv_source_title"
app:layout_constraintTop_toBottomOf="@id/tv_source_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="-5dp"
android:layout_marginBottom="-6dp"
android:src="@mipmap/ic_tab_indicator"
app:layout_constraintBottom_toBottomOf="@id/tv_title"
app:layout_constraintStart_toStartOf="@id/tv_title" />
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_16"
android:layout_marginTop="@dimen/dp_20"
android:text="已创建订阅"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_20"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/layout_area" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/mRecyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="@dimen/dp_7"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title"
tools:listitem="@layout/listitem_subscribe" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -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" />
<com.cheng.bole.widget.CommonShapeView
<FrameLayout
android:id="@+id/btn_next"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_46"
android:layout_marginStart="@dimen/dp_12"
android:layout_marginTop="@dimen/dp_30"
android:layout_marginEnd="@dimen/dp_12"
android:text="立即办理"
android:textColor="@color/white"
android:textSize="@dimen/sp_18"
android:textStyle="bold"
app:csb_cornerRadius="@dimen/dp_50"
app:csb_endColor="#3A70F7"
app:csb_orientation="TOP_BOTTOM"
app:csb_startColor="#4B96F6"
android:background="@drawable/shape_zzdb_btn_bg"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/view_line4" />
app:layout_constraintTop_toBottomOf="@id/view_line4"
android:layout_marginEnd="@dimen/dp_12">
<TextView
android:id="@+id/tv_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="立即办理"
android:shadowColor="#084CAF"
android:shadowRadius="4"
android:shadowDy="6"
android:layout_gravity="center"
android:textColor="@color/white"
android:textSize="@dimen/sp_18"
android:textStyle="bold"/>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_32"
android:background="@drawable/shape_keyword_default"
android:ellipsize="end"
android:gravity="center"
android:lines="1"
android:singleLine="true"
android:text="流动机械"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_13"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_48"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="@dimen/dp_14"
android:paddingEnd="@dimen/dp_14">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_tag1"
android:layout_width="@dimen/dp_20"
android:layout_height="@dimen/dp_20"
android:src="@mipmap/ic_recommend_source_tag1" />
<TextView
android:id="@+id/tv_index"
android:layout_width="@dimen/dp_20"
android:layout_height="@dimen/dp_20"
android:gravity="center"
android:text="4"
android:visibility="gone"
android:textColor="@color/color_999999"
android:textSize="@dimen/sp_14" />
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_10"
android:layout_marginEnd="@dimen/dp_10"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:singleLine="true"
android:text="北京政府采购网"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_14" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_tag2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_new_tag" />
</LinearLayout>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/dp_8"
android:paddingBottom="@dimen/dp_8">
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingStart="@dimen/dp_12"
android:paddingEnd="@dimen/dp_12"
android:text="北京政府采购网"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_14"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_32"
android:gravity="center"
android:layout_marginEnd="@dimen/dp_10"
android:layout_marginTop="@dimen/dp_10"
android:paddingStart="@dimen/dp_12"
android:paddingEnd="@dimen/dp_8"
android:background="@drawable/shape_selected_keyword_bg"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="流动机械"
android:lines="1"
android:singleLine="true"
android:ellipsize="end"
android:textColor="#2D81FF"
android:textSize="@dimen/sp_14" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/dp_4"
android:src="@mipmap/ic_delete_subscribe_keyword" />
</LinearLayout>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<com.lihang.ShadowLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_44"
android:layout_marginTop="@dimen/dp_1"
android:layout_marginEnd="@dimen/dp_1"
app:hl_cornerRadius="@dimen/dp_25"
app:hl_shadowColor="#0f000000"
app:hl_shadowLimit="@dimen/dp_7">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingStart="@dimen/dp_14"
android:paddingEnd="@dimen/dp_10">
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="北京政府采购网"
android:textColor="@color/color_666666"
android:textSize="@dimen/sp_13"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_4"
android:padding="@dimen/dp_4"
android:src="@mipmap/ic_delete_subscribe_keyword"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_name"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.lihang.ShadowLayout>

View File

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<com.lihang.ShadowLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_9"
android:layout_marginEnd="@dimen/dp_9"
app:hl_cornerRadius="@dimen/dp_10"
app:hl_shadowColor="#0d4a4f5b"
app:hl_shadowLimit="@dimen/dp_7">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/dp_12">
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableStart="@mipmap/ic_subscribe_title_icon"
android:drawablePadding="@dimen/dp_8"
android:gravity="center"
android:text="默认订阅"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_14"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_10"
android:background="@drawable/shape_f8f9fa_cor6"
app:layout_constraintTop_toBottomOf="@id/tv_name">
<TextView
android:id="@+id/tv_keywords"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_20"
android:layout_marginStart="@dimen/dp_10"
android:layout_marginTop="@dimen/dp_16"
android:gravity="center"
android:text="关键词:"
android:textColor="@color/color_999999"
android:textSize="@dimen/sp_12"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_keywords"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_12"
android:layout_marginEnd="@dimen/dp_10"
android:orientation="horizontal"
android:overScrollMode="never"
app:layoutManager="com.google.android.flexbox.FlexboxLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_keywords"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/listitem_subscribe_keyword" />
<TextView
android:id="@+id/tv_area"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_20"
android:layout_marginStart="@dimen/dp_10"
android:layout_marginTop="@dimen/dp_12"
android:gravity="center"
android:text="订阅地区:"
android:textColor="@color/color_999999"
android:textSize="@dimen/sp_12"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/rv_keywords" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_area"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_8"
android:layout_marginEnd="@dimen/dp_10"
android:orientation="horizontal"
android:overScrollMode="never"
app:layoutManager="com.google.android.flexbox.FlexboxLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_area"
app:layout_constraintTop_toBottomOf="@id/rv_keywords"
tools:listitem="@layout/listitem_subscribe_area" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_12"
android:layout_marginEnd="@dimen/dp_20"
android:drawableStart="@mipmap/ic_delete"
android:drawablePadding="@dimen/dp_2"
android:gravity="center"
android:text="删除"
android:textColor="@color/color_999999"
android:textSize="@dimen/sp_12"
app:layout_constraintEnd_toStartOf="@id/tv_edit"
app:layout_constraintTop_toBottomOf="@id/layout_content" />
<TextView
android:id="@+id/tv_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_12"
android:drawableStart="@mipmap/ic_edit"
android:drawablePadding="@dimen/dp_2"
android:gravity="center"
android:text="编辑"
android:textColor="@color/color_999999"
android:textSize="@dimen/sp_12"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/layout_content" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.lihang.ShadowLayout>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dp_4">
<com.cheng.bole.widget.CommonShapeView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_20"
android:paddingStart="@dimen/dp_2"
android:paddingEnd="@dimen/dp_2"
android:text="北京"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_13"
app:csb_fillColor="@color/transparent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dp_4">
<com.cheng.bole.widget.CommonShapeView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_20"
android:paddingStart="@dimen/dp_2"
android:paddingEnd="@dimen/dp_2"
android:text="水电站"
android:textColor="@color/color_1a1a1a"
android:textSize="@dimen/sp_13"
app:csb_fillColor="@color/transparent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 350 B

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 882 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 B

View File

@ -82,4 +82,6 @@
<color name="color_4a53d5">#4A53D5</color>
<color name="color_0391f5">#0391F5</color>
<color name="color_2a80fc">#2A80FC</color>
<color name="color_f8f9fa">#F8F9FA</color>
<color name="color_3bbf0f">#3BBF0F</color>
</resources>

View File

@ -87,5 +87,6 @@
<dimen name="dp_170">170dp</dimen>
<dimen name="dp_132">132dp</dimen>
<dimen name="dp_116">116dp</dimen>
<dimen name="dp_52">52dp</dimen>
</resources>

View File

@ -2,12 +2,12 @@
<!-- 自定义titleBar的样式的标题样式 -->
<style name="_titleTextAppearance" parent="@android:style/TextAppearance">
<item name="android:textSize">18sp</item>
<item name="android:textSize">17sp</item>
<item name="android:textColor">#212226</item>
<item name="android:gravity">center</item>
<item name="android:singleLine">true</item>
<item name="android:lines">1</item>
<item name="android:textStyle">bold</item>
<item name="fontFamily">sans-serif-medium</item>
</style>
<!-- 自定义titleBar的样式 -->