自定义视图不会在 Fragment 内更新

Posted

技术标签:

【中文标题】自定义视图不会在 Fragment 内更新【英文标题】:Custom view doesn't update inside a Fragment 【发布时间】:2019-08-28 09:54:55 【问题描述】:

我有一个项目,我必须在自定义布局中构建视图。这种布局代表了 MVP 架构中 View 的概念,它存在于 Fragment 中。每当事件发生时,Presenter 应该通过调用 View 来更新视图,最后会在 View 中更新 TextViews。但似乎在 View 初始化后,什么都没有更新了。

如果我的演示者调用包含我的TextView视图 - 什么都没有。如果我尝试直接从片段更新TextView,那么它可以工作。我真的不明白发生了什么以及为什么它没有从包含 TextView 的布局中更新。

我的自定义视图:

class MyCustomView(fragment: MyFragment): MyViewInterface, FrameLayout(fragment.context) 

    init 
        View.inflate(context, R.layout.my_fancy_layout, this)
    

    override fun getView(): View 
        return this
    

    override fun setData(uiModel: UiModel) 
        textview_name.text = uiModel.name
    

我的片段:

class MyFragment : Fragment() 

    @Inject lateinit var view: MyViewInterface
    @Inject lateinit var presenter: MyCustomPresenter

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        ... dagger injection ...
    

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? 
        return this.view.getView()
    

    override fun onActivityCreated(savedInstanceState: Bundle?) 
        super.onActivityCreated(savedInstanceState)
        presenter.setData(...some ID to fetch data from API...)
        //textview_name.text = "blue" //this works instead
    

我的演示者:

class MyPresenter @Inject constructor(
        private val repo: MyRepository,
        private val view: MyViewInterface
) 

    fun setData(productCode: String) 
        .. some code ...
        view.setData(it) //call to my view          
    

我的视图界面:

interface MyViewInterface 
    fun getView(): View

    fun setData(uiModel: UiModel)

【问题讨论】:

我能想到的只是视图的实例在你的 UI 和 Presenter 中是不一样的。 你是对的。似乎 Dagger 注入了 2 个不同的视图而不是作用域视图。如果您愿意,可以将其设为答案,我会标记它。 当然,为什么不呢。 . 【参考方案1】:

我能想到的只是视图的实例在你的 UI 和演示者中是不一样的。我不知道你 Dagger 的代码,所以我没有任何修复它的建议。

您可以将视图从 MyPresenter 的构造函数中移开,并在注入后将其设置在 MyFragment.onCreate 中。

【讨论】:

我使用了错误的@MyScope 注释,所以它没有将它作为“每个片段”注入,而是每次都重新实例化它,新手的错误。【参考方案2】:

因为你只是在创建视图时充气

    init 
        View.inflate(context, R.layout.my_fancy_layout, this)
    

在更新数据功能中添加无效视图

  override fun setData(uiModel: UiModel) 
        textview_name.text = uiModel.name
         this.invalidate()
         this.requestLayout()

    

【讨论】:

我真的不认为重新膨胀layout 有意义。尽管我确实尝试过它只是为了了解它是否有效(顺便说一句,它不是有效的),但它不是干净或有效的方法。 更新数据后的覆盖需要刷新布局,对于刷新视图,您有许多方法,例如使布局无效或... 我尝试了很多,但都没有成功。最后@vilpe89 是对的。如果可以的话,我仍然会避免重新膨胀布局。

以上是关于自定义视图不会在 Fragment 内更新的主要内容,如果未能解决你的问题,请参考以下文章

ViewController 操作后,Swift UIView 自定义视图不会更新

MVC3 自定义视图库

状态更改时自定义 SwiftUI 视图不会更新

如何在 UIStackView 内排列的子视图上设置自定义高度?

Android - 在运行时更改自定义标题视图

自定义 listModel 不通知视图