对Kotlin来说是新的......有了Optionals和Casting的问题

时间:2017-09-22 01:40:12

标签: kotlin

只是混淆了关于转换和如何设置类变量。在java中可以做到

private var mSectionsStatePageAdapter : SectionsStatePagerAdapter? = null
private val mViewPager : ViewPager? = null

现在我们在kotlin

class MainActivity : AppCompatActivity() {
   private var mSectionsStatePageAdapter : SectionsStatePagerAdapter? = null
   private val mViewPager : ViewPager? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val mytoolbar:Toolbar = findViewById(R.id.top_toolbar)
    setSupportActionBar(mytoolbar)

    mSectionsStatePageAdapter =  SectionsStatePagerAdapter(getSupportFragmentManager())
    mViewPager = findViewById(R.id.viewpager1)


    setupViewPager(mViewPager)
}



 fun setupViewPager(viewPager :ViewPager):Unit {
        var adapter : SectionsStatePagerAdapter = SectionsStatePagerAdapter(getSupportFragmentManager())
        adapter.addFragment(Fragment1(),"Fragment1")
        viewPager.setAdapter(adapter)
    }

我得到val无法重新分配... 错误:(65,24)智能投射到'ViewPager!'是不可能的,因为'mViewPager'是一个可变的属性,本来可以改变

2 个答案:

答案 0 :(得分:1)

对于Android,通常使用lateinit var因为您在构造函数之外创建对象(在onCreate中等)。你可以选择两条路线:

  • lateinit var variable:Type
  • var variable:Type?

如果您准备好使用变量,我建议您使用它。您无需进行null检查。 lateinit意味着延迟初始化。 Kotlin使用null表示尚未初始化,因此您不能使用可空类型并为其指定null。

如果你的变量可以为空,那么你应该采取第二种方式。

此外,如果您正在处理视图,则应使用Android extension来执行此操作。您不需要findViewByIdActivity自己Fragment

答案 1 :(得分:0)

这里发生了两件事。

首先,正如@gyosida指出的那样,您已将mPager属性定义为val而不是var,因此无法在行mViewPager = findViewById(R.id.viewpager1)中重新分配。正如@Joshua指出的那样,您要么必须使其成为var,要么需要将其设为lateinit val以解决未使用类实例初始化的问题。

第二个是您描述的实际错误,“可变属性”,可以更改',如果您将其设为var,您将继续看到使用lateinit的方法很可能是更好的主意。

但是,要解释此错误,请在您的方法声明中:

fun setupViewPager(viewPager: ViewPager): Unit {

您已经说过viewPager的参数不能为空。如果是,那将是viewPager: ViewPager?。因此,如果您将可能为null的内容传递给它,则会出现编译错误。

Kotlin告诉你的是,在这两行之间:

mViewPager = findViewById(R.id.viewpager1)

setupViewPager(mViewPager)

某事 - 想象另一个线程上的另一个方法 - 可能会将mViewPager的值从该已分配的实例更改为null。因此传递它是不安全的。

在不更改方法的情况下解决此问题的唯一方法是提供保证为非null的值。有几种方法可以做到这一点:

  • 将您的值分配给无法受到干扰的方法级变量,并将其作为参数提供
  • 只调用您的函数如果该值为非null,例如mViewPager?.let{ pager -> setupViewPager(pager)}
  • 声明mViewPager不会为空,在运行时保留任何违规失败,例如setupViewPager(mViewPager!!)