Kotlin中Fragment内TextView点击展开/隐藏短信按钮实现
实现TextView点击展开/隐藏对应短信按钮的功能
一、布局结构优化
首先需要把每个TextView对应的按钮分组封装到一个容器(比如LinearLayout或ConstraintLayout)中,这样可以统一控制按钮组的显示/隐藏状态。初始状态下将按钮容器设为隐藏(android:visibility="gone")。
修改后的布局示例(以بخاری 2对应的按钮组为例):
<?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:layout_width="match_parent" android:layout_height="wrap_content" tools:context=".OrderFragment"> <!-- TextView:بخاری 2 --> <TextView android:id="@+id/bokhari2" android:layout_width="153dp" android:layout_height="56dp" android:layout_marginTop="36dp" android:text="بخاری 2" android:textSize="30sp" android:clickable="true" android:focusable="true" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.941" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <!-- 封装بخاری 2对应的所有按钮 --> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/bokhari2ButtonsContainer" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="gone" app:layout_constraintTop_toBottomOf="@+id/bokhari2"> <Button android:id="@+id/bokhari1On" android:layout_width="169dp" android:layout_height="52dp" android:layout_marginStart="15dp" android:layout_marginTop="10dp" android:layout_marginEnd="15dp" android:backgroundTint="#8BC34A" android:padding="5dp" android:text="دستی همه روشن" android:textAllCaps="false" android:textSize="20sp" app:layout_constraintEnd_toStartOf="@+id/bokhari2Reset" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/bkhari2Off" android:layout_width="169dp" android:layout_height="52dp" android:layout_marginStart="15dp" android:layout_marginTop="10dp" android:layout_marginEnd="15dp" android:text="دست همه خاموش " android:backgroundTint="#FF1100" android:textSize="17sp" app:layout_constraintEnd_toStartOf="@+id/bokhari2Auto" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/bokhari1On" /> <Button android:id="@+id/bokhari2Auto" android:layout_width="169dp" android:layout_height="52dp" android:layout_marginTop="10dp" android:layout_marginEnd="15dp" android:backgroundTint="#3F51B5" android:padding="5dp" android:text="اتوماتیک کردن" android:textAllCaps="false" android:textSize="20sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/bokhari2Reset" /> <Button android:id="@+id/bokhari2Reset" android:layout_width="169dp" android:layout_height="52dp" android:layout_marginTop="10dp" android:layout_marginEnd="15dp" android:backgroundTint="#FF9800" android:text="ریست نمودن" android:textAllCaps="false" android:textSize="20sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> <!-- 其他TextView和对应的按钮组可以按照同样的结构添加 --> </androidx.constraintlayout.widget.ConstraintLayout>
注意:给TextView添加android:clickable="true"和android:focusable="true"确保它能响应点击事件。
二、Fragment逻辑实现
在OrderFragment中,我们需要:
- 为每个TextView设置点击事件,切换对应按钮容器的可见性
- 提取短信发送的公共方法,避免重复代码
- 处理权限(发送短信需要
SEND_SMS权限)
修改后的Kotlin代码:
class OrderFragment : Fragment() { private lateinit var phoneNumberEt: EditText override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val view = inflater.inflate(R.layout.fragment_order, container, false) // 初始化控件 phoneNumberEt = view.findViewById(R.id.idEdtPhone) val bokhari2Tv = view.findViewById<TextView>(R.id.bokhari2) val bokhari2ButtonsContainer = view.findViewById<ConstraintLayout>(R.id.bokhari2ButtonsContainer) val bokhari2ResetBtn = view.findViewById<Button>(R.id.bokhari2Reset) val bokhari2AutoBtn = view.findViewById<Button>(R.id.bokhari2Auto) val bokhari1OnBtn = view.findViewById<Button>(R.id.bokhari1On) val bkhari2OffBtn = view.findViewById<Button>(R.id.bkhari2Off) // TextView点击事件:切换按钮组显示/隐藏 bokhari2Tv.setOnClickListener { bokhari2ButtonsContainer.isVisible = !bokhari2ButtonsContainer.isVisible } // 绑定按钮的短信发送逻辑 bokhari2ResetBtn.setOnClickListener { sendSms("#9903011", "send") } bokhari2AutoBtn.setOnClickListener { sendSms("#9903012", "بخاری 2 = اتوماتیک کردن") } bokhari1OnBtn.setOnClickListener { sendSms("#9903013", "دستی همه روشن") } bkhari2OffBtn.setOnClickListener { sendSms("#9903014", "دست همه خاموش") } return view } // 提取公共短信发送方法 private fun sendSms(message: String, successMsg: String) { val phoneNumber = phoneNumberEt.text.toString().trim() if (phoneNumber.isEmpty()) { Toast.makeText(context, "تلفن را صحیح وارد کنید", Toast.LENGTH_SHORT).show() return } try { val smsManager = SmsManager.getDefault() smsManager.sendTextMessage(phoneNumber, null, message, null, null) Toast.makeText(context, successMsg, Toast.LENGTH_SHORT).show() } catch (e: Exception) { Toast.makeText(context, "ارسال پیام با خطا مواجه شد", Toast.LENGTH_SHORT).show() e.printStackTrace() } } // 动态申请短信权限(Android 6.0+) override fun onStart() { super.onStart() if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED ) { ActivityCompat.requestPermissions( requireActivity(), arrayOf(Manifest.permission.SEND_SMS), 100 ) } } override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == 100) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(context, "اجازه ارسال پیام به دست آمد", Toast.LENGTH_SHORT).show() } else { Toast.makeText(context, "اجازه ارسال پیام نیاز است", Toast.LENGTH_SHORT).show() } } } }
关键说明
- 可见性切换:使用
isVisible属性可以简洁地切换控件的显示/隐藏状态(替代setVisibility) - 代码复用:将短信发送逻辑提取成
sendSms方法,减少重复代码,便于维护 - 权限处理:Android 6.0及以上需要动态申请
SEND_SMS权限,否则无法发送短信 - 多TextView扩展:如果有更多TextView和按钮组,只需重复“TextView + 按钮容器”的结构,并添加对应的点击事件即可
内容的提问来源于stack exchange,提问作者Ali Damiri
相关产品推荐
相关产品推荐

