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