如何延迟在Kotlin中为val分配值?

Hel*_*oCW 1 android kotlin

我将mContext定义为val,我需要在有趣的onCreate中为其分配一个值。

代码private lateinit val mContext: Context不正确,我该怎么办?

class UIMain : AppCompatActivity() {

    private val mContext: Context

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

        mContext = this
    }
}
Run Code Online (Sandbox Code Playgroud)

回答Strelok

this就像下面的代码一样,关键字并不总是合适的,因此我认为将其分配this给mContext 更方便。

 private Context mContext;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_main);

        mContext=this;

        findViewById(R.id.btnClose).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "Hello A", Toast.LENGTH_LONG).show();
                Toast.makeText(mContext, "Hello B", Toast.LENGTH_LONG).show();
                //Toast.makeText(this, "Hello C", Toast.LENGTH_LONG).show(); //Doesn't work
                finish();
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

Mau*_*ker 5

如果使用lateinit关键字,则必须从更改valvar,从而失去不变性。如果您还可以,Strelok的答案就足够了。

但是,如果val出于任何原因您确实需要代码,可以尝试使用lazy delagate属性

Android Essense博客所述:

此属性采用lambda, lambda 在首次访问该属性时执行。之后,它将返回分配给它的值。这样,我们可以将属性声明为不可变且非null,以便只要在首次访问它之前就创建了片段(或Activity)。

例如,在您的情况下,您可以尝试执行以下操作:

private val mContext : Context by lazy {
    this
}
Run Code Online (Sandbox Code Playgroud)

简而言之:

  • 如果您的价值可以或需要可变,请使用 lateinit
  • 如果您的值要初始化一次并在您的方法之间共享,请lazy与结合使用val

但是正如其他人所述,在您的特定情况下,最好this在需要活动/上下文引用时才进行调用。

编辑:根据您的示例,为什么您需要mContext在Activity中添加一个内容,我仍然说您不需要它。

除了尝试直接在匿名函数内部调用this并使用它之外Toast#makeText(),您还可以:

  • 更改thisUIMain.this
  • 在Activity中创建一个方法,然后在匿名函数中调用该方法。例如:findViewById(R.id.btnClose).setOnClickListener { otherMethod() },在该方法内,您可以this再次使用Activity 。