From 8e2f0156923679a5774c17445db18c43d277ab0b Mon Sep 17 00:00:00 2001
From: tj <1378534974@qq.com>
Date: 星期三, 26 三月 2025 16:12:28 +0800
Subject: [PATCH] 1.vip续费页面-vip基础信息 2.vip续费页面-连续包月、年卡、月卡页面绘画
---
app/src/main/res/drawable/round_transition_gray_bg.xml | 9
app/src/main/res/drawable/member_background.xml | 8
app/src/main/java/com/example/firstapp/adapter/CardAdapter.kt | 126 ++++++
app/src/main/res/layout/item_card_yearly.xml | 81 +++
app/src/main/res/drawable/gray_border_shape.xml | 7
app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardViewModel.kt | 23 +
app/src/main/res/drawable/error_placeholder.xml | 9
app/src/main/res/layout/content_vip.xml | 19
app/src/main/res/layout/item_card_single_month.xml | 55 ++
app/src/main/java/com/example/firstapp/activity/VipActivity.kt | 108 +++++
app/src/main/res/xml/network_security_config.xml | 1
app/src/main/res/navigation/nav_graph.xml | 28 +
app/src/main/res/values-land/dimens.xml | 3
app/src/main/res/drawable/gold_border_shape.xml | 7
app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt | 6
app/src/main/res/values-w1240dp/dimens.xml | 3
app/src/main/res/values/dimens.xml | 1
app/src/main/java/com/example/firstapp/entity/CardData.kt | 24 +
app/src/main/res/layout/fragment_member_info_card.xml | 81 +++
app/src/main/res/drawable/round_red_bg.xml | 5
app/src/main/AndroidManifest.xml | 18
app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardFragment.kt | 118 +++++
app/src/main/res/layout/activity_vip.xml | 80 +++
app/src/main/res/layout/item_card.xml | 46 ++
app/src/main/res/layout/fragment_second.xml | 35 +
app/src/main/res/drawable/ic_check.xml | 14
app/src/main/java/com/example/firstapp/activity/SecondFragment.kt | 45 ++
app/src/main/res/drawable/ic_category.xml | 12
app/src/main/java/com/example/firstapp/activity/FirstFragment.kt | 45 ++
app/src/main/res/values-w600dp/dimens.xml | 3
app/src/main/res/layout/fragment_first.xml | 35 +
app/src/main/res/layout/item_card_continue_monthly.xml | 148 +++++++
32 files changed, 1,196 insertions(+), 7 deletions(-)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0446048..83d5efc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -83,7 +83,13 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.FirstApp"
- tools:targetApi="31">
+ tools:targetApi="31"
+ android:usesCleartextTraffic="true"
+ >
+ <activity
+ android:name=".activity.VipActivity"
+ android:exported="false"
+ android:theme="@style/Theme.FirstApp" />
<activity
android:name=".ui.reminderOther.ReminderOtherAddActivity2"
android:configChanges="orientation|keyboardHidden|screenSize"
@@ -106,14 +112,14 @@
android:exported="false" />
<activity
android:name=".activity.PickupActivity"
- android:exported="false"/>
- <activity
- android:name=".activity.ContentDetailActivity"
- android:theme="@style/Theme.ContentDetail"
android:exported="false" />
<activity
+ android:name=".activity.ContentDetailActivity"
+ android:exported="false"
+ android:theme="@style/Theme.ContentDetail" />
+ <activity
android:name=".ui.profile.EditProfileActivity"
- android:exported="false"/>
+ android:exported="false" />
</application>
</manifest>
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/activity/FirstFragment.kt b/app/src/main/java/com/example/firstapp/activity/FirstFragment.kt
new file mode 100644
index 0000000..9cc51ef
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/activity/FirstFragment.kt
@@ -0,0 +1,45 @@
+package com.example.firstapp.activity
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.navigation.fragment.findNavController
+import com.example.firstapp.R
+import com.example.firstapp.databinding.FragmentFirstBinding
+
+/**
+ * A simple [Fragment] subclass as the default destination in the navigation.
+ */
+class FirstFragment : Fragment() {
+
+ private var _binding: FragmentFirstBinding? = null
+
+ // This property is only valid between onCreateView and
+ // onDestroyView.
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+
+ _binding = FragmentFirstBinding.inflate(inflater, container, false)
+ return binding.root
+
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ binding.buttonFirst.setOnClickListener {
+ findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
+ }
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/activity/SecondFragment.kt b/app/src/main/java/com/example/firstapp/activity/SecondFragment.kt
new file mode 100644
index 0000000..8f44618
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/activity/SecondFragment.kt
@@ -0,0 +1,45 @@
+package com.example.firstapp.activity
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.navigation.fragment.findNavController
+import com.example.firstapp.R
+import com.example.firstapp.databinding.FragmentSecondBinding
+
+/**
+ * A simple [Fragment] subclass as the second destination in the navigation.
+ */
+class SecondFragment : Fragment() {
+
+ private var _binding: FragmentSecondBinding? = null
+
+ // This property is only valid between onCreateView and
+ // onDestroyView.
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+
+ _binding = FragmentSecondBinding.inflate(inflater, container, false)
+ return binding.root
+
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ binding.buttonSecond.setOnClickListener {
+ findNavController().navigate(R.id.action_SecondFragment_to_FirstFragment)
+ }
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/activity/VipActivity.kt b/app/src/main/java/com/example/firstapp/activity/VipActivity.kt
new file mode 100644
index 0000000..183cd41
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/activity/VipActivity.kt
@@ -0,0 +1,108 @@
+package com.example.firstapp.activity
+
+import android.graphics.Color
+import android.os.Bundle
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.cardview.widget.CardView
+import androidx.core.content.ContextCompat
+import androidx.navigation.ui.AppBarConfiguration
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.example.firstapp.R
+import com.example.firstapp.adapter.CardAdapter
+import com.example.firstapp.databinding.ActivityVipBinding
+import com.example.firstapp.entity.CardData
+import com.example.firstapp.utils.Log
+
+class VipActivity : AppCompatActivity() {
+
+ private lateinit var appBarConfiguration: AppBarConfiguration
+ private lateinit var binding: ActivityVipBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ binding = ActivityVipBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ setSupportActionBar(binding.toolbar)
+
+ // 显式设置 MaterialToolbar 的标题
+ supportActionBar?.title = ""
+
+ // 如果不需要 ActionBar 的导航功能,可以禁用
+// supportActionBar?.setDisplayHomeAsUpEnabled(false)
+// supportActionBar?.setDisplayShowHomeEnabled(false)
+
+
+ // 返回事件
+ binding.ivBack.setOnClickListener{
+ finish()
+ }
+
+ val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
+ recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
+
+ val cardList = listOf(
+ CardData.ContinueMonthly(
+ "首月限时特惠",
+ "连续包月",
+ "首次开通",
+ "¥9.9",
+ "次月起12元/月",
+ "自动续费可随时取消"
+ ),
+ CardData.Yearly(
+ "折合9元/月",
+ "年卡",
+ "¥108/年",
+ "¥168"
+ ),
+ CardData.SingleMonth(
+ "1个月",
+ "¥15"
+ )
+ )
+
+ val adapter = CardAdapter(cardList) {cardViewList, cardData, cardView ->
+ handleCardClick(cardViewList,cardData,cardView)
+ }
+
+ recyclerView.adapter = adapter
+
+
+ try {
+ val firstMonthCardView = findViewById<CardView>(R.id.vip_first_month_card_view)
+ firstMonthCardView.foreground = ContextCompat.getDrawable(this, R.drawable.gray_border_shape) // 设置自定义背景
+
+ }catch (e: Exception){
+ e.stackTrace
+ Log.e("VipActivity",e.message+"")
+ }
+
+ }
+
+ /**
+ * 会员卡样式点击事件
+ */
+ private fun handleCardClick(cardViewList: MutableList<CardView>,cardData: CardData, cardView: CardView) {
+ // 处理点击事件,修改样式
+ // 修改所有的边框色都是灰色
+ cardViewList.forEach { card ->
+ card.foreground = ContextCompat.getDrawable(this, R.drawable.gray_border_shape) // 设置自定义背景
+ }
+
+ // 单独将点击的卡片边框颜色改为金色
+// cardView.setCardBackgroundColor(Color.parseColor("#FF0000")) // 举例:设置背景颜色
+ cardView.foreground = ContextCompat.getDrawable(this, R.drawable.gold_border_shape) // 设置自定义背景
+ val title = when (cardData) {
+ is CardData.ContinueMonthly -> cardData.title
+ is CardData.Yearly -> cardData.title
+ is CardData.SingleMonth -> cardData.title
+ }
+ // 处理点击事件,这里我们只是简单地展示一个 Toast
+ Toast.makeText(this, "点击了: ${title}", Toast.LENGTH_SHORT).show()
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/adapter/CardAdapter.kt b/app/src/main/java/com/example/firstapp/adapter/CardAdapter.kt
new file mode 100644
index 0000000..9f1b699
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/adapter/CardAdapter.kt
@@ -0,0 +1,126 @@
+package com.example.firstapp.adapter
+
+import android.graphics.Color
+import android.graphics.Paint
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.cardview.widget.CardView
+import androidx.recyclerview.widget.RecyclerView
+import com.example.firstapp.R
+import com.example.firstapp.entity.CardData
+
+
+class CardAdapter(private val cardList: List<CardData>,
+ private val itemClickListener: (MutableList<CardView>, CardData, CardView) -> Unit
+ ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
+
+ private val CONTINUE_MONTHLY_VIEW_TYPE = 0
+ private val YEARLY_VIEW_TYPE = 1
+ private val SINGLE_MONTH_VIEW_TYPE = 2
+
+ private val cardViewList: MutableList<CardView> = mutableListOf()
+
+ override fun getItemViewType(position: Int): Int {
+ return when (cardList[position]) {
+ is CardData.ContinueMonthly -> CONTINUE_MONTHLY_VIEW_TYPE
+ is CardData.Yearly -> YEARLY_VIEW_TYPE
+ is CardData.SingleMonth -> SINGLE_MONTH_VIEW_TYPE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return when (viewType) {
+ CONTINUE_MONTHLY_VIEW_TYPE -> {
+ val view = LayoutInflater.from(parent.context).inflate(R.layout.item_card_continue_monthly, parent, false)
+ ContinueMonthlyViewHolder(view)
+ }
+ YEARLY_VIEW_TYPE -> {
+ val view = LayoutInflater.from(parent.context).inflate(R.layout.item_card_yearly, parent, false)
+ YearlyViewHolder(view)
+ }
+ SINGLE_MONTH_VIEW_TYPE -> {
+ val view = LayoutInflater.from(parent.context).inflate(R.layout.item_card_single_month, parent, false)
+ SingleMonthViewHolder(view)
+ }
+ else -> throw IllegalArgumentException("Unknown view type")
+ }
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ when (holder) {
+ is ContinueMonthlyViewHolder -> {
+ val data = cardList[position] as CardData.ContinueMonthly
+
+ holder.firstMonthTag.text = data.firstMonthTag
+ holder.titleText.text = data.title
+ holder.subTitleText.text = data.subTitle
+ holder.priceText.text = data.price
+ holder.nextPriceText.text = data.nextPrice
+ holder.autoRenewText.text = data.autoRenew
+
+ cardViewList.add(holder.cardView)
+
+ holder.itemView.setOnClickListener { itemClickListener(cardViewList,data, holder.cardView) } // 设置点击事件
+ }
+ is YearlyViewHolder -> {
+ val data = cardList[position] as CardData.Yearly
+ holder.discountTag.text = data.discountTag
+ holder.titleText.text = data.title
+ holder.priceText.text = data.price
+ holder.originalPriceText.text = data.originalPrice
+
+ // 设置中划线
+ val paint = holder.originalPriceText.paint
+ paint.flags = paint.flags or Paint.STRIKE_THRU_TEXT_FLAG
+ paint.color = Color.RED // 设置中划线的颜色
+
+ cardViewList.add(holder.cardView)
+
+ holder.itemView.setOnClickListener { itemClickListener(cardViewList,data, holder.cardView) } // 设置点击事件
+ }
+ is SingleMonthViewHolder -> {
+ val data = cardList[position] as CardData.SingleMonth
+ holder.titleText.text = data.title
+ holder.priceText.text = data.price
+
+ cardViewList.add(holder.cardView)
+
+ holder.itemView.setOnClickListener { itemClickListener(cardViewList,data, holder.cardView) } // 设置点击事件
+
+ }
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return cardList.size
+ }
+
+ inner class ContinueMonthlyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ val cardView: CardView = view.findViewById(R.id.vip_first_month_card_view)
+ val firstMonthTag: TextView = view.findViewById(R.id.first_month_tag)
+ val titleText: TextView = view.findViewById(R.id.title_text)
+ val subTitleText: TextView = view.findViewById(R.id.sub_title_text)
+ val priceText: TextView = view.findViewById(R.id.price_text)
+ val nextPriceText: TextView = view.findViewById(R.id.next_price_text)
+ val autoRenewText: TextView = view.findViewById(R.id.auto_renew_text)
+
+ }
+
+ inner class YearlyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ val cardView: CardView = view.findViewById(R.id.vip_year_card_view)
+ val discountTag: TextView = view.findViewById(R.id.discount_tag)
+ val titleText: TextView = view.findViewById(R.id.yearly_title_text)
+ val priceText: TextView = view.findViewById(R.id.yearly_price_text)
+ val originalPriceText: TextView = view.findViewById(R.id.yearly_original_price_text)
+
+ }
+
+ inner class SingleMonthViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ val cardView: CardView = view.findViewById(R.id.vip_month_card_view)
+ val titleText: TextView = view.findViewById(R.id.single_month_title_text)
+ val priceText: TextView = view.findViewById(R.id.single_month_price_text)
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/entity/CardData.kt b/app/src/main/java/com/example/firstapp/entity/CardData.kt
new file mode 100644
index 0000000..f5c7c46
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/entity/CardData.kt
@@ -0,0 +1,24 @@
+package com.example.firstapp.entity
+
+sealed class CardData {
+ data class ContinueMonthly(
+ val firstMonthTag: String,
+ val title: String,
+ val subTitle: String,
+ val price: String,
+ val nextPrice: String,
+ val autoRenew: String
+ ) : CardData()
+
+ data class Yearly(
+ val discountTag: String,
+ val title: String,
+ val price: String,
+ val originalPrice: String
+ ) : CardData()
+
+ data class SingleMonth(
+ val title: String,
+ val price: String
+ ) : CardData()
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt b/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt
index ef69523..9c128a1 100644
--- a/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt
+++ b/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt
@@ -31,6 +31,7 @@
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.launch
import com.bumptech.glide.Glide
+import com.example.firstapp.activity.VipActivity
import com.example.firstapp.database.response.UserInfo
class NotificationsFragment : Fragment() {
@@ -232,7 +233,10 @@
// VIP续费
binding.btnRenew.setOnClickListener {
- Toast.makeText(context, "VIP续费功能开发中", Toast.LENGTH_SHORT).show()
+// Toast.makeText(context, "VIP续费功能开发中", Toast.LENGTH_SHORT).show()
+ // 跳转到vipActivity
+ val intent = Intent(requireContext(), VipActivity::class.java)
+ startActivity(intent)
}
}
diff --git a/app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardFragment.kt b/app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardFragment.kt
new file mode 100644
index 0000000..3671d10
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardFragment.kt
@@ -0,0 +1,118 @@
+package com.example.firstapp.ui.vip
+
+import android.graphics.drawable.Drawable
+import androidx.fragment.app.viewModels
+import android.os.Bundle
+import android.util.Log
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.databinding.DataBindingUtil
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.engine.GlideException
+import com.bumptech.glide.load.resource.bitmap.RoundedCorners
+import com.bumptech.glide.request.RequestListener
+import com.bumptech.glide.request.target.Target
+import com.bumptech.glide.load.DataSource
+import com.example.firstapp.R
+import com.example.firstapp.databinding.FragmentMemberInfoCardBinding
+
+class MemberInfoCardFragment : Fragment() {
+
+
+ companion object {
+ fun newInstance() = MemberInfoCardFragment()
+ }
+
+ private val viewModel: MemberInfoCardViewModel by viewModels()
+
+ // 绑定变量
+ private var _binding: FragmentMemberInfoCardBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ // 使用 DataBindingUtil.inflate 来绑定布局
+ _binding = FragmentMemberInfoCardBinding.inflate(inflater, container, false)
+ binding.viewModel = viewModel
+ binding.lifecycleOwner = this
+
+ // 绑定头像
+
+ Glide.with(this)
+ .load("http://192.168.1.201:9000/sms/avatar/avatar.jpg")
+ .transform(RoundedCorners(100)) // 设置圆角
+ .error(R.drawable.error_placeholder) // 如果加载失败,显示占位图
+ .listener(object : RequestListener<Drawable> {
+ override fun onResourceReady(
+ resource: Drawable?,
+ model: Any?,
+ target: Target<Drawable>?, // 正确使用 Target 作为泛型参数
+ dataSource: DataSource?, // 导入正确的 DataSource
+ isFirstResource: Boolean
+ ): Boolean {
+ Log.d("Glide", "Image loaded successfully")
+ return false
+ }
+
+ override fun onLoadFailed(
+ e: GlideException?,
+ model: Any?,
+ target: Target<Drawable>?, // 正确使用 Target 作为泛型参数
+ isFirstResource: Boolean
+ ): Boolean {
+ Log.e("Glide", "Image load failed", e)
+ return false
+ }
+ })
+ .into(binding.memberAvatarView)
+
+
+ // 绑定会员徽章
+
+ Glide.with(this)
+ .load("http://192.168.1.201:9000/sms/member/vip_no.png")
+ .transform(RoundedCorners(100)) // 设置圆角
+ .error(R.drawable.error_placeholder) // 如果加载失败,显示占位图
+ .listener(object : RequestListener<Drawable> {
+ override fun onResourceReady(
+ resource: Drawable?,
+ model: Any?,
+ target: Target<Drawable>?, // 正确使用 Target 作为泛型参数
+ dataSource: DataSource?, // 导入正确的 DataSource
+ isFirstResource: Boolean
+ ): Boolean {
+ Log.d("Glide", "Image loaded successfully")
+ return false
+ }
+
+ override fun onLoadFailed(
+ e: GlideException?,
+ model: Any?,
+ target: Target<Drawable>?, // 正确使用 Target 作为泛型参数
+ isFirstResource: Boolean
+ ): Boolean {
+ Log.e("Glide", "Image load failed", e)
+ return false
+ }
+ })
+ .into(binding.memberImageView)
+
+ return binding.root
+ }
+
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardViewModel.kt b/app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardViewModel.kt
new file mode 100644
index 0000000..1530b32
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardViewModel.kt
@@ -0,0 +1,23 @@
+package com.example.firstapp.ui.vip
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.launch
+
+class MemberInfoCardViewModel : ViewModel() {
+ // TODO: Implement the ViewModel
+ private val _phoneNumber = MutableStateFlow("18099999999")
+ val phoneNumber: StateFlow<String> = _phoneNumber
+
+ private val _memberStatus = MutableStateFlow("未开通")
+ val memberStatus: StateFlow<String> = _memberStatus
+
+ // 更新数据的方法
+ fun updatePhoneNumber(phoneNumber: String) {
+ viewModelScope.launch {
+ _phoneNumber.value = phoneNumber
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/error_placeholder.xml b/app/src/main/res/drawable/error_placeholder.xml
new file mode 100644
index 0000000..c556fa1
--- /dev/null
+++ b/app/src/main/res/drawable/error_placeholder.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="100dp"
+ android:height="100dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF6666"
+ android:pathData="M12,2L2,22h20L12,2zM13,18h-2v-2h2v2zm0,-4h-2v-4h2v4z"/>
+</vector>
diff --git a/app/src/main/res/drawable/gold_border_shape.xml b/app/src/main/res/drawable/gold_border_shape.xml
new file mode 100644
index 0000000..b660c93
--- /dev/null
+++ b/app/src/main/res/drawable/gold_border_shape.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="@android:color/transparent"/> <!-- 背景透明 -->
+ <stroke android:width="2dp" android:color="#F9EBC6"/> <!-- 金色边框 -->
+ <corners android:radius="16dp"/> <!-- 圆角大小 -->
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/gray_border_shape.xml b/app/src/main/res/drawable/gray_border_shape.xml
new file mode 100644
index 0000000..843e22f
--- /dev/null
+++ b/app/src/main/res/drawable/gray_border_shape.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="@android:color/transparent"/> <!-- 背景透明 -->
+ <stroke android:width="1dp" android:color="#FFFFFF"/> <!-- 金色边框 -->
+ <corners android:radius="16dp"/> <!-- 圆角大小 -->
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_category.xml b/app/src/main/res/drawable/ic_category.xml
new file mode 100644
index 0000000..2c57814
--- /dev/null
+++ b/app/src/main/res/drawable/ic_category.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#00BFFF"
+ android:pathData="M10,6L8.59,7.41 13.17,12 8.59,16.59 10,18l6,-6z"/>
+
+</vector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_check.xml b/app/src/main/res/drawable/ic_check.xml
new file mode 100644
index 0000000..8cba425
--- /dev/null
+++ b/app/src/main/res/drawable/ic_check.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#FFFFFF"
+ android:strokeWidth="2"
+ android:strokeColor="#000000"
+ android:pathData="M10.29,15.29 4,9 5.41,7.59 10.29,12.47 19.59,3.17 21,4.59 10.29,15.29"/>
+
+</vector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/member_background.xml b/app/src/main/res/drawable/member_background.xml
new file mode 100644
index 0000000..a50c8ba
--- /dev/null
+++ b/app/src/main/res/drawable/member_background.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <gradient
+ android:startColor="#000000"
+ android:endColor="#7A7596"
+ android:angle="90"/>
+</shape>
diff --git a/app/src/main/res/drawable/round_red_bg.xml b/app/src/main/res/drawable/round_red_bg.xml
new file mode 100644
index 0000000..8fcd59b
--- /dev/null
+++ b/app/src/main/res/drawable/round_red_bg.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="#FD6478"/> <!-- 设置背景颜色 -->
+ <corners android:radius="100dp"/> <!-- 设置圆角半径 -->
+</shape>
diff --git a/app/src/main/res/drawable/round_transition_gray_bg.xml b/app/src/main/res/drawable/round_transition_gray_bg.xml
new file mode 100644
index 0000000..0bcc740
--- /dev/null
+++ b/app/src/main/res/drawable/round_transition_gray_bg.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- 设置透明背景 -->
+ <solid android:color="@android:color/transparent"/>
+ <!-- 设置灰色边框 -->
+ <stroke android:color="#808080" android:width="1dp"/> <!-- 可以调整宽度 -->
+ <!-- 设置圆角 -->
+ <corners android:radius="16dp"/> <!-- 设置圆角半径 -->
+</shape>
diff --git a/app/src/main/res/layout/activity_vip.xml b/app/src/main/res/layout/activity_vip.xml
new file mode 100644
index 0000000..3ef2986
--- /dev/null
+++ b/app/src/main/res/layout/activity_vip.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
+ android:fitsSystemWindows="true"
+ android:background="@drawable/member_background"
+ tools:context=".activity.VipActivity">
+
+ <com.google.android.material.appbar.AppBarLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:fitsSystemWindows="true"
+ android:background="@android:color/transparent"
+ >
+
+ <com.google.android.material.appbar.MaterialToolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize" >
+ <!-- 直接在 Toolbar 中添加 TextView -->
+ <ImageView
+ android:id="@+id/ivBack"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="left"
+ android:layout_marginStart="16dp"
+ android:src="@drawable/ic_back" />
+ <TextView
+ android:id="@+id/tvTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="智信会员"
+ android:textColor="#FFFFFF"
+ android:textSize="18sp"
+ android:layout_gravity="left"
+ android:layout_marginEnd="16dp"/>
+ </com.google.android.material.appbar.MaterialToolbar>
+
+ </com.google.android.material.appbar.AppBarLayout>
+ <!-- 引入 MemberInfoCardFragment -->
+ <fragment
+ android:name="com.example.firstapp.ui.vip.MemberInfoCardFragment"
+ android:id="@+id/memberInfoCardFragment"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
+
+<!-- 滑动框-->
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/recycler_view"
+ android:layout_width="match_parent"
+ android:layout_height="200dp"
+ android:layout_marginTop="200dp"
+ app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ android:background="@android:color/transparent"
+ />
+
+
+
+
+
+
+ <!-- <include layout="@layout/content_vip" />-->
+
+ <!-- <com.google.android.material.floatingactionbutton.FloatingActionButton-->
+ <!-- android:id="@+id/fab"-->
+ <!-- android:layout_width="wrap_content"-->
+ <!-- android:layout_height="wrap_content"-->
+ <!-- android:layout_gravity="bottom|end"-->
+ <!-- android:layout_marginEnd="@dimen/fab_margin"-->
+ <!-- android:layout_marginBottom="16dp"-->
+ <!-- app:srcCompat="@android:drawable/ic_dialog_email" />-->
+
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/content_vip.xml b/app/src/main/res/layout/content_vip.xml
new file mode 100644
index 0000000..a2d7fbb
--- /dev/null
+++ b/app/src/main/res/layout/content_vip.xml
@@ -0,0 +1,19 @@
+<?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"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior">
+
+ <fragment
+ android:id="@+id/nav_host_fragment_content_vip"
+ android:name="androidx.navigation.fragment.NavHostFragment"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ app:defaultNavHost="true"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:navGraph="@navigation/nav_graph" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_first.xml b/app/src/main/res/layout/fragment_first.xml
new file mode 100644
index 0000000..44baecd
--- /dev/null
+++ b/app/src/main/res/layout/fragment_first.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.core.widget.NestedScrollView 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"
+ tools:context=".FirstFragment">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="16dp">
+
+ <Button
+ android:id="@+id/button_first"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/next"
+ app:layout_constraintBottom_toTopOf="@id/textview_first"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+
+ <TextView
+ android:id="@+id/textview_first"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:text="@string/lorem_ipsum"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/button_first" />
+ </androidx.constraintlayout.widget.ConstraintLayout>
+</androidx.core.widget.NestedScrollView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_member_info_card.xml b/app/src/main/res/layout/fragment_member_info_card.xml
new file mode 100644
index 0000000..d42005b
--- /dev/null
+++ b/app/src/main/res/layout/fragment_member_info_card.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <data>
+ <variable
+ name="viewModel"
+ type="com.example.firstapp.ui.vip.MemberInfoCardViewModel"/>
+ </data>
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".ui.vip.MemberInfoCardFragment">
+
+ <!-- CardView 内部的内容 -->
+ <androidx.cardview.widget.CardView
+ android:layout_width="match_parent"
+ android:layout_height="100dp"
+ android:layout_marginTop="20dp"
+ android:layout_marginLeft="15dp"
+ android:layout_marginRight="15dp"
+ app:cardCornerRadius="30dp"
+ android:elevation="2dp"> <!-- 设置CardView的elevation -->
+
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/memberCard"
+ android:layout_width="match_parent"
+ android:layout_height="80dp"
+ android:layout_marginTop="10dp"
+ tools:ignore="MissingConstraints">
+
+ <ImageView
+ android:id="@+id/memberAvatarView"
+ android:layout_width="60dp"
+ android:layout_height="60dp"
+ android:layout_marginLeft="10dp"
+ android:layout_marginRight="10dp"
+ android:scaleType="centerCrop"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent" />
+
+ <TextView
+ android:id="@+id/phoneNumberText"
+ android:layout_width="120dp"
+ android:layout_height="60dp"
+ android:gravity="center"
+ android:text="@{viewModel.phoneNumber}"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toEndOf="@id/memberAvatarView" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="15dp"
+ android:layout_marginTop="60dp"
+ android:gravity="start"
+ android:text="@{viewModel.memberStatus}" />
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+
+
+ </androidx.cardview.widget.CardView>
+
+ <!-- 悬浮的 ImageView, 位于右侧 -->
+ <ImageView
+ android:id="@+id/memberImageView"
+ android:layout_width="80dp"
+ android:layout_height="80dp"
+ android:layout_marginTop="0dp"
+ android:layout_marginRight="40dp"
+ android:scaleType="centerCrop"
+ android:layout_gravity="end|top"
+ android:elevation="4dp" /> <!-- 设置memberImageView的elevation,确保它在上层 -->
+
+ </FrameLayout>
+
+</layout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_second.xml b/app/src/main/res/layout/fragment_second.xml
new file mode 100644
index 0000000..d074310
--- /dev/null
+++ b/app/src/main/res/layout/fragment_second.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.core.widget.NestedScrollView 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"
+ tools:context=".SecondFragment">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="16dp">
+
+ <Button
+ android:id="@+id/button_second"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/previous"
+ app:layout_constraintBottom_toTopOf="@id/textview_second"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+
+ <TextView
+ android:id="@+id/textview_second"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:text="@string/lorem_ipsum"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/button_second" />
+ </androidx.constraintlayout.widget.ConstraintLayout>
+</androidx.core.widget.NestedScrollView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_card.xml b/app/src/main/res/layout/item_card.xml
new file mode 100644
index 0000000..9728346
--- /dev/null
+++ b/app/src/main/res/layout/item_card.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.cardview.widget.CardView 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="8dp"
+ app:cardBackgroundColor="#F0F0F0"
+ app:cardCornerRadius="16dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:id="@+id/tag_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="#FF0000"
+ android:text="首月限时特惠"
+ android:textColor="#FFFFFF"
+ android:padding="16dp"
+ />
+
+ <TextView
+ android:id="@+id/title_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="连续包月"
+ android:textSize="18sp"
+ android:textColor="#333333"
+ android:layout_marginTop="8dp" />
+
+ <TextView
+ android:id="@+id/price_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="¥9.9"
+ android:textSize="24sp"
+ android:textColor="#FF0000"
+ android:layout_marginTop="8dp" />
+
+ </LinearLayout>
+
+</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_card_continue_monthly.xml b/app/src/main/res/layout/item_card_continue_monthly.xml
new file mode 100644
index 0000000..115f488
--- /dev/null
+++ b/app/src/main/res/layout/item_card_continue_monthly.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="280dp"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dp"
+ android:background="@android:color/transparent"
+ app:cardBackgroundColor="@android:color/transparent"
+ app:cardElevation="0dp"
+ app:cardUseCompatPadding="false"
+ >
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/vip_first_month_card_view"
+ 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="140dp"
+ android:layout_marginTop="10dp"
+ app:cardCornerRadius="16dp"
+ android:foreground="@drawable/gold_border_shape"
+ app:cardBackgroundColor="@android:color/transparent"
+ app:cardElevation="0dp"
+ app:cardUseCompatPadding="false">
+
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="16dp"
+ android:background="@android:color/transparent">
+
+ <!-- Title Text -->
+ <TextView
+ android:id="@+id/title_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="连续包月"
+ android:textSize="18sp"
+ android:textColor="#F9EBC6"
+ android:layout_marginTop="8dp"
+ android:background="@android:color/transparent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent" />
+
+ <!-- Subtitle Text -->
+ <TextView
+ android:id="@+id/sub_title_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="首次开通"
+ android:textSize="10dp"
+ android:textColor="#CCCCCC"
+ android:paddingStart="5dp"
+ android:paddingTop="2dp"
+ android:paddingEnd="5dp"
+ android:paddingBottom="2dp"
+ android:background="@drawable/round_transition_gray_bg"
+ app:layout_constraintTop_toBottomOf="@id/title_text"
+ app:layout_constraintStart_toStartOf="parent"
+ android:layout_marginStart="85dp"
+ android:layout_marginTop="-20dp"
+ />
+
+ <!-- Price Text -->
+ <TextView
+ android:id="@+id/price_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="¥9.9"
+ android:textSize="40sp"
+ android:textColor="#F9EBC6"
+ android:layout_marginTop="0dp"
+ android:layout_marginLeft="150dp"
+ android:background="@android:color/transparent"
+ app:layout_constraintTop_toBottomOf="@id/sub_title_text"
+ app:layout_constraintStart_toStartOf="parent" />
+
+ <!-- Next Price Text -->
+ <TextView
+ android:id="@+id/next_price_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="次月起12元/月"
+ android:textSize="14sp"
+ android:textColor="#CCCCCC"
+ android:layout_marginTop="-30dp"
+ android:background="@android:color/transparent"
+ app:layout_constraintTop_toBottomOf="@id/price_text"
+ app:layout_constraintStart_toStartOf="parent" />
+
+ <!-- Auto Renew Text -->
+ <TextView
+ android:id="@+id/auto_renew_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="自动续费可随时取消"
+ android:textSize="12sp"
+ android:textColor="#CCCCCC"
+ android:layout_marginTop="4dp"
+ android:background="@android:color/transparent"
+ app:layout_constraintTop_toBottomOf="@id/next_price_text"
+ app:layout_constraintStart_toStartOf="parent" />
+
+<!-- <TextView-->
+<!-- android:id="@+id/auto_renew_text2"-->
+<!-- android:layout_width="wrap_content"-->
+<!-- android:layout_height="wrap_content"-->
+<!-- android:text="活动须知"-->
+<!-- android:textSize="12sp"-->
+<!-- android:textColor="#CCCCCC"-->
+<!-- android:layout_marginTop="4dp"-->
+<!-- android:background="@android:color/transparent"-->
+<!-- app:layout_constraintTop_toBottomOf="@id/auto_renew_text"-->
+<!-- app:layout_constraintStart_toStartOf="parent" />-->
+<!-- <TextView-->
+<!-- android:id="@+id/auto_renew_text3"-->
+<!-- android:layout_width="wrap_content"-->
+<!-- android:layout_height="wrap_content"-->
+<!-- android:text=">"-->
+<!-- android:textSize="16sp"-->
+<!-- android:textColor="#CCCCCC"-->
+<!-- android:layout_marginTop="0dp"-->
+<!-- android:background="@android:color/transparent"-->
+<!-- android:layout_marginLeft="60dp"-->
+<!-- app:layout_constraintTop_toBottomOf="@id/auto_renew_text"-->
+<!-- app:layout_constraintStart_toStartOf="parent" />-->
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+
+</androidx.cardview.widget.CardView>
+ <TextView
+ android:id="@+id/first_month_tag"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="0dp"
+ android:layout_marginRight="5dp"
+ android:scaleType="centerCrop"
+ android:layout_gravity="end|top"
+ android:text="首月限时特惠"
+ android:textColor="#FFFFFF"
+ android:padding="4dp"
+ android:elevation="4dp"
+ android:background="@drawable/round_red_bg"
+ />
+</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_card_single_month.xml b/app/src/main/res/layout/item_card_single_month.xml
new file mode 100644
index 0000000..21d888d
--- /dev/null
+++ b/app/src/main/res/layout/item_card_single_month.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="160dp"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dp"
+ android:background="@android:color/transparent"
+ app:cardBackgroundColor="@android:color/transparent"
+ app:cardElevation="0dp"
+ app:cardUseCompatPadding="false"
+ >
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/vip_month_card_view"
+ android:layout_width="160dp"
+ android:layout_height="140dp"
+ android:padding="8dp"
+ android:layout_marginTop="10dp"
+ android:layout_marginEnd="20dp"
+ android:background="@android:color/transparent"
+ android:foreground="@drawable/gray_border_shape"
+ app:cardBackgroundColor="@android:color/transparent"
+ app:cardCornerRadius="16dp"
+ app:cardElevation="0dp"
+ app:cardUseCompatPadding="false">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="20dp"
+ android:gravity="center"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:id="@+id/single_month_title_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:text="1个月"
+ android:textColor="#F9EBC6"
+ android:textSize="18sp" />
+
+ <TextView
+ android:id="@+id/single_month_price_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:text="¥15"
+ android:textColor="#F9EBC6"
+ android:textSize="40sp" />
+
+ </LinearLayout>
+ </androidx.cardview.widget.CardView>
+</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_card_yearly.xml b/app/src/main/res/layout/item_card_yearly.xml
new file mode 100644
index 0000000..d07e1ec
--- /dev/null
+++ b/app/src/main/res/layout/item_card_yearly.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="160dp"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dp"
+ android:background="@android:color/transparent"
+ app:cardBackgroundColor="@android:color/transparent"
+ app:cardElevation="0dp"
+ app:cardUseCompatPadding="false"
+ >
+ <androidx.cardview.widget.CardView
+ android:id="@+id/vip_year_card_view"
+ 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="140dp"
+ android:layout_marginTop="10dp"
+ app:cardCornerRadius="16dp"
+ android:foreground="@drawable/gray_border_shape"
+ app:cardBackgroundColor="@android:color/transparent"
+ app:cardElevation="0dp"
+ app:cardUseCompatPadding="false">
+
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center"
+ android:padding="16dp">
+
+ <TextView
+ android:id="@+id/yearly_title_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="年卡"
+ android:textSize="18sp"
+ android:textColor="#F9EBC6"
+ android:layout_marginTop="8dp"/>
+
+ <TextView
+ android:id="@+id/yearly_price_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="¥108/年"
+ android:textSize="30sp"
+ android:textColor="#F9EBC6"
+ android:layout_marginTop="8dp"/>
+
+ <TextView
+ android:id="@+id/yearly_original_price_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="¥168"
+ android:textSize="12sp"
+ android:textColor="#CCCCCC"
+ android:layout_marginTop="4dp"
+ />
+
+ </LinearLayout>
+
+
+</androidx.cardview.widget.CardView>
+
+ <TextView
+ android:id="@+id/discount_tag"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="0dp"
+ android:layout_marginRight="5dp"
+ android:scaleType="centerCrop"
+ android:layout_gravity="end|top"
+ android:text="折合9元/月"
+ android:textColor="#FFFFFF"
+ android:padding="4dp"
+ android:elevation="4dp"
+ android:background="@drawable/round_red_bg"
+ />
+
+</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml
new file mode 100644
index 0000000..b22fff5
--- /dev/null
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<navigation xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/nav_graph"
+ app:startDestination="@id/FirstFragment">
+
+ <fragment
+ android:id="@+id/FirstFragment"
+ android:name="com.example.firstapp.activity.FirstFragment"
+ android:label="@string/first_fragment_label"
+ tools:layout="@layout/fragment_first">
+
+ <action
+ android:id="@+id/action_FirstFragment_to_SecondFragment"
+ app:destination="@id/SecondFragment" />
+ </fragment>
+ <fragment
+ android:id="@+id/SecondFragment"
+ android:name="com.example.firstapp.activity.SecondFragment"
+ android:label="@string/second_fragment_label"
+ tools:layout="@layout/fragment_second">
+
+ <action
+ android:id="@+id/action_SecondFragment_to_FirstFragment"
+ app:destination="@id/FirstFragment" />
+ </fragment>
+</navigation>
\ No newline at end of file
diff --git a/app/src/main/res/values-land/dimens.xml b/app/src/main/res/values-land/dimens.xml
new file mode 100644
index 0000000..22d7f00
--- /dev/null
+++ b/app/src/main/res/values-land/dimens.xml
@@ -0,0 +1,3 @@
+<resources>
+ <dimen name="fab_margin">48dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values-w1240dp/dimens.xml b/app/src/main/res/values-w1240dp/dimens.xml
new file mode 100644
index 0000000..d73f4a3
--- /dev/null
+++ b/app/src/main/res/values-w1240dp/dimens.xml
@@ -0,0 +1,3 @@
+<resources>
+ <dimen name="fab_margin">200dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values-w600dp/dimens.xml b/app/src/main/res/values-w600dp/dimens.xml
new file mode 100644
index 0000000..22d7f00
--- /dev/null
+++ b/app/src/main/res/values-w600dp/dimens.xml
@@ -0,0 +1,3 @@
+<resources>
+ <dimen name="fab_margin">48dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 29be459..dd87850 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -5,4 +5,5 @@
<dimen name="list_item_spacing">16dp</dimen>
<dimen name="list_item_spacing_half">8dp</dimen>
<dimen name="heatmap_cell_size">12dp</dimen>
+ <dimen name="fab_margin">16dp</dimen>
</resources>
\ No newline at end of file
diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml
index d1689af..f8bbdd2 100644
--- a/app/src/main/res/xml/network_security_config.xml
+++ b/app/src/main/res/xml/network_security_config.xml
@@ -5,6 +5,7 @@
<domain includeSubdomains="true">192.168.1.213</domain>
<domain includeSubdomains="true">192.168.1.198</domain>
<domain includeSubdomains="true">192.168.1.199</domain>
+ <domain includeSubdomains="true">192.168.1.201</domain>
<!-- 可添加其他域名或IP(如192.168.0.101) -->
<!-- 如果本地服务使用自签名证书,需在 network_security_config.xml 中信任该证书:-->
<!-- <trust-anchors>-->
--
Gitblit v1.9.3