【问题标题】:Change activity's button state from fragment从片段更改活动的按钮状态
【发布时间】:2021-11-06 14:00:48
【问题描述】:

这里有来自我的活动和片段的代码:

活动:

class Activity0: AppCompatActivity() {
   private lateinit var binding: Activity0Binding
   override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)                                    
      binding = Activity0Binding.inflate(layoutInflater)
      setContentView(binding.root)

      binding.popUpButton.setOnClickListener {
        supportFragmentManager.commit {
            replace(R.id.quiz_fragment_container, Activity0FragmentNull())
        }
        binding.popUpButton.isEnabled = false
      }
   }
}

片段:

class Activity0FragmentNull : Fragment() {
   ...
   override fun onCreateView(
     inflater: LayoutInflater, container: ViewGroup?,
     savedInstanceState: Bundle?
   ): View? {
       Activity0().popUpButton.isEnabled = true
       return inflater.inflate(R.layout.activity0_null, container, false)
   }
   ...
}

在这里,我尝试更改按钮的状态,以便在启动片段时启用。但是,每当我的片段运行时,应用程序就会崩溃并返回到主要活动(应用程序的开始)。为什么试图从我的片段中访问我的活动中的按钮会导致应用程序崩溃。感谢您的宝贵时间,感谢您提供任何帮助。

【问题讨论】:

    标签: android-studio kotlin android-fragments android-activity android-button


    【解决方案1】:

    我认为mightyWoz 的方法足以满足您的目的。

    但根据我的经验,这种事情经常出现,并且有一种方法可以即时处理它们。

    我通常的工作流程是让孩子(如警报对话框或片段)访问他们的父活动,如下所示。

    1. 在孩子内部,声明一个回调,然后在您知道会运行的地方调用它。它看起来像这样:
    class Activity0FragmentNull : Fragment() {
    
    var controllParentCallback:(()->Unit)?=null
       ...
    
       override fun onCreateView(
         inflater: LayoutInflater, container: ViewGroup?,
         savedInstanceState: Bundle?
       ): View? {
           controllParentCallback?.invoke()
    
           return inflater.inflate(R.layout.activity0_null, container, false)
       }
       ...
    
    

    现在在父活动中,为子活动命名,然后为其回调赋值。它看起来像这样:

    class Activity0: AppCompatActivity() {
       private lateinit var binding: Activity0Binding
       override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)                                    
          binding = Activity0Binding.inflate(layoutInflater)
          setContentView(binding.root)
          val childFragment=Activity0FragmentNull()
          childFragment.controllParentCallback={
    binding.popUpButton.isEnabled = true
    }
    
          binding.popUpButton.setOnClickListener {
            supportFragmentManager.commit {
                replace(R.id.quiz_fragment_container, Activity0FragmentNull())
            }
            binding.popUpButton.isEnabled = false
          }
       }
    }
    

    因此,即使创建一个接口很棒而且非常 Kotlinic,但在您创建子级而不知道以后需要访问父级的情况下,这样的小回调确实可以加快开发时间。

    【讨论】:

      【解决方案2】:

      您永远不会创建Activity 对象,这是操作系统的责任。所以永远不要这样做Activity0()。在片段中,您可以使用 activity 属性访问关联的 Activity。

      你的问题可以这样解决

      定义接口

      interface ButtonStateManager{
          fun setEnabled(enabled: Boolean)
      }
      

      让你的Activity实现这个接口

      class Activity0: AppCompatActivity(), ButtonStateManager {
          
          ...
      
          override fun setEnabled(enabled: Boolean) {
               binding.popUpButton.isEnabled = enabled
          }
      }
      

      现在您可以从Fragment as 启用/禁用按钮

      override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
           super.onViewCreated(view, savedInstanceState)
           /* cast the activity to ButtonStateManager and then call the function */
           (activity as? ButtonStateManager)?.setEnabled(true)  
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多