生成二维码
This commit is contained in:
@@ -25,6 +25,9 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.DefenseApplication">
|
android:theme="@style/Theme.DefenseApplication">
|
||||||
|
<activity
|
||||||
|
android:name=".personal.InvitationCodeActivity"
|
||||||
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".liveVideo.StrikePositionActivity"
|
android:name=".liveVideo.StrikePositionActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ data class LinkedUser(
|
|||||||
)
|
)
|
||||||
|
|
||||||
class LinkedUserAdapter(
|
class LinkedUserAdapter(
|
||||||
|
private val deleteText: String,
|
||||||
private val onItemClick: (LinkedUser, Int) -> Unit,
|
private val onItemClick: (LinkedUser, Int) -> Unit,
|
||||||
private val onDeleteClick: (LinkedUser, Int) -> Unit
|
private val onDeleteClick: (LinkedUser, Int) -> Unit
|
||||||
) : RecyclerView.Adapter<LinkedUserAdapter.LinkedUserViewHolder>() {
|
) : RecyclerView.Adapter<LinkedUserAdapter.LinkedUserViewHolder>() {
|
||||||
@@ -43,6 +44,7 @@ class LinkedUserAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: LinkedUserViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: LinkedUserViewHolder, position: Int) {
|
||||||
|
|
||||||
holder.bind(items[position], position)
|
holder.bind(items[position], position)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +60,8 @@ class LinkedUserAdapter(
|
|||||||
binding.tvPhone.text = "手机号码:${item.phone}"
|
binding.tvPhone.text = "手机号码:${item.phone}"
|
||||||
binding.tvIdCard.text = "身份证号:${item.idCard}"
|
binding.tvIdCard.text = "身份证号:${item.idCard}"
|
||||||
binding.tvTime.text = item.time
|
binding.tvTime.text = item.time
|
||||||
|
//设置删除按钮的文字
|
||||||
|
binding.tvDeleteAction.text = deleteText
|
||||||
binding.llContent.setOnClickListener {
|
binding.llContent.setOnClickListener {
|
||||||
onItemClick(item, position)
|
onItemClick(item, position)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,10 +50,13 @@ class PersonalFragment : Fragment() {
|
|||||||
binding.itemSwitchFamily.setOnClickListener {
|
binding.itemSwitchFamily.setOnClickListener {
|
||||||
showFamilySwitchDialog()
|
showFamilySwitchDialog()
|
||||||
}
|
}
|
||||||
|
//用户管理点击事件跳转关联用户页面
|
||||||
binding.itemUserManage.setOnClickListener {
|
binding.itemUserManage.setOnClickListener {
|
||||||
val intent = Intent(requireContext(), LinkedUserActivity::class.java)
|
val intent = Intent(requireContext(), LinkedUserActivity::class.java)
|
||||||
|
intent.putExtra(LinkedUserActivity.EXTRA_MODE, LinkedUserActivity.MODE_PERSONAL)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
// 密码管理点击事件
|
||||||
binding.itemPwdManage.setOnClickListener {
|
binding.itemPwdManage.setOnClickListener {
|
||||||
val intent= Intent(requireContext(), PasswordManagementActivity::class.java)
|
val intent= Intent(requireContext(), PasswordManagementActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.example.defenseapplication.liveVideo
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
@@ -18,10 +19,14 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
private lateinit var binding: LinkedUserActivityBinding
|
private lateinit var binding: LinkedUserActivityBinding
|
||||||
private lateinit var adapter: LinkedUserAdapter
|
private lateinit var adapter: LinkedUserAdapter
|
||||||
private val userList = mutableListOf<LinkedUser>()
|
private val userList = mutableListOf<LinkedUser>()
|
||||||
|
private var mode: Int = MODE_SETTINGS
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val REQUEST_CODE_SEARCH = 1001
|
const val REQUEST_CODE_SEARCH = 1001
|
||||||
const val EXTRA_SEARCH_RESULT = "search_result"
|
const val EXTRA_SEARCH_RESULT = "search_result"
|
||||||
|
const val EXTRA_MODE = "extra_mode"
|
||||||
|
const val MODE_SETTINGS = 0
|
||||||
|
const val MODE_PERSONAL = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@@ -29,6 +34,8 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
binding = LinkedUserActivityBinding.inflate(layoutInflater)
|
binding = LinkedUserActivityBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
mode = intent.getIntExtra(EXTRA_MODE, MODE_SETTINGS)
|
||||||
|
|
||||||
ImmersionBar.with(this)
|
ImmersionBar.with(this)
|
||||||
.statusBarDarkFont(true)
|
.statusBarDarkFont(true)
|
||||||
.titleBar(binding.topBar)
|
.titleBar(binding.topBar)
|
||||||
@@ -37,10 +44,13 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
initView()
|
initView()
|
||||||
initData()
|
initData()
|
||||||
initListener()
|
initListener()
|
||||||
|
setupModeUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initView() {
|
private fun initView() {
|
||||||
|
val deleteText = if (mode == MODE_SETTINGS) getString(R.string.unlink) else getString(R.string.delete)
|
||||||
adapter = LinkedUserAdapter(
|
adapter = LinkedUserAdapter(
|
||||||
|
deleteText = deleteText,
|
||||||
onItemClick = { user, position ->
|
onItemClick = { user, position ->
|
||||||
val intent = Intent(this, UserDetailsActivity::class.java).apply {
|
val intent = Intent(this, UserDetailsActivity::class.java).apply {
|
||||||
putExtra("name", user.name)
|
putExtra("name", user.name)
|
||||||
@@ -131,11 +141,16 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
currentSwipeHeld = true
|
currentSwipeHeld = true
|
||||||
|
|
||||||
val dialog = CustomDialogFragmentText()
|
val dialog = CustomDialogFragmentText()
|
||||||
dialog.setTitle("解除关联")
|
if (mode == MODE_SETTINGS) {
|
||||||
dialog.setMessage("确定要解除与 ${user.name} 的关联吗?")
|
dialog.setTitle(getString(R.string.tip))
|
||||||
|
dialog.setMessage(getString(R.string.unlink_confirm_message))
|
||||||
|
} else {
|
||||||
|
dialog.setTitle(getString(R.string.tip))
|
||||||
|
dialog.setMessage(getString(R.string.confirm_delete_user))
|
||||||
|
}
|
||||||
dialog.setShowInput(false)
|
dialog.setShowInput(false)
|
||||||
dialog.setPositiveText("确定")
|
dialog.setPositiveText(getString(R.string.confirm))
|
||||||
dialog.setNegativeText("取消")
|
dialog.setNegativeText(getString(R.string.cancel))
|
||||||
dialog.setOnConfirmListener {
|
dialog.setOnConfirmListener {
|
||||||
userList.removeAt(position)
|
userList.removeAt(position)
|
||||||
adapter.removeItem(position)
|
adapter.removeItem(position)
|
||||||
@@ -185,6 +200,21 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
val intent = Intent(this, AddLinkedUserActivity::class.java)
|
val intent = Intent(this, AddLinkedUserActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.fabAdd.setOnClickListener {
|
||||||
|
val intent = Intent(this, com.example.defenseapplication.personal.InvitationCodeActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupModeUI() {
|
||||||
|
if (mode == MODE_SETTINGS) {
|
||||||
|
binding.btnAddLinkedUser.visibility = View.VISIBLE
|
||||||
|
binding.fabAdd.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
binding.btnAddLinkedUser.visibility = View.GONE
|
||||||
|
binding.fabAdd.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
|
|||||||
@@ -74,8 +74,10 @@ class SettingsActivity : BaseActivity() {
|
|||||||
val intent = Intent(this, DeviceInfoActivity::class.java)
|
val intent = Intent(this, DeviceInfoActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
// 关联用户
|
||||||
binding.itemRelatedUsers.setOnClickListener {
|
binding.itemRelatedUsers.setOnClickListener {
|
||||||
val intent = Intent(this, LinkedUserActivity::class.java)
|
val intent = Intent(this, LinkedUserActivity::class.java)
|
||||||
|
intent.putExtra(LinkedUserActivity.EXTRA_MODE, LinkedUserActivity.MODE_SETTINGS)
|
||||||
startActivity( intent)
|
startActivity( intent)
|
||||||
}
|
}
|
||||||
binding.itemWifiManage.setOnClickListener {
|
binding.itemWifiManage.setOnClickListener {
|
||||||
|
|||||||
@@ -0,0 +1,191 @@
|
|||||||
|
package com.example.defenseapplication.personal
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.Paint
|
||||||
|
import android.os.Bundle
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.RadioButton
|
||||||
|
import android.widget.RadioGroup
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.example.defenseapplication.R
|
||||||
|
import com.example.defenseapplication.databinding.DialogExpireTimeBinding
|
||||||
|
import com.example.defenseapplication.databinding.InvitationCodeActivityBinding
|
||||||
|
import com.google.zxing.BarcodeFormat
|
||||||
|
import com.google.zxing.EncodeHintType
|
||||||
|
import com.google.zxing.qrcode.QRCodeWriter
|
||||||
|
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
|
||||||
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
import java.util.Hashtable
|
||||||
|
|
||||||
|
//邀请码页面
|
||||||
|
class InvitationCodeActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var binding: InvitationCodeActivityBinding
|
||||||
|
private var expireTimeInMillis: Long = 24 * 60 * 60 * 1000 // 默认24小时
|
||||||
|
private var selectedExpireOption: Int = 0 // 0: 24h, 1: 7d,默认选中24h
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val EXPIRE_24H = 24 * 60 * 60 * 1000L
|
||||||
|
const val EXPIRE_7D = 7 * 24 * 60 * 60 * 1000L
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
binding = InvitationCodeActivityBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
ImmersionBar.with(this)
|
||||||
|
.statusBarDarkFont(true)
|
||||||
|
.titleBar(binding.topBar)
|
||||||
|
.init()
|
||||||
|
|
||||||
|
initListener()
|
||||||
|
// 默认显示时效为24h
|
||||||
|
binding.tvExpireTime.text = getString(R.string.expire_24h)
|
||||||
|
// 默认显示灰色占位区域,二维码不可见
|
||||||
|
hideQrCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initListener() {
|
||||||
|
binding.ivBack.setOnClickListener {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.llExpireTime.setOnClickListener {
|
||||||
|
showExpireTimeDialog()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.llWechatShare.setOnClickListener {
|
||||||
|
// 微信分享功能
|
||||||
|
shareToWeChat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showExpireTimeDialog() {
|
||||||
|
val dialogBinding = DialogExpireTimeBinding.inflate(LayoutInflater.from(this))
|
||||||
|
|
||||||
|
val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
|
||||||
|
dialog.setContentView(dialogBinding.root)
|
||||||
|
|
||||||
|
// 设置选中状态
|
||||||
|
when (selectedExpireOption) {
|
||||||
|
0 -> dialogBinding.rb24h.isChecked = true
|
||||||
|
1 -> dialogBinding.rb7d.isChecked = true
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogBinding.radioGroup.setOnCheckedChangeListener { _, checkedId ->
|
||||||
|
when (checkedId) {
|
||||||
|
R.id.rb24h -> selectedExpireOption = 0
|
||||||
|
R.id.rb7d -> selectedExpireOption = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogBinding.tvCancel.setOnClickListener {
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogBinding.tvConfirm.setOnClickListener {
|
||||||
|
when (selectedExpireOption) {
|
||||||
|
0 -> {
|
||||||
|
expireTimeInMillis = EXPIRE_24H
|
||||||
|
binding.tvExpireTime.text = getString(R.string.expire_24h)
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
expireTimeInMillis = EXPIRE_7D
|
||||||
|
binding.tvExpireTime.text = getString(R.string.expire_7d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 选择后显示二维码并生成
|
||||||
|
showQrCode()
|
||||||
|
generateQRCode()
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hideQrCode() {
|
||||||
|
// 隐藏二维码,显示灰色占位区域
|
||||||
|
binding.ivQrCode.visibility = View.GONE
|
||||||
|
binding.ivQrLogo.visibility = View.GONE
|
||||||
|
binding.vQrPlaceholder.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showQrCode() {
|
||||||
|
// 显示二维码,隐藏灰色占位区域
|
||||||
|
binding.vQrPlaceholder.visibility = View.GONE
|
||||||
|
binding.ivQrCode.visibility = View.VISIBLE
|
||||||
|
binding.ivQrLogo.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateQRCode() {
|
||||||
|
val content = generateInviteCode()
|
||||||
|
val qrBitmap = createQRCodeWithLogo(content, 400, 400)
|
||||||
|
binding.ivQrCode.setImageBitmap(qrBitmap)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateInviteCode(): String {
|
||||||
|
// 生成包含邀请信息的JSON字符串
|
||||||
|
val timestamp = System.currentTimeMillis()
|
||||||
|
val expireTime = timestamp + expireTimeInMillis
|
||||||
|
return "{\"type\":\"invite\",\"code\":\"INV${timestamp}\",\"expire\":$expireTime}"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createQRCodeWithLogo(content: String, width: Int, height: Int): Bitmap? {
|
||||||
|
return try {
|
||||||
|
val hints = Hashtable<EncodeHintType, Any>()
|
||||||
|
hints[EncodeHintType.CHARACTER_SET] = "UTF-8"
|
||||||
|
hints[EncodeHintType.ERROR_CORRECTION] = ErrorCorrectionLevel.H
|
||||||
|
|
||||||
|
val writer = QRCodeWriter()
|
||||||
|
val bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints)
|
||||||
|
|
||||||
|
val qrBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||||
|
val canvas = Canvas(qrBitmap)
|
||||||
|
|
||||||
|
// 绘制白色背景
|
||||||
|
canvas.drawColor(Color.WHITE)
|
||||||
|
|
||||||
|
// 绘制二维码
|
||||||
|
val paint = Paint(Paint.ANTI_ALIAS_FLAG)
|
||||||
|
paint.color = Color.BLACK
|
||||||
|
|
||||||
|
val cellWidth = width.toFloat() / bitMatrix.width
|
||||||
|
val cellHeight = height.toFloat() / bitMatrix.height
|
||||||
|
|
||||||
|
for (x in 0 until bitMatrix.width) {
|
||||||
|
for (y in 0 until bitMatrix.height) {
|
||||||
|
if (bitMatrix.get(x, y)) {
|
||||||
|
canvas.drawRect(
|
||||||
|
x * cellWidth,
|
||||||
|
y * cellHeight,
|
||||||
|
(x + 1) * cellWidth,
|
||||||
|
(y + 1) * cellHeight,
|
||||||
|
paint
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qrBitmap
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun shareToWeChat() {
|
||||||
|
// 微信分享实现
|
||||||
|
// 这里需要集成微信SDK
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,7 +47,7 @@ class FamilySwitchDialog(
|
|||||||
|
|
||||||
val familyList = listOf(
|
val familyList = listOf(
|
||||||
FamilyItem("1", context.getString(R.string.my_family)),
|
FamilyItem("1", context.getString(R.string.my_family)),
|
||||||
FamilyItem("2", context.getString(R.string.zhangsan_family))
|
FamilyItem("2", "张三的家庭")
|
||||||
)
|
)
|
||||||
|
|
||||||
adapter = FamilySwitchAdapter(familyList) { familyItem ->
|
adapter = FamilySwitchAdapter(familyList) { familyItem ->
|
||||||
|
|||||||
BIN
app/src/main/res/drawable/add_img.png
Normal file
BIN
app/src/main/res/drawable/add_img.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
21
app/src/main/res/drawable/bg_radio_button_selector.xml
Normal file
21
app/src/main/res/drawable/bg_radio_button_selector.xml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_checked="true">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="@color/bg_gray" />
|
||||||
|
<corners android:radius="8dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item android:state_pressed="true">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="@color/bg_gray" />
|
||||||
|
<corners android:radius="8dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="@color/white" />
|
||||||
|
<corners android:radius="8dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
6
app/src/main/res/drawable/bg_white_rounded.xml
Normal file
6
app/src/main/res/drawable/bg_white_rounded.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="@color/white" />
|
||||||
|
<corners android:radius="8dp" />
|
||||||
|
</shape>
|
||||||
BIN
app/src/main/res/drawable/logo.png
Normal file
BIN
app/src/main/res/drawable/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
5
app/src/main/res/drawable/text_color_selector.xml
Normal file
5
app/src/main/res/drawable/text_color_selector.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_checked="true" android:color="@color/black" />
|
||||||
|
<item android:color="@color/black" />
|
||||||
|
</selector>
|
||||||
BIN
app/src/main/res/drawable/vx.png
Normal file
BIN
app/src/main/res/drawable/vx.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
72
app/src/main/res/layout/dialog_expire_time.xml
Normal file
72
app/src/main/res/layout/dialog_expire_time.xml
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/white"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<!-- 标题栏 -->
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvCancel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:text="@string/cancel"
|
||||||
|
android:textColor="@color/gray"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvConfirm"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:text="@string/confirm"
|
||||||
|
android:textColor="@color/green"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<!-- 选项列表 -->
|
||||||
|
<RadioGroup
|
||||||
|
android:id="@+id/radioGroup"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb24h"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:background="@drawable/bg_radio_button_selector"
|
||||||
|
android:button="@null"
|
||||||
|
android:checked="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/expire_24h"
|
||||||
|
android:textColor="@drawable/text_color_selector"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb7d"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="@drawable/bg_radio_button_selector"
|
||||||
|
android:button="@null"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/expire_7d"
|
||||||
|
android:textColor="@drawable/text_color_selector"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true" />
|
||||||
|
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
172
app/src/main/res/layout/invitation_code_activity.xml
Normal file
172
app/src/main/res/layout/invitation_code_activity.xml
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
<?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:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@color/bg_gray"
|
||||||
|
tools:context=".personal.InvitationCodeActivity">
|
||||||
|
|
||||||
|
<!-- 标题栏 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/topBar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingHorizontal="16dp"
|
||||||
|
android:background="@color/white">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivBack"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@drawable/back" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/invite_code"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- 邀请码时效选择 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/llExpireTime"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="@color/white"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingHorizontal="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/invite_code_expire_time"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvExpireTime"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text=""
|
||||||
|
android:textColor="@color/gray"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:src="@drawable/right_back" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- 二维码卡片 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/llQrCodeCard"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:background="@drawable/bg_white_rounded"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="24dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:text="@string/qr_code_invite"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<!-- 二维码图片 -->
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="24dp">
|
||||||
|
|
||||||
|
<!-- 灰色占位背景 -->
|
||||||
|
<View
|
||||||
|
android:id="@+id/vQrPlaceholder"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/bg_gray" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivQrCode"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="fitCenter" />
|
||||||
|
|
||||||
|
<!-- 中间Logo -->
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivQrLogo"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@mipmap/loge" />
|
||||||
|
</FrameLayout>
|
||||||
|
<!-- 说明文字 -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvTips"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/invite_code_tips"
|
||||||
|
android:textColor="@color/gray"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:lineSpacingMultiplier="1.2" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- 其他邀请方式 -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:text="@string/other_invite_methods"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<!-- 微信好友 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/llWechatShare"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="@color/white"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingHorizontal="16dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="43dp"
|
||||||
|
android:layout_height="43dp"
|
||||||
|
android:src="@drawable/vx" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/wechat_friend"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@drawable/right_back" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/tvDeleteAction"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/unlink"
|
android:text="@string/unlink"
|
||||||
|
|||||||
@@ -66,7 +66,6 @@
|
|||||||
android:textSize="14sp"/>
|
android:textSize="14sp"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<!-- 列表区域 -->
|
<!-- 列表区域 -->
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/rvLinkedUser"
|
android:id="@+id/rvLinkedUser"
|
||||||
@@ -79,6 +78,7 @@
|
|||||||
|
|
||||||
<!-- 底部按钮 -->
|
<!-- 底部按钮 -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingHorizontal="16dp"
|
android:paddingHorizontal="16dp"
|
||||||
@@ -92,6 +92,16 @@
|
|||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="14dp"
|
android:textSize="14dp"
|
||||||
android:background="@drawable/rounded_blue_bg" />
|
android:background="@drawable/rounded_blue_bg" />
|
||||||
|
<!-- 悬浮加号按钮 -->
|
||||||
|
<ImageView
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:src="@drawable/add_img"
|
||||||
|
android:id="@+id/fabAdd"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="40dp"
|
android:layout_height="40dp"
|
||||||
android:layout_margin="16dp"
|
android:layout_margin="16dp"
|
||||||
android:layout_marginBottom="20dp"
|
android:layout_marginBottom="40dp"
|
||||||
android:background="@drawable/rounded_blue_bg"
|
android:background="@drawable/rounded_blue_bg"
|
||||||
android:text="@string/submit"
|
android:text="@string/submit"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
|
|||||||
@@ -398,4 +398,16 @@
|
|||||||
<string name="password_error">密码错误</string>
|
<string name="password_error">密码错误</string>
|
||||||
<string name="operation_password_not_set">未设置操作密码</string>
|
<string name="operation_password_not_set">未设置操作密码</string>
|
||||||
<string name="confirm_reset_password_btn">确认重置</string>
|
<string name="confirm_reset_password_btn">确认重置</string>
|
||||||
|
<string name="user_status">用户状态</string>
|
||||||
|
<string name="contact_name">联系人姓名</string>
|
||||||
|
<string name="id_card">身份证号</string>
|
||||||
|
<string name="mac_address">MAC地址</string>
|
||||||
|
<string name="invite_code">邀请码</string>
|
||||||
|
<string name="invite_code_expire_time">邀请码有效期</string>
|
||||||
|
<string name="qr_code_invite">二维码邀请</string>
|
||||||
|
<string name="invite_code_tips">邀请二维码24小时内有效,仅可接受一次;手动撤销或重新生成将使原邀请二维码失效</string>
|
||||||
|
<string name="other_invite_methods">其他邀请方式</string>
|
||||||
|
<string name="wechat_friend">微信好友</string>
|
||||||
|
<string name="expire_24h">24小时</string>
|
||||||
|
<string name="expire_7d">7天</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -103,8 +103,6 @@
|
|||||||
<string name="add_user">Add User</string>
|
<string name="add_user">Add User</string>
|
||||||
<string name="admin">Admin</string>
|
<string name="admin">Admin</string>
|
||||||
<string name="member">Member</string>
|
<string name="member">Member</string>
|
||||||
<string name="normal_member">Ordinary Member</string>
|
|
||||||
<string name="zhangsan_family">Zhang San Family</string>
|
|
||||||
<string name="phone_number">Phone Number</string>
|
<string name="phone_number">Phone Number</string>
|
||||||
<string name="enter_nickname">Enter nickname</string>
|
<string name="enter_nickname">Enter nickname</string>
|
||||||
|
|
||||||
@@ -244,10 +242,6 @@
|
|||||||
|
|
||||||
<!-- Additional missing strings -->
|
<!-- Additional missing strings -->
|
||||||
<string name="scan_device_qr">Please scan the QR code on the device or manual</string>
|
<string name="scan_device_qr">Please scan the QR code on the device or manual</string>
|
||||||
<string name="user_status">用户状态</string>
|
|
||||||
<string name="contact_name">联系人姓名</string>
|
|
||||||
<string name="id_card">身份证号</string>
|
|
||||||
<string name="mac_address">MAC地址</string>
|
|
||||||
<string name="workshop">Workshop</string>
|
<string name="workshop">Workshop</string>
|
||||||
<string name="parents_home">Parents Home</string>
|
<string name="parents_home">Parents Home</string>
|
||||||
<string name="smart_hanging_defense">Smart Hanging Defense</string>
|
<string name="smart_hanging_defense">Smart Hanging Defense</string>
|
||||||
@@ -408,4 +402,16 @@
|
|||||||
<string name="hint_new_password_zh">Please enter new password</string>
|
<string name="hint_new_password_zh">Please enter new password</string>
|
||||||
<string name="hint_confirm_password_zh">Please re-enter new password</string>
|
<string name="hint_confirm_password_zh">Please re-enter new password</string>
|
||||||
<string name="confirm_reset_password_btn">Confirm Reset</string>
|
<string name="confirm_reset_password_btn">Confirm Reset</string>
|
||||||
|
<string name="user_status">User Status</string>
|
||||||
|
<string name="contact_name">Contact Name</string>
|
||||||
|
<string name="id_card">ID Card Number</string>
|
||||||
|
<string name="mac_address">MAC Address</string>
|
||||||
|
<string name="invite_code">Invite Code</string>
|
||||||
|
<string name="invite_code_expire_time">Invite Code Expiry</string>
|
||||||
|
<string name="qr_code_invite">QR Code Scan Invite</string>
|
||||||
|
<string name="invite_code_tips">Invite QR code is valid for 24 hours; can only be accepted once; manual revocation or regenerating will invalidate the previous invite QR code</string>
|
||||||
|
<string name="other_invite_methods">Other Invite Methods</string>
|
||||||
|
<string name="wechat_friend">WeChat Friend</string>
|
||||||
|
<string name="expire_24h">24h</string>
|
||||||
|
<string name="expire_7d">7d</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -19,4 +19,11 @@
|
|||||||
<item name="android:windowEnterAnimation">@anim/slide_up</item>
|
<item name="android:windowEnterAnimation">@anim/slide_up</item>
|
||||||
<item name="android:windowExitAnimation">@anim/slide_down</item>
|
<item name="android:windowExitAnimation">@anim/slide_down</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="BottomSheetDialog" parent="Theme.Material3.DayNight.BottomSheetDialog">
|
||||||
|
<item name="android:windowIsFloating">false</item>
|
||||||
|
<item name="android:windowBackground">@android:color/transparent</item>
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
<item name="android:navigationBarColor">@color/white</item>
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user