在MainActivityjava中,如何直接调用ankoclass?

In the MainActivity java, how to call the anko class directly?

我使用 anko 库创建了一个登录视图。

class SingInView : AnkoComponent<SingleInActivity> {
   override fun createView(ui: AnkoContext<SingleInActivity>) = with(ui) {
       verticalLayout {
          lparams(width = matchParent, height = matchParent) 

          textView("Member Login")
          editText {
              hint = "E-mail"
          }
          editText {
              hint = "PassWord"
          }
          button("Login")
       }
    }
}

和SingleInActivity.kt

class SingleInActivity : AppCompatActivity() {
   override fun onCreate(savedInstanceState)
   SingInView().setContentView(this)

和MainActivity.java

public class MainActivity extends AppCompatActivity {

   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       startActivity(new Intent(this, SingInView.class));
       finish();
   }
}

当前我的应用程序 MainActivity -> SingleInActivity -> SingInView .

当然可以简单的做。

但是有一个条件 1.MainActivity是java(kotlin禁止) 2. 只使用MainActivity, SingInView.

如何解决这个问题?

如何直接从 Java class

调用 Anko class

如果你深入研究 Anko 源代码,你会很快发现:

interface AnkoComponent<in T> {
    fun createView(ui: AnkoContext<T>): View
}

来自 wiki(其中 MyActivityUI 是组件):MyActivityUI().setContentView(this)。现在,AnkoComponent 只是一个接口,而 setContentView 方法是 returns createView 的扩展函数。

无论如何,setContentView 扩展函数将 AnkoContextImpl 的最后一个变量作为 true 传递。最后一个变量是是否实际设置内容视图,这就是首先传递 activity 的原因。

TL;DR(可能对我的观点进行更明智的总结):

  • 该组件不是 Activity
  • setContentView 方法不能替代 Activity 中的 setContentView;只是一个包装器。

并且由于它不是 activity,因此您不能在其中使用意图。因此,您不能单独使用它。你需要一个 activity。现在,您当然可以使用常规方法,但还有另一种方法。由于 AnkoComponent 本身没有任何字段,因此可以毫不费力地对其进行序列化。只是为了澄清:有些字段即使不可序列化也可以序列化(尽管有些 class 像 Context 不能序列化)。不管怎样,你创建了一个 activity:

class AnkoComponentActivity : AppCompatActivity(){//Can be a regular Activity too

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState);
        val component = intent.getSerializableExtra("uiComponent") as AnkoComponent<AnkoComponentActivity>//The type has to match this activity, or setContentView won't allow passing `this`
        component.setContentView(this)//The context of the activity doesn't get passed until this point, which enables the use of this system. 
    }
}

或者等同于 Java:

public class AnkoComponentActivity extends AppCompatActivity {

    public void onCreate(Bundle sis){
        super.onCreate(sis);
        AnkoComponent<AnkoComponentActivity> component = (AnkoComponent<AnkoComponentActivity>) getIntent().getSerializableExtra("uiComponent");
        org.jetbrains.anko.AnkoContextKt.setContentView(component, this);//For reference, this is how you call Kotlin extension functions from Java
    }
}

请注意,发送到此 class 的任何 UI 组件都必须用 <AnkoComponentActivity> 声明。此外,组件必须实现 Serializable。否则它们无法通过 Bundle 传递。或者,您可以使用整数或字符串作为标识符,并使用值来选择要显示的 AnkoComponent。

尽管如此,最简单的方法就是为每个组件创建一个 activity。

TL;DR: AnkoComponent 不是 Activity,这意味着您不能在其中使用意图。你必须使用一个 Activity,但是使用 Serializable 可以让你通过一个包将组件传递给一个 Activity 用于手动创建多个 AnkoComponents 而无需指定特定类型。