第四十五回:Checkbox Widget

文章介绍了Flutter中的CheckboxWidget,包括其概念、使用方法和示例代码。Checkbox是用来表示是否选中的组件,可以通过属性如checkColor、activeColor、shape和side来定制样式,并使用onChanged方法处理用户交互。示例代码展示了如何创建和控制Checkbox的状态。


我们在上一章回中介绍了DatePickerDialog Widget相关的内容,本章回中将介绍 Checkbox Widget.闲话休提,让我们一起Talk Flutter吧。

概念介绍

我们在这里说的Checkbox也是叫复选框,没有选中时是一个正方形边框,边框内容是空白的,选中时会在边框中显示一个白色对号,对号周围用深色来填充。它主要用来表示某项内容是否被选中,而且可以同时选中多项内容。

Flutter把复选框封装成了独立的组件,使用Checkbox类来表示该组件,本章回中将详细介绍它的使用的方法。

使用方法

和其它Widget一样,Chexkbox组件也提供了相关的属性来操作自己,下面是一些常用的属性,掌握这些属性的用法后就可以熟练地使用Checkbox组件了:

  • checkColor属性:用来控制被选中后对号的颜色,默认是白色;
  • activeColor属性:用来控制被选中后对号周围的填充颜色,默认是蓝色;
  • shape属性:用来控制没有选中时边框的形状,默认是正方形;
  • side属性:用来制没有选中时边框的颜色和粗细,默认是灰色;
  • value属性:它是一个布尔类型的值,用来控制复选框是否被选中;
  • onChanged属性:它是方法类型,点击复选框时会回此方法,此方法的参数值和value属性值相同;

最后有些注意事项需要单独说明:

  • 可以在shape属性中设置边框粗细和颜色,但是没有效果,需要配置side属性才能修改边框粗细和颜色;
  • value属性为true时表示复选框被选中,此时会在方框中显示一个对号,反之表示复选框没有被选中,不会显示对号。
  • value属性和onChanged属性经常配合使用,在onChanged方法中修改value的属性值,这样来实现点击时选中复选框,再点击时释放被选中的复选框,如果看官们不理解的话,可以看下面的示例代码:

示例代码

child: Checkbox(
  //是否选中的状态
  value: _checkState,
  //对号周围的颜色,默认是蓝色
  activeColor: Colors.deepPurpleAccent,
  //对号的颜色,默认是白色
  checkColor: Colors.amber,
  hoverColor: Colors.greenAccent,
  //shape只能修改形状,边框粗细和颜色没有效果,需要配置side属性才能修改边框粗细颜色
  shape: const CircleBorder(
    side: BorderSide(
      color: Colors.greenAccent,
      width: 3,
    ),
  ),
  side: const BorderSide(
    color: Colors.greenAccent,
    width: 2,
  ),
  //选择时的回调方法,通过修改状态值来切换选中/未选中状态
  onChanged: (value) {
    setState(() {
      if (_checkState) {
        _checkState = false;
      } else {
        _checkState = true;
      }
    });
  },
),

上面的代码只是核心代码,完整的代码可以查看Github中ex022文件中的内容。

编译并且运行上面的程序,会看到一个绿色的圆形边框,表示复选框没有被选中,点击此边框后在边框中出现一个黄色的对号,对号周围用紫色填充,表示复选框被选中。我在这里就不演示程序的运行结果了,建议大家自己动手去实践。

看官们,关于Checkbox Widget的内容就介绍到这里,欢迎大家在评论区交流与讨论!

FATAL EXCEPTION: main Process: com.example.emptytapo, PID: 31664 kotlin.UninitializedPropertyAccessException: lateinit property confirmButton has not been initialized at PP_ToUFragment.onViewCreated(PP_ToUFragment.kt:45):import android.graphics.Color import android.graphics.Typeface import android.os.Bundle import android.text.Spannable import android.text.SpannableString import android.text.method.LinkMovementMethod import android.text.style.ClickableSpan import android.text.style.StyleSpan import android.text.style.UnderlineSpan import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button import android.widget.CheckBox import android.widget.TextView import androidx.fragment.app.Fragment import com.example.emptytapo.PassWordFragment import com.example.emptytapo.R import com.example.tapologin.PrivacyPolicyFragment import com.example.tapologin.TermsofUseFragment import com.example.tapologin.UserExperienceImprovProgramFragment class PP_ToUFragment : Fragment() { private lateinit var checkBox1: CheckBox private lateinit var checkBox2: CheckBox private lateinit var confirmButton: Button override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.login, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 初始化控件 checkBox1 = view.findViewById(R.id.checkbox1) checkBox2 = view.findViewById(R.id.checkbox2) confirmButton = view.findViewById(R.id.btn_agree) confirmButton.setTextColor(Color.parseColor("#A7A9AC")) // 更新按钮状态的闭包 val updateButtonState: () -> Unit = { val bothChecked = checkBox1.isChecked && checkBox2.isChecked if (bothChecked) { confirmButton.isEnabled = true confirmButton.setTextColor(Color.parseColor("#1BCBFF")) } else { confirmButton.isEnabled = false confirmButton.setTextColor(Color.parseColor("#A7A9AC")) } } // 设置监听器 checkBox1.setOnCheckedChangeListener { _, _ -> updateButtonState() } checkBox2.setOnCheckedChangeListener { _, _ -> updateButtonState() } // 点击事件 confirmButton.setOnClickListener { if (checkBox1.isChecked && checkBox2.isChecked) { Log.d("ConfirmButton", "发生点击") parentFragmentManager.beginTransaction() .replace(R.id.fragment_container, PassWordFragment()) .addToBackStack(null) .commit() } } // 设置 Privacy Policy 文本 val privacyText = view.findViewById<TextView>(R.id.PrivacyPolicy) val termsText = view.findViewById<TextView>(R.id.TermsofUse) // 设置 Privacy Policy 链接 val fullPrivacyText = "I have fully read and accepted the Privacy Policy and Terms of Use." val spannablePrivacy = SpannableString(fullPrivacyText) val privacyStart = fullPrivacyText.indexOf("Privacy Policy") val privacyEnd = privacyStart + "Privacy Policy".length spannablePrivacy.setSpan(StyleSpan(Typeface.NORMAL), privacyStart, privacyEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spannablePrivacy.setSpan(UnderlineSpan(), privacyStart, privacyEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spannablePrivacy.setSpan(object : ClickableSpan() { override fun onClick(widget: View) { parentFragmentManager.beginTransaction() .replace(R.id.fragment_container, PrivacyPolicyFragment()) .addToBackStack(null) .commit() } }, privacyStart, privacyEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) // 设置 Terms of Use 链接 val termsStart = fullPrivacyText.indexOf("Terms of Use") val termsEnd = termsStart + "Terms of Use".length spannablePrivacy.setSpan(StyleSpan(Typeface.NORMAL), termsStart, termsEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spannablePrivacy.setSpan(UnderlineSpan(), termsStart, termsEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spannablePrivacy.setSpan(object : ClickableSpan() { override fun onClick(widget: View) { parentFragmentManager.beginTransaction() .replace(R.id.fragment_container, TermsofUseFragment()) .addToBackStack(null) .commit() } }, termsStart, termsEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) privacyText.text = spannablePrivacy privacyText.movementMethod = LinkMovementMethod.getInstance() // 设置 User Experience 链接 val ueText = "I agree to join the User Experience Improvement Program." val spannableUE = SpannableString(ueText) val ueStart = ueText.indexOf("User Experience Improvement Program") val ueEnd = ueStart + "User Experience Improvement Program".length spannableUE.setSpan(object : ClickableSpan() { override fun onClick(widget: View) { parentFragmentManager.beginTransaction() .replace(R.id.fragment_container, UserExperienceImprovProgramFragment()) .addToBackStack(null) .commit() } }, ueStart, ueEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) termsText.text = spannableUE termsText.movementMethod = LinkMovementMethod.getInstance() } } 第45行为: confirmButton.setTextColor(Color.parseColor("#A7A9AC"))
最新发布
08-12
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

talk_8

真诚赞赏,手有余香

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值