只是混淆了关于转换和如何设置类变量。在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'是一个可变的属性,本来可以改变
答案 0 :(得分:1)
对于Android,通常使用lateinit var
因为您在构造函数之外创建对象(在onCreate
中等)。你可以选择两条路线:
lateinit var variable:Type
var variable:Type?
如果您准备好使用变量,我建议您使用它。您无需进行null
检查。 lateinit
意味着延迟初始化。 Kotlin使用null
表示尚未初始化,因此您不能使用可空类型并为其指定null。
如果你的变量可以为空,那么你应该采取第二种方式。
此外,如果您正在处理视图,则应使用Android extension来执行此操作。您不需要findViewById
或Activity
自己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的值。有几种方法可以做到这一点:
mViewPager?.let{ pager -> setupViewPager(pager)}
mViewPager
不会为空,在运行时保留任何违规失败,例如setupViewPager(mViewPager!!)