简体   繁体   English

PagerAdapter 中上下文和 findViewById() 的错误使用?

[英]Wrong usage of context and findViewById() in PagerAdapter?

In an existing Android App project (MVVM is used as pattern) I have found a PagerAdapter to swipe several information within this adapter:在现有的 Android App 项目(MVVM 用作模式)中,我发现了一个 PagerAdapter 可以在此适配器中滑动多个信息:

class InformationSlideAdapter(ctx: Context) : PagerAdapter() {

    private var contextCopy = ctx

    override fun instantiateItem(container: ViewGroup, position: Int): Any {

        val layoutInflater = contextCopy.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        val layoutScreen = layoutInflater.inflate(R.layout.slide_item, null)

        val imageView = layoutScreen.findViewById<ImageView>(R.id.iv_logo)
        //..
    }
}

Question 1: Why is there findViewById() used?问题1:为什么要用findViewById()? Shouldn't databinding solve this issue also for PageAdapters?数据绑定不应该也为 PageAdapters 解决这个问题吗?

Question 2: Whenever I find a context in any other class than my view (especially when MVVM was used), this is very anti pattern for me.问题 2:每当我在任何其他 class 中找到与我的看法不同的上下文时(尤其是在使用 MVVM 时),这对我来说都是非常反模式的。 Why was a context provided there?为什么在那里提供上下文? Is there a reason for not using有没有理由不使用

    val imageView = container.findViewById<ImageView>(R.id.iv_logo)

without inflating the two lines ahead?没有膨胀前面的两条线?

Question 3: Altough the code is working (for now).. How are copies handled in kotlin?问题 3:尽管代码正在运行(目前).. kotlin 中的副本如何处理?

    private var contextCopy = ctx

Here a complete new copy instance is created in Kotlin?这里在 Kotlin 中创建了一个完整的新副本实例? Eg when I flip the screen, the context in corresponding InformationSlideActivity handles this correctly, but my InformationSlideAdapter still has an old instance of context with the unflipped state?例如,当我翻转屏幕时,相应InformationSlideActivity中的上下文会正确处理此问题,但我的InformationSlideAdapter仍然有一个旧的上下文实例,其中未翻转的 state?

Unfortunately I cant ask the coder, since he has gone.不幸的是,我不能问编码员,因为他已经走了。

Thnx in advance提前谢谢

Pav帕夫

Question 1: databinding or synthetics could be used use instead of findViewById.问题 1:可以使用数据绑定或合成来代替 findViewById。 This could be legacy code or given the id of the view, it is possible that there are more views with same id and the developer wanted to avoid ambiguity by searching in a specific layout.这可能是遗留代码或给定视图的 id,可能有更多具有相同 id 的视图,开发人员希望通过在特定布局中搜索来避免歧义。

Question 2: Injecting or passing context (in most cases) is an antipattern.问题 2:注入或传递上下文(在大多数情况下)是一种反模式。 If the context is needed it can be retrieved from the container.如果需要上下文,可以从容器中检索它。 the difference between和...之间的不同

layoutScreen.findViewById<ImageView>(R.id.iv_logo)

and

container.findViewById<ImageView>(R.id.iv_logo)

is that the first one is searching in the newly inflated layout, that may or may not be attached to the container at that point in time.是第一个是在新膨胀的布局中搜索,在那个时间点可能会或可能不会附加到容器。

Question 3:问题 3:

private var contextCopy = ctx

this makes no sense, it is just making a reference copy.这没有任何意义,它只是制作参考副本。 Given that the context is passed as a contructor parameter it is possible that the developer didn't know that they could do the following:鉴于上下文作为构造函数参数传递,开发人员可能不知道他们可以执行以下操作:

class InformationSlideAdapter(val ctx: Context, list: List<RelevantItem>) : PagerAdapter() {

in either case the context will not be refreshed and to have a new instance the adapter should be recreated As per the answer of question2, the context should not be passed to the adapter and instead retrieved from the container.在任何一种情况下,都不会刷新上下文,并且要拥有一个新实例,应重新创建适配器根据问题 2 的答案,不应将上下文传递给适配器,而是从容器中检索。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM