.gitignore
@@ -16,3 +16,5 @@ .externalNativeBuild .cxx local.properties .idea/ .idea/.gitignore
文件已删除 .idea/codeStyles/Project.xml
文件已删除 .idea/codeStyles/codeStyleConfig.xml
文件已删除 .idea/compiler.xml
文件已删除 .idea/deploymentTargetSelector.xml
文件已删除 .idea/gradle.xml
文件已删除 .idea/kotlinc.xml
文件已删除 .idea/migrations.xml
文件已删除 .idea/misc.xml
文件已删除 .idea/runConfigurations.xml
文件已删除 .idea/vcs.xml
文件已删除 README.md
@@ -1,6 +1,9 @@ ## FirstApp2 短信平台 # 短信平台 # 密码 # md5 ADC67C7C8E0BE3829D34E976D8EFCC9B app/build.gradle
@@ -14,7 +14,8 @@ compileSdk 34 defaultConfig { applicationId "com.example.firstapp" // applicationId "com.example.firstapp" applicationId "net.sourceforge.simcpux" minSdk 24 targetSdk 34 versionCode 1 @@ -27,7 +28,15 @@ release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' signingConfig signingConfigs.debug } debug { minifyEnabled false debuggable true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' signingConfig signingConfigs.debug } } compileOptions { sourceCompatibility JavaVersion.VERSION_17 @@ -109,6 +118,23 @@ excludes += ["META-INF/*.kotlin_module", "META-INF/*.version", "kotlin/**", "DebugProbesKt.bin"] } } signingConfigs { release { storeFile file('../keystore/sms-manager.jks') storePassword 'Cloudroam!@#123' keyAlias 'sm' keyPassword 'Cloudroam!@#123' } debug { storeFile file('../keystore/keystore.jks') storePassword 'android' keyAlias 'android' } } } dependencies { @@ -123,6 +149,7 @@ implementation libs.androidx.navigation.ui.ktx implementation libs.androidx.legacy.support.v4 implementation libs.androidx.recyclerview implementation libs.androidx.activity testImplementation libs.junit androidTestImplementation libs.androidx.junit androidTestImplementation libs.androidx.espresso.core @@ -294,4 +321,7 @@ implementation 'de.hdodenhof:circleimageview:3.1.0' implementation 'com.github.castorflex:SmoothProgressBar:1.1.0' api 'com.tencent.mm.opensdk:wechat-sdk-android:+' } app/src/main/AndroidManifest.xml
@@ -83,16 +83,29 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.FirstApp" tools:targetApi="31" android:usesCleartextTraffic="true" > tools:targetApi="31"> <activity android:name=".activity.SettingActivity" android:configChanges="orientation|keyboardHidden|screenSize" android:exported="false" android:label="@string/title_activity_setting" android:theme="@style/Theme.FirstApp.Fullscreen" /> <activity android:name=".pay.wxpay.WXPayEntryActivity" android:exported="true" android:launchMode="singleTop" /> <!-- 微信支付回调组件别名 --> <activity-alias android:name="${applicationId}.wxapi.WXPayEntryActivity" android:exported="true" android:targetActivity=".pay.wxpay.WXPayEntryActivity" android:theme="@android:style/Theme.NoDisplay" /> <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="remove" /> <activity android:name=".activity.VipActivity" @@ -127,11 +140,10 @@ android:theme="@style/Theme.ContentDetail" /> <activity android:name=".ui.profile.EditProfileActivity" android:exported="false"/> android:exported="false" /> <activity android:name=".ui.invitation.InvitationActivity" android:exported="false"/> android:exported="false" /> </application> </manifest> app/src/main/java/com/example/firstapp/activity/LoginActivity.kt
@@ -1,9 +1,24 @@ package com.example.firstapp.activity import android.app.AlertDialog import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import android.content.Intent import android.graphics.Color import android.text.SpannableString import android.text.Spanned import android.text.TextPaint import android.text.method.LinkMovementMethod import android.text.style.ClickableSpan import android.view.LayoutInflater import android.view.View import android.widget.Button import android.widget.CheckBox import android.widget.TextView import com.example.firstapp.R import com.example.firstapp.databinding.ActivityLoginBinding import com.example.firstapp.utils.PreferencesManager import kotlin.system.exitProcess class LoginActivity : AppCompatActivity() { private lateinit var binding: ActivityLoginBinding @@ -13,6 +28,12 @@ binding = ActivityLoginBinding.inflate(layoutInflater) setContentView(binding.root) setupViews() val phone=PreferencesManager.getLastLoginPhone() // 如果phone不存在则展示弹框 if (phone.isNullOrEmpty()) { showConfirmDialog() } } private fun setupViews() { @@ -41,4 +62,99 @@ } } private fun showConfirmDialog() { val dialogView = LayoutInflater.from(this).inflate(R.layout.login_protocol_dialog_custom, null) val dialog = AlertDialog.Builder(this) .setView(dialogView) .create() dialog.window?.setBackgroundDrawableResource(R.drawable.dialog_background) val btnConfirm = dialogView.findViewById<Button>(R.id.btnConfirm) btnConfirm.setOnClickListener { dialog.dismiss() } val btnCancel = dialogView.findViewById<Button>(R.id.btnCancel) btnCancel.setOnClickListener { dialog.dismiss() // 退出整个应用 finishAffinity() // 关闭当前Activity和它之上的所有Activity exitProcess(0) // 终止应用进程(需要引入 kotlin.system.exitProcess) } // 👇 设置可点击文字逻辑 val textView = dialogView.findViewById<TextView>(R.id.dialogMessage2) val content = "您可以阅读「服务使用协议」和「隐私保护政策」了解相关信息。如果您同意,请点击同意,开始使用我们的服务。" val spannableString = SpannableString(content) val serviceStart = content.indexOf("「服务使用协议」") val serviceEnd = serviceStart + "「服务使用协议」".length val privacyStart = content.indexOf("「隐私保护政策」") val privacyEnd = privacyStart + "「隐私保护政策」".length spannableString.setSpan(object : ClickableSpan() { override fun onClick(widget: View) { startContentActivity("用户协议", "服务使用协议") // Toast.makeText(this@LoginActivity, "点击了服务使用协议", Toast.LENGTH_SHORT).show() // 可跳转 WebViewActivity 或打开链接 } override fun updateDrawState(ds: TextPaint) { super.updateDrawState(ds) ds.color = Color.parseColor("#1E88E5") ds.isUnderlineText = false } }, serviceStart, serviceEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) spannableString.setSpan(object : ClickableSpan() { override fun onClick(widget: View) { startContentActivity("隐私协议", "隐私保护政策") // Toast.makeText(this@LoginActivity, "点击了隐私保护政策", Toast.LENGTH_SHORT).show() } override fun updateDrawState(ds: TextPaint) { super.updateDrawState(ds) ds.color = Color.parseColor("#1E88E5") ds.isUnderlineText = false } }, privacyStart, privacyEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) textView.text = spannableString textView.movementMethod = LinkMovementMethod.getInstance() dialog.show() } /* private fun showConfirmDialog() { val dialogView = LayoutInflater.from(this).inflate(R.layout.login_protocol_dialog_custom, null) val dialog = AlertDialog.Builder(this) .setView(dialogView) .create() // 设置自定义背景 dialog.window?.setBackgroundDrawableResource(R.drawable.dialog_background) // 获取按钮并设置点击事件 val btnConfirm = dialogView.findViewById<Button>(R.id.btnConfirm) btnConfirm.setOnClickListener { // 将协议勾选上 dialog.dismiss() } // 显示对话框 dialog.show() }*/ private fun startContentActivity(id: String, title: String) { val intent = Intent(this, ContentDetailActivity::class.java).apply { putExtra(ContentDetailActivity.ID, id) putExtra(ContentDetailActivity.EXTRA_TITLE, title) } startActivity(intent) } } app/src/main/java/com/example/firstapp/activity/SettingActivity.kt
对比新文件 @@ -0,0 +1,141 @@ package com.example.firstapp.activity import androidx.appcompat.app.AppCompatActivity import android.annotation.SuppressLint import android.app.AlertDialog import android.content.Intent import android.os.Build import android.os.Bundle import android.os.Handler import android.os.Looper import android.view.Gravity import android.view.MenuItem import android.view.MotionEvent import android.view.View import android.view.WindowInsets import android.widget.LinearLayout import android.widget.TextView import androidx.appcompat.widget.Toolbar import androidx.lifecycle.ViewModelProvider import com.example.firstapp.databinding.ActivitySettingBinding import com.example.firstapp.R import com.example.firstapp.ui.home.HomeViewModel /** * An example full-screen activity that shows and hides the system UI (i.e. * status bar and navigation/system bar) with user interaction. */ class SettingActivity : AppCompatActivity() { private lateinit var binding: ActivitySettingBinding private val homeViewModel: HomeViewModel by lazy { ViewModelProvider(this).get(HomeViewModel::class.java) } private var isFullscreen: Boolean = false @SuppressLint("ClickableViewAccessibility") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivitySettingBinding.inflate(layoutInflater) setContentView(binding.root) var toolbar=binding.settingToolbar // 获取 Toolbar 并设置为 ActionBar setSupportActionBar(toolbar) // 显示返回按钮 supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true) // 设置标题(如果没有在 XML 中设置标题,可以在代码中动态设置) supportActionBar?.title = "" // binding.settingExit.setOnClickListener(View.OnClickListener { // // homeViewModel.logout() // // 跳转到vipActivity // val intent = Intent(this, LoginActivity::class.java) // intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK // startActivity(intent) // // }) binding.settingExit.setOnClickListener { // 弹出确认退出的对话框 val alertDialog = AlertDialog.Builder(this) .setTitle("确认退出") .setMessage("您确定要退出吗?") .setPositiveButton("确认") { dialog, _ -> // 确认退出 homeViewModel.logout() // 跳转到 LoginActivity 并清除之前的任务栈 val intent = Intent(this, LoginActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK startActivity(intent) // 关闭当前页面 finish() } .setNegativeButton("取消") { dialog, _ -> // 取消退出操作 dialog.dismiss() } .create() // 显示对话框 alertDialog.show() } } // 点击返回按钮时调用 override fun onOptionsItemSelected(item: MenuItem): Boolean { if (item.itemId == android.R.id.home) { onBackPressed() return true } return super.onOptionsItemSelected(item) } override fun onPostCreate(savedInstanceState: Bundle?) { super.onPostCreate(savedInstanceState) // Trigger the initial hide() shortly after the activity has been // created, to briefly hint to the user that UI controls // are available. delayedHide(100) } private fun toggle() { if (isFullscreen) { hide() } else { show() } } private fun hide() { // Hide UI first supportActionBar?.hide() } private fun show() { } private fun delayedHide(delayMillis: Int) { } } app/src/main/java/com/example/firstapp/activity/VipActivity.kt
@@ -252,8 +252,9 @@ Toast.makeText(this@VipActivity, "请勾选协议", Toast.LENGTH_LONG).show() return@launch // 直接 return,不往下执行 } Toast.makeText(this@VipActivity, "功能暂未开放", Toast.LENGTH_LONG).show() return@launch // Toast.makeText(this@VipActivity, "功能暂未开放", Toast.LENGTH_LONG).show() // return@launch doWechatPay() } catch (e: Exception) { @@ -266,6 +267,23 @@ } private fun doWechatPay() { val map=HashMap<String,String>() map["appId"]="wxb4ba3c02aa476ea1" map["partnerid"]="1900006771" map["package"]="Sign=WXPay" map["noncestr"]="2ac6c60ebfe7e549fbbc922ac54269bb" map["timeStamp"]="1606317975" map["prepayid"]="wx25232614962974fb29d1227819cc3e000g" map["sign"]="wx25232614962974fb29d1227819cc3e000g" PayAbility.wxPay(this, map, Observer { success -> if (success == 0) { Toast.makeText(this@VipActivity, "支付失败", Toast.LENGTH_LONG).show() } else { Toast.makeText(this@VipActivity, "支付成功", Toast.LENGTH_LONG).show() } }) } private fun vipCardInit() { val recyclerView = findViewById<RecyclerView>(R.id.recycler_view) app/src/main/java/com/example/firstapp/database/service/ApiService.kt
@@ -62,7 +62,7 @@ suspend fun getUserInfo(@Path("phone") phone: String): ApiResponse<UserInfo> @Multipart @POST("flower/api/supplier/operation/update") @POST("api/supplier/operation/update") suspend fun updateProfile( @Part("nickname") nickname: RequestBody, @Part avatar: MultipartBody.Part? @@ -78,8 +78,8 @@ // 创建Retrofit实例(单例) object RetrofitClient{ // private const val BASE_URL ="http://192.168.1.198:8080/flower/" private const val BASE_URL ="http://14.103.144.28:8080/flower/" private const val BASE_URL ="http://192.168.1.198:8080/flower/" // private const val BASE_URL ="http://14.103.144.28:8080/flower/" // 创建OkHttpClient,配置拦截器和超时时间 app/src/main/java/com/example/firstapp/pay/PayAbility.kt
文件已删除 app/src/main/java/com/example/firstapp/pay/alipay/AliPayHelper.kt
app/src/main/java/com/example/firstapp/pay/alipay/PayAbility.kt
对比新文件 @@ -0,0 +1,35 @@ package com.example.firstapp.pay import android.app.Activity import androidx.fragment.app.FragmentActivity import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer object PayAbility { private val wxPayResultLiveData = MutableLiveData<Int?>() /** * 支付宝支付方法 */ fun aliPay(activity: Activity, orderInfo: String, observer: Observer<PayResult>) { AliPayHelper.pay(activity, orderInfo, observer) } /** * 微信支付方法 */ fun wxPay(activity: Activity, orderInfo: Map<String,String>, observer: Observer<Int?>) { if(activity is FragmentActivity){ wxPayResultLiveData.observe(activity, observer) } WxPayHelper.pay(activity, orderInfo, observer) } internal fun postWXPayResult(result: Int) { wxPayResultLiveData.postValue(result) wxPayResultLiveData.value= null } } app/src/main/java/com/example/firstapp/pay/alipay/PayResult.kt
app/src/main/java/com/example/firstapp/pay/wxpay/WXPayEntryActivity.java
对比新文件 @@ -0,0 +1,44 @@ package com.example.firstapp.pay.wxpay; import android.app.Activity; import android.os.Bundle; import android.util.Log; import com.tencent.mm.opensdk.constants.ConstantsAPI; import com.tencent.mm.opensdk.modelbase.BaseReq; import com.tencent.mm.opensdk.modelbase.BaseResp; import com.tencent.mm.opensdk.openapi.IWXAPI; import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler; import com.tencent.mm.opensdk.openapi.WXAPIFactory; public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler { private static final String TAG = "WXPayEntryActivity"; private IWXAPI api; @Override protected void onCreate(Bundle savedInstanceState) { getWindow().setBackgroundDrawable(null); super.onCreate(savedInstanceState); api= WXAPIFactory.createWXAPI(this,"wxb4ba302aa476ea1"); api.handleIntent(getIntent(),this); } @Override public void onReq(BaseReq baseReq) { } @Override public void onResp(BaseResp baseResp) { Log.d(TAG,"onPayFinish,errCode="+baseResp.errCode); if(baseResp.getType()== ConstantsAPI.COMMAND_PAY_BY_WX){ finish(); } } } app/src/main/java/com/example/firstapp/pay/wxpay/WxPayHelper.kt
对比新文件 @@ -0,0 +1,42 @@ package com.example.firstapp.pay import android.app.Activity import android.text.TextUtils import androidx.lifecycle.Observer import com.alipay.sdk.app.PayTask import com.example.firstapp.utils.AppGlobals import com.example.firstapp.utils.Log import com.tencent.mm.opensdk.modelpay.PayReq import com.tencent.mm.opensdk.openapi.WXAPIFactory object WxPayHelper { private val api=WXAPIFactory.createWXAPI(AppGlobals.get(), "wx4f794c0f0f0f0f0f",true) init { api.registerApp("wx4f794c0f0f0f0f0f") } fun pay(activity: Activity, params:Map<String,String>,observer:Observer<Int?>) { // 开启线程 Thread { try { val req=PayReq() req.appId=params["appid"] req.partnerId=params["partnerid"] req.prepayId=params["prepayid"] req.nonceStr=params["noncestr"] req.timeStamp=params["timestamp"] req.packageValue=params["package"] req.sign=params["sign"] req.signType=params["signType"] req.extData=params["extData"] api.sendReq(req) } catch (e: Exception) { e.printStackTrace() } }.start() } } 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.SettingActivity import com.example.firstapp.activity.VipActivity import com.example.firstapp.database.response.UserInfo import com.example.firstapp.ui.invitation.InvitationActivity @@ -95,6 +96,14 @@ } return binding.root } override fun onResume() { super.onResume() // 加载用户信息 lifecycleScope.launch { loadUserInfo() } } private suspend fun loadConfigurations() { @@ -217,6 +226,13 @@ startActivity(intent) } // 设置按钮点击 binding.ivSetting.setOnClickListener { // 跳转到 val intent = Intent(requireContext(), SettingActivity::class.java) startActivity(intent) } } app/src/main/java/com/example/firstapp/ui/profile/EditProfileActivity.kt
@@ -18,8 +18,11 @@ import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import com.bumptech.glide.Glide import com.example.firstapp.database.response.UserInfo import com.example.firstapp.databinding.ActivityEditProfileBinding import com.example.firstapp.database.service.ApiService import com.example.firstapp.database.service.RetrofitClient import com.example.firstapp.utils.PreferencesManager import kotlinx.coroutines.launch import java.io.File import okhttp3.MediaType.Companion.toMediaType @@ -31,7 +34,6 @@ class EditProfileActivity : AppCompatActivity() { private lateinit var binding: ActivityEditProfileBinding private var selectedImageUri: Uri? = null private lateinit var apiService: ApiService private var loadingDialog: AlertDialog? = null private val pickImage = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> @@ -114,12 +116,38 @@ } // 调用更新接口 apiService.updateProfile( RetrofitClient.apiService.updateProfile( nickname = nicknameBody, avatar = avatarPart ) Toast.makeText(this@EditProfileActivity, "保存成功", Toast.LENGTH_SHORT).show() // 更新用户信息 // 从本地获取保存的手机号 val savedPhone = PreferencesManager.getPhone() if (savedPhone.isNullOrEmpty()) { Toast.makeText(this@EditProfileActivity, "用户未登录", Toast.LENGTH_SHORT).show() return@launch } val response = RetrofitClient.apiService.getUserInfo(savedPhone) if (response.code == "0" && response.data != null) { // 保存用户信息 val userInfo:UserInfo = response.data // 获取传入的数据 val currentNickname = userInfo.name val currentAvatarUrl = userInfo.cover // 设置当前数据 binding.etNickname.setText(currentNickname) if (!currentAvatarUrl.isNullOrEmpty()) { Glide.with(this@EditProfileActivity) .load(currentAvatarUrl) .circleCrop() .into(binding.ivAvatar) } } finish() } catch (e: Exception) { app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardFragment.kt
@@ -53,6 +53,7 @@ Glide.with(this) .load(viewModel.cover) .circleCrop() .transform(RoundedCorners(100)) // 设置圆角 // .error(R.drawable.error_placeholder) // 如果加载失败,显示占位图 .error(R.mipmap.avatar_default) @@ -118,6 +119,7 @@ viewModel.cover.collect { coverUrl -> Glide.with(this@MemberInfoCardFragment) .load(coverUrl) .circleCrop() .transform(RoundedCorners(100)) .error(R.drawable.error_placeholder) .into(binding.memberAvatarView) @@ -132,6 +134,7 @@ .transform(RoundedCorners(100)) .error(R.drawable.error_placeholder) .into(binding.memberImageView) } } app/src/main/java/com/example/firstapp/utils/AppGlobals.kt
对比新文件 @@ -0,0 +1,29 @@ package com.example.firstapp.utils import android.app.Application import java.lang.Exception /** * 这种方式获取全局的Application 是一种拓展思路。 * * * 对于组件化项目,不可能把项目实际的Application下沉到Base,而且各个module也不需要知道Application真实名字 * * * 这种一次反射就能获取全局Application对象的方式相比于在Application#OnCreate保存一份的方式显示更加通用了 */ object AppGlobals { private var application: Application? = null fun get(): Application? { if (application == null) { try { application = Class.forName("android.app.ActivityThread") .getMethod("currentApplication") .invoke(null) as Application } catch (ex: Exception) { ex.printStackTrace() } } return application } } app/src/main/res/layout/activity_setting.xml
对比新文件 @@ -0,0 +1,61 @@ <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#F0F2F5" tools:context=".activity.SettingActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- Toolbar (标题栏) --> <androidx.appcompat.widget.Toolbar android:id="@+id/setting_toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#F9F9F9" android:elevation="4dp" android:layout_gravity="center" android:gravity="center"> <!-- 自定义标题 TextView --> <TextView android:id="@+id/toolbar_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="设置" android:textColor="@android:color/black" android:textSize="18sp" android:layout_gravity="center" android:gravity="center" /> <!-- 确保标题居中 --> </androidx.appcompat.widget.Toolbar> <LinearLayout android:id="@+id/setting_exit" android:layout_width="match_parent" android:layout_height="50dp" android:gravity="center" android:orientation="vertical" android:background="#F9F9F9" android:layout_marginTop="20dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:text="退出登录" android:textColor="#E23C2F" /> </LinearLayout> </LinearLayout> </FrameLayout> app/src/main/res/layout/activity_wxpay_entry.xml
对比新文件 @@ -0,0 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".pay.wxpay.WXPayEntryActivity"> </androidx.constraintlayout.widget.ConstraintLayout> app/src/main/res/layout/fragment_member_info_card.xml
@@ -36,15 +36,26 @@ android:background="@android:color/transparent" > <ImageView <!-- <ImageView--> <!-- android:id="@+id/memberAvatarView"--> <!-- android:layout_width="25dp"--> <!-- android:layout_height="27dp"--> <!-- android:layout_marginLeft="10dp"--> <!-- android:scaleType="centerCrop"--> <!-- app:layout_constraintStart_toStartOf="parent"--> <!-- app:layout_constraintTop_toTopOf="parent"--> <!-- />--> <com.google.android.material.imageview.ShapeableImageView android:id="@+id/memberAvatarView" android:layout_width="40dp" android:layout_height="40dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:scaleType="centerCrop" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" app:shapeAppearanceOverlay="@style/CircleImageView" /> <TextView android:id="@+id/phoneNumberText" app/src/main/res/layout/fragment_notifications.xml
@@ -19,6 +19,27 @@ android:layout_height="32dp" android:scaleType="centerCrop" /> <LinearLayout android:layout_width="match_parent" android:layout_height="25dp" android:gravity="center_vertical" android:orientation="horizontal"> <View android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <ImageView android:id="@+id/iv_setting" android:layout_width="28dp" android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:contentDescription="设置" android:src="@mipmap/setting" /> </LinearLayout> <!-- 用户信息区域 - 减小padding --> <RelativeLayout android:id="@+id/layout_user_info" app/src/main/res/layout/login_protocol_dialog_custom.xml
对比新文件 @@ -0,0 +1,89 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:background="@drawable/dialog_background" android:padding="20dp" android:gravity="center" > <!-- 标题 --> <TextView android:id="@+id/dialogTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="服务协议和隐私政策" android:textSize="20sp" android:textColor="#000000" android:gravity="center" android:paddingBottom="10dp" /> <View android:id="@+id/divider" android:layout_width="match_parent" android:layout_height="1dp" android:background="#E2E2E2" android:layout_marginTop="5dp" android:layout_marginHorizontal="0dp" /> <!-- 内容 --> <TextView android:id="@+id/dialogMessage" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="请您务必阅读、理解「服务协议】和「隐私政策」,我们仅会收集提供服务必要的信息:未经您同意,我们不会与第三方共享与披露您的个人隐私信息。" android:textSize="16sp" android:textColor="#000000" android:gravity="left" android:layout_marginTop="5dp" android:paddingBottom="20dp" /> <TextView android:id="@+id/dialogMessage2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="您可以阅读「服务使用协议」和「隐私保护政策」了解相关信息。如果您同意,请点击「同意,开始使用我们的服务。" android:textSize="16sp" android:textColor="#000000" android:gravity="left" android:paddingBottom="20dp" /> <!-- 按钮 --> <Button android:id="@+id/btnConfirm" android:layout_width="200dp" android:layout_height="wrap_content" android:text="同意" android:textColor="@android:color/white" android:backgroundTint="#000000" android:gravity="center" /> <!-- <Button--> <!-- android:id="@+id/btnCancel"--> <!-- android:layout_width="200dp"--> <!-- android:layout_height="wrap_content"--> <!-- android:text="不同意"--> <!-- android:textColor="@android:color/white"--> <!-- android:backgroundTint="#000000"--> <!-- android:gravity="center" />--> <Button android:id="@+id/btnCancel" android:layout_width="200dp" android:layout_height="wrap_content" android:text="不同意" android:textColor="#999999" android:background="@android:color/transparent" android:gravity="center" android:elevation="0dp" android:stateListAnimator="@null" /> </LinearLayout> app/src/main/res/mipmap/setting.png
app/src/main/res/navigation/nav_graph2.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_graph2" app:startDestination="@id/First2Fragment"> <fragment android:id="@+id/First2Fragment" android:name="com.example.firstapp.pay.wxpay.First2Fragment" android:label="@string/first_fragment_label" tools:layout="@layout/fragment_first2"> <action android:id="@+id/action_First2Fragment_to_Second2Fragment" app:destination="@id/Second2Fragment" /> </fragment> <fragment android:id="@+id/Second2Fragment" android:name="com.example.firstapp.pay.wxpay.Second2Fragment" android:label="@string/second_fragment_label" tools:layout="@layout/fragment_second2"> <action android:id="@+id/action_Second2Fragment_to_First2Fragment" app:destination="@id/First2Fragment" /> </fragment> </navigation> app/src/main/res/values-night/themes.xml
对比新文件 @@ -0,0 +1,12 @@ <resources xmlns:tools="http://schemas.android.com/tools"> <!-- Base application theme. --> <style name="Base.Theme.FirstApp" parent="Theme.Material3.DayNight.NoActionBar"> <!-- Customize your dark theme here. --> <!-- <item name="colorPrimary">@color/my_dark_primary</item> --> </style> <style name="ThemeOverlay.FirstApp.FullscreenContainer" parent=""> <item name="fullscreenBackgroundColor">@color/light_blue_900</item> <item name="fullscreenTextColor">@color/light_blue_A400</item> </style> </resources> app/src/main/res/values-v23/themes.xml
@@ -1,9 +1,16 @@ <resources xmlns:tools="http://schemas.android.com/tools"> <!-- <style name="Theme.FirstApp" parent="Base.Theme.FirstApp">--> <!-- <!– Transparent system bars for edge-to-edge. –>--> <!-- <item name="android:navigationBarColor">@android:color/transparent</item>--> <!-- <item name="android:statusBarColor">@android:color/transparent</item>--> <!-- <item name="android:windowLightStatusBar">?attr/isLightTheme</item>--> <!-- </style>--> <!-- <style name="Theme.FirstApp" parent="Base.Theme.FirstApp">--> <!-- <!– Transparent system bars for edge-to-edge. –>--> <!-- <item name="android:navigationBarColor">@android:color/transparent</item>--> <!-- <item name="android:statusBarColor">@android:color/transparent</item>--> <!-- <item name="android:windowLightStatusBar">?attr/isLightTheme</item>--> <!-- </style>--> <style name="Theme.FirstApp" parent="Base.Theme.FirstApp"> <!-- Transparent system bars for edge-to-edge. --> <item name="android:navigationBarColor">@android:color/transparent</item> <item name="android:statusBarColor">@android:color/transparent</item> <item name="android:windowLightStatusBar">?attr/isLightTheme</item> </style> </resources> app/src/main/res/values/colors.xml
@@ -16,5 +16,6 @@ <color name="light_blue_50">#E1F5FE</color> <color name="tab_selected">#FF039BE5</color> <color name="light_blue_new">#02A7F0</color> <color name="light_grey">#F6F7FB </color> 灰色主题 <color name="light_grey">#F6F7FB</color> 灰色主题 </resources> app/src/main/res/values/strings.xml
@@ -94,5 +94,6 @@ <string name="invite_reward_text"><![CDATA[ 每邀请1位新用户<font color="#FF0000"><b><i><u>可得</u></i></b></font> ]]></string> <string name="title_activity_setting">SettingActivity</string> </resources> app/src/main/res/values/styles.xml
@@ -55,4 +55,12 @@ <item name="cornerFamily">rounded</item> <item name="cornerSize">50%</item> </style> <!-- 自定义标题样式 --> <style name="ToolbarTitleStyle"> <item name="android:textSize">18sp</item> <!-- 设置标题字体大小 --> <item name="android:gravity">center</item> <!-- 设置标题居中 --> <item name="android:textColor">#000000</item> <!-- 设置标题颜色 --> </style> </resources> app/src/main/res/values/themes.xml
@@ -23,9 +23,9 @@ </style> <style name="Theme.FirstApp.Fullscreen" parent="Theme.FirstApp"> <!-- <item name="android:actionBarStyle">@style/Widget.Theme.FirstApp.ActionBar.Fullscreen</item>--> <!-- <item name="android:windowActionBarOverlay">true</item>--> <!-- <item name="android:windowBackground">@null</item>--> <!-- <item name="android:actionBarStyle">@style/Widget.Theme.FirstApp.ActionBar.Fullscreen</item>--> <!-- <item name="android:windowActionBarOverlay">true</item>--> <!-- <item name="android:windowBackground">@null</item>--> </style> <style name="ThemeOverlay.FirstApp.FullscreenContainer" parent=""> gradle.properties
@@ -35,5 +35,8 @@ android.precompileDependenciesResources=false android.enableJetifier=true #android.enableD8=true org.gradle.java.home=D\:\\tanjiyaun\\jdk\\jdk1.8\\jdk-17.0.12 org.gradle.java.home=D\:\\devInstall\\java\\jdk-17.0.12 # ?????? WX_PAY_APP_ID=wxb4ba302aa476ea1 gradle/libs.versions.toml
@@ -15,6 +15,7 @@ legacySupportV4 = "1.0.0" fragmentKtx = "1.5.6" recyclerview = "1.3.0" activity = "1.8.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -31,6 +32,7 @@ androidx-legacy-support-v4 = { group = "androidx.legacy", name = "legacy-support-v4", version.ref = "legacySupportV4" } androidx-fragment-ktx = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "fragmentKtx" } androidx-recyclerview = { group = "androidx.recyclerview", name = "recyclerview", version.ref = "recyclerview" } androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } keystore/keystore.jksBinary files differ
keystore/sms-manager.jksBinary files differ
keytool