在MainActivity java中,如何直接调用anko类?

时间:2018-04-11 07:32:53

标签: java android kotlin anko

我使用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 - &gt; SingleInActivity - &gt; SingInView

当然可以简单地制作。

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

如何解决这个问题?

如何直接从Java类

调用Anko类

1 个答案:

答案 0 :(得分:2)

如果您仔细阅读Anko源代码,您很快就会发现:

it('Should redirect to previous visited page', () => {
    console.log(action.called); // false
});

来自wiki(MyActivityUI是组件):interface AnkoComponent<in T> { fun createView(ui: AnkoContext<T>): View } 。现在,AnkoComponent只是一个接口,而setContentView方法是一个返回createView的扩展函数。

无论如何,setContentView扩展函数将AnkoContextImpl的最后一个变量传递为MyActivityUI().setContentView(this)。最后一个变量是否是实际设置内容视图,这是活动首先传递的原因。

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

  • 该组件不是活动
  • setContentView方法不能替代Activity中的setContentView;只是它的包装。

由于它不是一项活动,因此您无法使用意图。而且,因此,您不能单独使用它。你需要一项活动。现在,您当然可以使用常规方法,但也有另一种方法。由于AnkoComponent本身没有任何字段,因此可以毫不费力地序列化。只是为了澄清:某些字段可以序列化,即使它不可序列化(尽管某些类如Context不能序列化)。无论如何,你创建了一个活动:

true

或者它在Java中的等价物:

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. 
    }
}

请注意,发送到此类的任何UI组件都必须使用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 } } 声明。此外,组件必须实现Serializable。否则他们无法通过Bundle。或者,您可以使用int或Strings作为标识符,并使用该值来选择要显示的AnkoComponent。

尽管如此,绝对最简单的方法是为每个组件创建一个活动。

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