【问题标题】:Using Binding for accessing UI element of parent activity from fragment使用绑定从片段访问父活动的 UI 元素
【发布时间】:2022-01-02 01:11:48
【问题描述】:

所以,我正在尝试从 kotlin 合成迁移到 Jetpack 视图绑定。

这是 kotlin 合成代码(工作正常),它只是将片段的父活动中 TextView 的可见性设置为不可见。

import kotlinx.android.synthetic.main.activity_main.*

class FirstFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_first, container, false)

        requireActivity().textView.visibility = View.INVISIBLE
        return view
    }
}

这是我正在做的迁移:

import com.mypc.myapp.databinding.FragmentFirstBinding
import com.mypc.myapp.databinding.ActivityMainBinding
    
class FirstFragment : Fragment() {
    
    private var _binding: FragmentFirstBinding? = null
    private val binding get() = _binding!!
    
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View {
            _binding = FragmentFirstBinding.inflate(inflater, container, false)
            return binding.root
        }
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
    
            binding.textView.visibility = View.INVISIBLE
            binding.textview.setOnClickListener {
            Navigation.findNavController(view).navigate(R.id.goto_secondfragment)
        }
        }
    
        override fun onDestroyView() {
            super.onDestroyView()
            _binding = null
        }
    }

我在“textview”处收到错误为“未解决的参考”:

binding.textView.visibility = View.INVISIBLE

在:

binding.textview.setOnClickListener {
            Navigation.findNavController(view).navigate(R.id.goto_secondfragment)
        }

显然编译器无法找到 Activity 中的 TextView 我已经添加了这一行:

import com.mypc.myapp.databinding.ActivityMainBinding

【问题讨论】:

    标签: android kotlin android-jetpack android-viewbinding


    【解决方案1】:

    由于您的bindingMainActivity 是私有的,您只能从MainActivity 引用您的textView。要在 FirstFragment 中显示/隐藏此视图,您可以在 MainActivity 中创建一个公共函数并从您的 FirstFragment 中调用它。

    class MainActivity: AppCompatActivity {
    
        private var _binding: ActivityMainBinding? = null
        private val binding get() = _binding!!
    
        fun showHideTextView(visible: Boolean) {
            binding.textView.isVisible = visible
        }
    }
    

    在你的片段中,你可以调用:

    (requireActivity() as MainActivity).showHideTextView(false) // This will hide the textView
    

    【讨论】:

    • 谢谢它的工作,但我还需要实现这个binding.textview.setOnClickListener { Navigation.findNavController(view).navigate(R.id.goto_details) }
    • 不幸的是,我认为没有办法将它添加到活动中的函数并从片段中调用它
    • 我已经更新了问题以便更好地理解
    • 您可以在活动本身中设置点击监听器。当侦听器被调用时,检查哪个是 backstack 中最顶层的片段。如果是FirstFragment,可以在那里执行对应的代码。
    • @notBot 此代码不符合您的要求吗?
    【解决方案2】:

    首先,您应该在作为 MainActivity 的父类的 baseActivity 中定义活动视图绑定的实例,然后定义更改文本视图的方法,例如 'showTextView' ,然后在基片段类中初始化基本活动在 onAttach 方法中具有强制转换上下文对象的实例。 我给你一些代码:

    abstract class BaseRegisterActivity : BaseActivity() {
    
        //---
    
        protected lateinit var binding: ActivityRegisterBinding
    
        private val navHostFragment by lazy {
            supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as 
            NavHostFragment
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            binding = DataBindingUtil.setContentView(this, R.layout.activity_register)
    
            //---
        }
    
         fun showTextView() {
            binding.textView.visibility = View.VISIBLE
            binding.textView.setOnClickListener {
                val fragment =
                    navHostFragment.childFragmentManager.fragments[0]
    
                if (fragment is FirstFragment) {
                   //todo
                }
            }
        }
    
    }
    
    abstract class BaseFragment : Fragment(), Injectable {
    
        //--
    
        lateinit var baseActivity: BaseRegisterActivity
    
       
        override fun onAttach(context: Context) {
            super.onAttach(context)
            baseActivity = context as BaseRegisterActivity
        }
        
        
        //--
    }
    

    【讨论】:

    • 我已更新问题以便更好地理解。请检查
    • 我已经更新了答案@notBot
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 2016-12-30
    • 2017-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多