Notice setContentView
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainActivityBinding binding =
DataBindingUtil.setContentView(this,
R.layout.main_activity);
User user = new User("Test", "User");
binding.setUser(user);
//setContentView(R.layout.activity_device_info);
}
Remember to remove the old setContentView()
in the onCreate()
, or it may override your data binding
List-like view data binding
This blog and Android guide give us very good example and explanation. What should be noticed is that the example used the RecyclerView
to bind data, and I doesn’t find good example with ListView.
NavigationView data binding
It seems no direct way to make data binding for NavigationView, so I have to implement it in somewhat hacker way:
First, in order to use bind, we can’t use direct headerLayout
and replace it with a included layout
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_drawer"
app:menu="@menu/drawer">
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="@menu/drawer">
<include layout="@layout/nav_header_drawer"
bind:thisDevice="@{thisDevice}" />
</android.support.design.widget.NavigationView>
The newly included view is on the top of menu, so it will show normally. But part of menu items will move up because there is no header above it and are overlapped by newly included view( although those items can receive the touch event), so we can add a header.
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/navigation"
app:menu="@menu/activity_drawer_drawer">
<include
layout="@layout/nav_header_drawer"
bind:thisDevice="@{thisDevice}" />
</android.support.design.widget.NavigationView>
navigation layout is an empty layout having the same height and width with real nav_header_drawer
. So both menu our real layout is shown normally.
Of course, the java code is necessary for data binding:
ActivityDrawerBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_drawer);
binding.setThisDevice(Device.now);
Layout file is here.
Working example can be found here.
Get data from bound view
Sometimes, we want to get the data we bound to view. For example, when a user click a list of messages, then you want to show next view by the data bound to this list item, you may choose to get data from this view.
public void onClickMsgAvatar(View view) {
Intent intent = new Intent(this, OthersInfoActivity.class);
// get data from view?
// add data to intent
startActivity(intent);
}
In this case, I find we can use customer xml property to make the connection between view and data.
@BindingAdapter("device")
public static void setDevice(ImageView imageView, Device device) {
map.put(imageView, device);
}
public static Device getDevice(ImageView view) {
return map.get(view);
}
And how to use it:
<ImageView
app:device="@{msg.device}"
android:onClick="onClickMsgAvatar" />
So we can use it in onClick
public void onClickMsgAvatar(View view) {
Intent intent = new Intent(this, OthersInfoActivity.class);
Device device = AvatarBindingAdapters.getDevice((ImageView) view);
// add data into intent
startActivity(intent);
}
Written with StackEdit.
评论
发表评论