使用Android Studio开发Android应用程序鲜为人知的features是数据绑定(data binding)。在后面的文章将会介绍它所带来的优秀的features,但最基本的features是移除findViewById。
原文链接:https://medium.com/google-developers/no-more-findviewbyid-457457644885#.guw4rf4gb
这个代码是不是很烦人?
1 | TextView hello = (TextView) findViewById(R.id.hello); |
有一些工具可以省去写这种代码的麻烦,但这有一种官方的方法是使用Android Studio 1.5+。
首先,你需要在应用程序的build.gradle文件中添加如下代码:1
2
3
4
5
6android {
....
dataBinding {
enabled = true
}
}
然后修改布局文件的最外层标签为<layout>
而不是无论你使用的什么ViewGroup:
1 | <layout xmlns:android="http://schemas.android.com/apk/res/android" |
layout 标签会告诉Android Studio这个布局在编译的时候需要额外的处理找到所有需要的Views并且注意它们的下一步。所有外层没有使用 layout 标签的布局不会有额外处理这一步,因此你可以把这个运用到新的工程任何你喜欢的地方不用修改应用程序的其它地方。
下一步需要做的是告诉它加载你的布局文件在运行的时候。因为这个方法的所有工作都会返回到Eclaire release,加载这些预处理布局文件没有依赖新框架。因此,你不得不对加载程序做一点修改。
对于Activity,不是这样:1
2
3
4setContentView(R.layout.hello_world);
TextView hello = (TextView) findViewById(R.id.hello);
hello.setText("Hello World"); // for example, but you'd use
// resources, right?
就像这样加载它:1
2
3HelloWorldBinding binding =
DataBindingUtil.setContentView(this, R.layout.hello_world);
binding.hello.setText("Hello World"); // you should use resources!
你可以看到这有一个类,HelloWorldBinding 是由 hello_world.xml 布局文件生成的并且你可以使用ID “@+id/hello”的View分配的final field hello。不需要强转,不需要findViewById。
这个访问View的机制不仅比findViewById方便,而且还更快。绑定过程中,布局中的所有view都将分配给单一的字段。当你运行findViewById,View层级每次都会去找到它。
你会看到的是它会以驼峰式命名变量(就像hello_world.xml会生成HelloWorldBinding类),因此如果你设置了一个“@+id/hello_text” ID字段名会是 helloText。
当你使用RecyclerView,ViewPager或其它没有设置为Activity的内容填充你的布局时,你也想使用生成类中生成的类型安全的方法。这有几个方法对应LayoutInflater,选择最适合你的一个使用。例如:
1 | ViewInflateTestBinding binding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.view_inflate_test, null, false); |
如果你还没有attaching填充的View到ViewGroup的容器,那你不得不访问填充View的层级。你可以使用binding的getRoot()方法实现这个:
1 | linearLayout.addView(binding.getRoot()); |
现在你可能想知道,假如我有一个布局有不同的配置和不同的Views会怎样?布局预处理和运行时填充阶段会通过添加所有Views IDs到生成的类并且如果它们没有填充到布局会把它们设置为null。
是不是很神奇,嗯哈?最厉害的地方在于这个在运行的时候没有用反射或其它高成本的技术。它很容易在你当前的应用中使用,让生活更简单并且加载你的布局可能会稍微快一点。
你可以从这里下载完整代码:https://github.com/yuweiguocn/DataBindingDemo