android - PagerAdapter 中上下文和 findViewById() 的错误使用?
问题描述
在现有的 Android 应用程序项目(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)
//..
}
}
问题1:为什么要用findViewById()?数据绑定不应该也为 PageAdapters 解决这个问题吗?
问题 2:每当我在我的视图之外的任何其他类中找到上下文时(尤其是使用 MVVM 时),这对我来说是非常反模式的。为什么在那里提供上下文?有没有理由不使用
val imageView = container.findViewById<ImageView>(R.id.iv_logo)
没有膨胀前面的两条线?
问题 3:尽管代码正在运行(目前).. kotlin 中如何处理副本?
private var contextCopy = ctx
这里在 Kotlin 中创建了一个完整的新副本实例?例如,当我翻转屏幕时,相应的上下文会InformationSlideActivity
正确处理这个问题,但我InformationSlideAdapter
仍然有一个未翻转状态的旧上下文实例?
不幸的是,我不能问编码员,因为他已经走了。
提前谢谢
帕夫
解决方案
问题 1:可以使用数据绑定或合成来代替 findViewById。这可能是遗留代码或给定视图的 id,可能有更多具有相同 id 的视图,开发人员希望通过在特定布局中搜索来避免歧义。
问题 2:注入或传递上下文(在大多数情况下)是一种反模式。如果需要上下文,可以从容器中检索它。和...之间的不同
layoutScreen.findViewById<ImageView>(R.id.iv_logo)
和
container.findViewById<ImageView>(R.id.iv_logo)
是第一个是在新膨胀的布局中搜索,在那个时间点可能会或可能不会附加到容器。
问题 3:
private var contextCopy = ctx
这没有任何意义,它只是制作参考副本。鉴于上下文作为构造函数参数传递,开发人员可能不知道他们可以执行以下操作:
class InformationSlideAdapter(val ctx: Context, list: List<RelevantItem>) : PagerAdapter() {
在任何一种情况下,都不会刷新上下文,并且要拥有一个新实例,应该重新创建适配器根据问题 2 的答案,不应将上下文传递给适配器,而是从容器中检索。
推荐阅读
- python - 如何使用主脚本的变量执行辅助脚本?
- symfony - 使用 JMS 序列化程序从 FOSUserBundle 中排除字段,该 JMS 序列化程序在 dev 上工作但不在 prod 环境中
- java - 如何将 WebElement 转换为 selenium/Java 中“if”语句的字符串
- sql - 如果子目录不存在,则使用 SQL 脚本创建子目录
- xcode - 自动签名无法解决“项目”目标的权利问题
- macos - 使用 Jenkins-lts Homebrew 更改端口
- r - 使用 nloptr 包进行更灵活的目标定义
- apache-nifi - Nifi流文件中如何删除流文件属性?
- tensorflow - 直接导入 Keras 还是通过 TensorFlow 导入?我应该卸载其中一个吗?
- javascript - ASP.NET Core Fetch POST FormData() application/x-www-form-urlencoded