From f496392b24eb9c9a38498cbbf03159ef5aa037d1 Mon Sep 17 00:00:00 2001
From: tj <1378534974@qq.com>
Date: 星期一, 21 四月 2025 15:38:08 +0800
Subject: [PATCH] 1.好友邀请-我的邀请记录:列表样式重写,图片显示 2.已登录的用户点击应用图标之后直接登录
---
app/src/main/java/com/example/firstapp/ui/invitation/InvitationActivity.kt | 337 +++++++++++++++++++++++++++++++++----------------------
1 files changed, 202 insertions(+), 135 deletions(-)
diff --git a/app/src/main/java/com/example/firstapp/ui/invitation/InvitationActivity.kt b/app/src/main/java/com/example/firstapp/ui/invitation/InvitationActivity.kt
index 55d957f..9fb0021 100644
--- a/app/src/main/java/com/example/firstapp/ui/invitation/InvitationActivity.kt
+++ b/app/src/main/java/com/example/firstapp/ui/invitation/InvitationActivity.kt
@@ -1,21 +1,49 @@
package com.example.firstapp.ui.invitation
+import android.app.Dialog
+import android.content.ClipData
+import android.content.ClipboardManager
import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.graphics.Color
+import android.graphics.drawable.BitmapDrawable
+import android.graphics.drawable.ColorDrawable
+import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.text.Html
import android.util.TypedValue
import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import android.widget.ImageView
+import android.widget.LinearLayout
import android.widget.TextView
+import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat
+import androidx.core.content.FileProvider
+import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearSmoothScroller
import androidx.recyclerview.widget.RecyclerView
+import com.example.firstapp.App.Companion.context
import com.example.firstapp.R
import com.example.firstapp.adapter.InvitationAdapter
+import com.example.firstapp.adapter.InvitationRecord2Adapter
import com.example.firstapp.adapter.InvitationRecordAdapter
+import com.example.firstapp.database.request.SmsLoginRequest
+import com.example.firstapp.database.service.RetrofitClient
import com.example.firstapp.entity.InvitationRecord
+import com.example.firstapp.utils.Log
+import com.example.firstapp.utils.PreferencesManager
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
+import java.io.FileOutputStream
import kotlin.math.abs
class InvitationActivity : AppCompatActivity() {
@@ -23,14 +51,19 @@
private lateinit var recyclerSuccessView: RecyclerView
private lateinit var recyclerRecordView: RecyclerView
private lateinit var adapter: InvitationAdapter
- private lateinit var recordadapter: InvitationRecordAdapter
- private val data = mutableListOf<InvitationRecord>()
- private val recorddata = mutableListOf<InvitationRecord>()
+// private lateinit var recordadapter: InvitationRecordAdapter
+ private var data = mutableListOf<InvitationRecord>()
+ private var recorddata = mutableListOf<InvitationRecord>()
private val handler = Handler(Looper.getMainLooper())
private val scrollInterval = 3000L
private var currentScrollPosition = 0
private var currentRecordScrollPosition = 0
private var itemHeight = 0 // 动态存储item高度
+
+ private lateinit var invitedRecordRecyclerView2: RecyclerView
+ private lateinit var invitationAdapter: InvitationRecord2Adapter
+
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -42,99 +75,70 @@
//初始化Adapter
initSuccessAdapter()
- initRecorddapter()
+// initRecorddapter()
//加载数据
- loadData()
-
- loadRecordData()
+ getInvitereward()
//启动轮播
startAutoScroll()
+
+ //分享
+ val btnInvite = findViewById<Button>(R.id.btnInvite)
+ btnInvite.setOnClickListener {
+ showImagePreviewDialog()
+ }
+
+ //邀请码
+ val invitationCodeText = findViewById<TextView>(R.id.invitationCodeText)
+ invitationCodeText.text = formatInvitationCode(PreferencesManager.getInviteCode());
+ findViewById<Button>(R.id.copyButton).setOnClickListener {
+ val clipboard = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
+ val clip = ClipData.newPlainText(
+ "邀请码",
+ invitationCodeText.text.toString().replace(" ", "") // 复制时去掉空格
+ )
+ clipboard.setPrimaryClip(clip)
+ Toast.makeText(this, "已复制邀请码", Toast.LENGTH_SHORT).show()
+ }
+
+
}
+
private fun initViews() {
findViewById<TextView>(R.id.tv_notic).apply {
text = Html.fromHtml(getString(R.string.invite_reward_text), Html.FROM_HTML_MODE_LEGACY)
}
+
+ // 成功列表
recyclerSuccessView = findViewById(R.id.invitationsuccessRecyclerView)
- addSuccessListener()
-
- recyclerRecordView = findViewById(R.id.invitationrecordRecyclerView)
- addRecordListener()
- }
-
- private fun addSuccessListener(){
recyclerSuccessView.viewTreeObserver.addOnGlobalLayoutListener {
if (recyclerSuccessView.childCount > 0) {
- // 计算预期高度(60dp转px)
val expectedHeight = dpToPx(60f)
- if(itemHeight!= expectedHeight){
- // 修正所有item的高度
+ if (itemHeight != expectedHeight) {
for (i in 0 until recyclerSuccessView.childCount) {
recyclerSuccessView.getChildAt(i).layoutParams.height = expectedHeight
}
- // 请求重新布局
recyclerSuccessView.requestLayout()
itemHeight = expectedHeight
}
}
}
- recyclerSuccessView.layoutManager = object : LinearLayoutManager(this@InvitationActivity) {
- override fun onMeasure(
- recycler: RecyclerView.Recycler, state: RecyclerView.State,
- widthSpec: Int, heightSpec: Int
- ) {
- if (itemHeight > 0) {
- // 使用实际测量的高度
- setMeasuredDimension(
- View.resolveSize(widthSpec, width),
- itemHeight
- )
- } else {
- // 默认高度60dp
- val defaultHeight = TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP, 60f,
- resources.displayMetrics
- ).toInt()
- setMeasuredDimension(
- View.resolveSize(widthSpec, width),
- defaultHeight
- )
- }
- }
- }
- }
- private fun addRecordListener(){
- recyclerRecordView.viewTreeObserver.addOnGlobalLayoutListener {
- if (recyclerSuccessView.childCount > 0) {
- // 计算预期高度(60dp转px)
- val expectedHeight = dpToPx(60f)
- if(itemHeight!= expectedHeight){
- // 修正所有item的高度
- for (i in 0 until recyclerSuccessView.childCount) {
- recyclerSuccessView.getChildAt(i).layoutParams.height = expectedHeight
- }
- // 请求重新布局
- recyclerSuccessView.requestLayout()
- itemHeight = expectedHeight
- }
- }
- }
- recyclerRecordView.layoutManager = object : LinearLayoutManager(this@InvitationActivity) {
+
+ recyclerSuccessView.layoutManager = object : LinearLayoutManager(this) {
override fun onMeasure(
- recycler: RecyclerView.Recycler, state: RecyclerView.State,
+ recycler: RecyclerView.Recycler,
+ state: RecyclerView.State,
widthSpec: Int, heightSpec: Int
) {
if (itemHeight > 0) {
- // 使用实际测量的高度
setMeasuredDimension(
View.resolveSize(widthSpec, width),
itemHeight
)
} else {
- // 默认高度60dp
val defaultHeight = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 60f,
resources.displayMetrics
@@ -146,6 +150,9 @@
}
}
}
+ // 记录列表
+// recyclerRecordView = findViewById(R.id.invitationrecordRecyclerView)
+// recyclerRecordView.layoutManager = LinearLayoutManager(this)
}
private fun initSuccessAdapter() {
@@ -164,48 +171,147 @@
recyclerSuccessView.adapter = adapter
}
- private fun initRecorddapter() {
- recordadapter = InvitationRecordAdapter(this, recorddata).apply {
- registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
- override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
- // 数据插入时检查高度
- recyclerRecordView.post {
- if (recyclerRecordView.childCount > 0) {
- itemHeight = recyclerRecordView.getChildAt(0).height
+// private fun initRecorddapter() {
+// recordadapter = InvitationRecordAdapter(this, recorddata)
+// recyclerRecordView.adapter = recordadapter
+// }
+// private fun initRecorddapter() {
+// recordadapter = InvitationRecordAdapter(this, recorddata).apply {
+// registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
+// override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
+// // 数据插入时检查高度
+// recyclerRecordView.post {
+// if (recyclerRecordView.childCount > 0) {
+// itemHeight = recyclerRecordView.getChildAt(0).height
+// }
+// }
+// }
+// })
+// }
+// recyclerRecordView.adapter = recordadapter
+// }
+
+ private fun getInvitereward() {
+ lifecycleScope.launch {
+ try {
+ val response = RetrofitClient.apiService.getInvitereward()
+ if (response.code == "0") {
+ response.data?.let { records ->
+ // 正确更新现有列表(保持原有引用)
+ data.apply {
+ clear()
+ addAll(records.successInvite ?: emptyList())
}
+
+ recorddata.apply {
+ clear()
+ addAll(records.myInvite ?: emptyList()) // 注意这里使用myInvite
+ }
+
+ // 加载适配器
+ invitedRecordRecyclerView2 = findViewById(R.id.invited_record_recycler_view_2)
+ invitedRecordRecyclerView2.layoutManager = LinearLayoutManager(this@InvitationActivity)
+ invitationAdapter = InvitationRecord2Adapter(records.myInvite)
+ invitedRecordRecyclerView2.adapter = invitationAdapter
+
+
+ // 在UI线程更新适配器
+ withContext(Dispatchers.Main) {
+ adapter.notifyDataSetChanged()
+// recordadapter.notifyDataSetChanged()
+ }
+ } ?: run {
+ Log.w("API", "Response data is null")
}
+ } else {
+ Log.w("API", "Server error: ${response.msg}")
}
- })
+ } catch (e: Exception) {
+ Log.e("getinviterewardError", "message: ${e.message}", e)
+ withContext(Dispatchers.Main) {
+ Toast.makeText(context, "请求失败: ${e.message}", Toast.LENGTH_SHORT).show()
+ }
+ }
}
- recyclerRecordView.adapter = recordadapter
}
- private fun loadData() {
- data.clear()
- data.addAll(
- listOf(
- InvitationRecord("H****e", "获得了1天会员","已注册"),
- InvitationRecord("U****r", "获得了2天会员","已注册"),
- InvitationRecord("A****e", "获得了免广告特权","已注册"),
- InvitationRecord("B****e", "获得了3天会员","已注册"),
- InvitationRecord("C****o", "获得了4天会员","已注册")
- )
- )
- adapter.notifyDataSetChanged()
+ private fun showImagePreviewDialog() {
+ val dialog = Dialog(this, android.R.style.Theme_Translucent_NoTitleBar).apply {
+ // 设置全屏+透明背景
+ window?.apply {
+ setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
+ setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ }
+
+ setContentView(R.layout.dialog_image_preview)
+ setCancelable(true) // 点击空白处可关闭
+
+ val imageView = findViewById<ImageView>(R.id.ivPreview)
+
+ // 长按分享(不关闭对话框)
+ imageView.setOnLongClickListener {
+ shareImageToWechat()
+ true
+ }
+
+ // 点击图片关闭(可选)
+ imageView.setOnClickListener {
+ dismiss()
+ }
+ }
+
+ dialog.show()
}
- private fun loadRecordData() {
- recorddata.clear()
- recorddata.addAll(
- listOf(
- InvitationRecord("M****e", "","未注册"),
- InvitationRecord("Q****r", "","已注册"),
- InvitationRecord("W****e", "","未注册"),
- InvitationRecord("E****e", "","未注册"),
- InvitationRecord("R****o", "","已注册")
+
+ // 分享资源图片到微信
+ private fun shareImageToWechat() {
+ try {
+ // 1. 将 drawable 图片保存到缓存目录
+ val drawable = ContextCompat.getDrawable(this, R.drawable.invite)!!
+ val bitmap = (drawable as BitmapDrawable).bitmap
+
+ // 2. 创建临时图片文件
+ val cacheDir = File(cacheDir, "shared_images").apply { mkdirs() }
+ val imageFile = File(cacheDir, "invite.jpg") // 指定文件名
+ FileOutputStream(imageFile).use { out ->
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)
+ }
+
+ // 3. 使用 FileProvider 获取 URI
+ val imageUri = FileProvider.getUriForFile(
+ this,
+ "${packageName}.fileprovider",
+ imageFile
)
- )
- recordadapter.notifyDataSetChanged()
+
+ // 4. 创建分享 Intent
+ val intent = Intent().apply {
+ action = Intent.ACTION_SEND
+ type = "image/jpeg"
+ putExtra(Intent.EXTRA_STREAM, imageUri)
+ flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
+ setPackage("com.tencent.mm") // 指定微信包名
+ }
+
+ // 5. 启动分享选择器
+ val chooserIntent = Intent.createChooser(intent, "分享邀请图片")
+ if (intent.resolveActivity(packageManager) != null) {
+ startActivity(chooserIntent)
+ } else {
+ Toast.makeText(this, "未找到可分享的应用", Toast.LENGTH_SHORT).show()
+ }
+ } catch (e: Exception) {
+ Toast.makeText(this, "分享失败: ${e.message}", Toast.LENGTH_SHORT).show()
+ }
+ }
+
+ private fun formatInvitationCode(code: String): String {
+ return if (code.length > 1) {
+ code.chunked(1).joinToString(" ")
+ } else {
+ code
+ }
}
private val scrollRunnable = object : Runnable {
@@ -217,7 +323,6 @@
// 使用取模运算确保位置在有效范围内
currentScrollPosition++
- currentRecordScrollPosition++
// 创建自定义平滑滚动器
val smoothScroller = object : LinearSmoothScroller(this@InvitationActivity) {
@@ -242,32 +347,9 @@
targetPosition = currentScrollPosition
}
- val smoothRecordScroller = object : LinearSmoothScroller(this@InvitationActivity) {
- override fun getVerticalSnapPreference(): Int = SNAP_TO_START
-
- override fun calculateDyToMakeVisible(view: View, snapPreference: Int): Int {
- // 计算需要滚动的距离,确保完整显示下一个item
- val top = view.top
- val height = view.height
- return when {
- snapPreference == SNAP_TO_START -> -top
- snapPreference == SNAP_TO_END -> -(top - (recyclerRecordView.height - height))
- else -> -(top - (recyclerRecordView.height / 2 - height / 2))
- }
- }
-
- override fun calculateTimeForScrolling(dx: Int): Int {
- // 根据滚动距离动态计算时间,保持匀速
- return maxOf((500f * abs(dx) / itemHeight).toInt(), 200)
- }
- }.apply {
- targetPosition = currentRecordScrollPosition
- }
// 启动平滑滚动
recyclerSuccessView.layoutManager?.startSmoothScroll(smoothScroller)
-
- recyclerRecordView.layoutManager?.startSmoothScroll(smoothRecordScroller)
// 更智能的边界检测
(recyclerSuccessView.layoutManager as? LinearLayoutManager)?.let { lm ->
@@ -282,25 +364,10 @@
}
}
- (recyclerRecordView.layoutManager as? LinearLayoutManager)?.let { lm ->
- val lastVisible = lm.findLastVisibleItemPosition()
- val totalItems = recordadapter.itemCount
-
- // 当接近"虚拟列表"末尾时,跳转到中间位置
- if (lastVisible >= totalItems - 3) {
- val jumpPosition = (totalItems / 2) * (Int.MAX_VALUE / totalItems)
- currentRecordScrollPosition = jumpPosition
- recyclerRecordView.scrollToPosition(jumpPosition)
- }
- }
-
handler.postDelayed(this, scrollInterval)
}
}
- private fun pxToDp(px: Int, context: Context): Int {
- return (px / (context.resources.displayMetrics.density)).toInt()
- }
private fun dpToPx(dp: Float): Int {
return (dp * resources.displayMetrics.density).toInt()
}
--
Gitblit v1.9.3