从片段更改 activity 的按钮状态

Change activity's button state from fragment

这里有我的 activity 和片段的代码:

Activity:

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)
   }
   ...
}

我在这里尝试更改我的按钮状态,以便在片段启动时启用。但是,每当我的片段是 运行 时,应用程序就会崩溃,并且 returns 到主 activity (应用程序开始)。为什么试图从我的片段到达我的 activity 中的按钮会导致应用程序崩溃。感谢您的宝贵时间,我们将不胜感激。

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

访问关联的 Activity

对于你的问题可以这样解决

定义接口

interface ButtonStateManager{
    fun setEnabled(enabled: Boolean)
}

让你的Activity实现这个接口

class Activity0: AppCompatActivity(), ButtonStateManager {
    
    ...

    override fun setEnabled(enabled: Boolean) {
         binding.popUpButton.isEnabled = enabled
    }
}

现在您可以 enable/disable 来自 Fragment 的按钮作为

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)  
}

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

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

我通常使用 child 像警报对话框或片段访问他们的 parent activity 的工作流程是这样的。

  1. 在 child 内,声明一个回调,然后在您知道会 运行 的地方调用它。它看起来像这样:
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)
   }
   ...

现在在 parent activity 中,为 child 命名,然后为其回调赋值。它看起来像这样:

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,但在您创建 children 却不知道您需要访问 parent稍后。