User.java(略)
包含String类型的name和int类型的age,构造方法包含这两个参数。包含getter和setter
item_title.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="handler"
type="com.example.hjcai.myapplication.EventHandler">
variable>
data>
<Button
android:id="@+id/userbtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{handler::onClickFriend}"
android:text="xnxnxnx"/>
layout>
显示标题的格式
EventHandler.java
public class EventHandler {
private Context mContext;
public EventHandler(Context context) {
mContext = context;
}
public void onClickFriend(View view) {
Toast.makeText(mContext, "onClickFriend", Toast.LENGTH_LONG).show();
}
}
使用databinding构建事件监听的格式如上所示(xml+java)
item_user_layout.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="useritem"
type="com.example.hjcai.myapplication.data.User" />
data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{useritem.name}" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text='@{"" +useritem.age}' />
LinearLayout>
layout>
显示user信息的布局格式,具体数据是如何与xml绑定的
UserAdapter.java
public class UserAdapter extends BaseAdapter{
private List userList;
private Context context;
public UserAdapter(Context context, List userList) {
this.userList = userList ;
this.context = context ;
}
@Override
public int getCount() {
//need add the count of title
return userList.size()+1;
}
@Override
public User getItem(int position) {
//need exclude index 0(it is position for title)
if(position>0){
//position 0 is title,so position from need - 1,that's the position for users
return userList.get(position-1);
}else{
return null;
}
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getViewTypeCount() {
//there two type of view
return 2;
}
@Override
public int getItemViewType(int position) {
if (position ==0){
//if position is 0,it is type for title
return 0;
}else{
//if not,it is type for user
return 1;
}
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ItemUserLayoutBinding itemUserLayoutBinding = null;
ItemTitleBinding itemTitleBinding = null;
//需要区分user和title的显示,其实按照如下格式,代码可读性更强
//if (convertView == null) {
// switch (type) {
// case 0:
// ...
// //all code for title
// case 1:
// ...
// //all code for user
// default:
// return null;
int type = getItemViewType(position);
if (convertView == null) {
switch (type) {
case 0:
itemTitleBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_title, parent, false);
convertView = itemTitleBinding.getRoot();
break;
case 1:
itemUserLayoutBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_user_layout, parent, false);
convertView = itemUserLayoutBinding.getRoot();
break;
}
} else {
switch (type) {
case 0:
itemTitleBinding = DataBindingUtil.getBinding(convertView);
break;
case 1:
itemUserLayoutBinding = DataBindingUtil.getBinding(convertView);
break;
}
}
switch (type) {
case 0:
itemTitleBinding.setHandler(new EventHandler(context));
return itemTitleBinding.getRoot();
case 1:
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, "Click " + position, Toast.LENGTH_SHORT).show();
}
});
itemUserLayoutBinding.setUseritem(userList.get(position - 1));
return itemUserLayoutBinding.getRoot();
default:
return null;
}
}
}
ItemUserLayoutBinding是item_user_layout.xml自动生成的对应java文件,用于获取xml中的数据和对象,与Java文件通信
ItemTitleBinding则是item_title.xml自动生成的对应java文件,用于获取xml中的数据和对象,与Java文件通信
他们可以通过DataBindingUtil.inflate方法来获得可以获取xml内容的binding对象
在xml定义如下的格式
<data>
"useritem"
type="com.example.hjcai.myapplication.data.User" />
data>
则对应binding文件会生成对应useritem的set和get方法。
activity_main.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="@+id/listAll"
android:layout_width="match_parent"
android:layout_height="wrap_content">
ListView>
LinearLayout>
layout>
显示list(list将包含title和useritem,title和useritem以前滚动)
MainActivity.java
public class MainActivity extends AppCompatActivity {
private List mUserList;
private UserAdapter mUserAdapter;
ActivityMainBinding mainBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
initData();
}
private void initData() {
mUserList = new ArrayList();
for (int i=0;i<20;i++){
User u = new User("Caihuijian",27);
mUserList.add(u);
}
mUserAdapter = new UserAdapter(this,mUserList);
mainBinding.listAll.setAdapter(mUserAdapter);
}
}
databinding的xml中凡是定义了id的数据均可以通过binding对象直接点出来。例如mainBinding.listAll就是activity_main.xml中的id为listAll的listview
想在listview加入不同类型的view的核心代码在adapter中
通常情况,Android的databinding包括以下几类对象(名称都为代指,非具体类名文件名)
MainActivity:显示的界面
MyDataList:存储显示列表的内容
activity_main:显示界面对应的xml布局
MyBindings:界面xml中对应方法,会由Android机制自动调用其中的方法
MyAdapter:list的adapter,在dataBinding中不需要手动设置,在MyBindings写好,会由Android机制自动调用
item_title.xml:显示item的布局,在Adapter的getView方法中设置。
他们的关系如下:
MainActivity负责界面显示,通过setData之类的方法,将list数据存储在MyDataList实例中;MyDataList与其布局文件activity_main紧密关联,可以通过databing来实现;activity_main中一般会包含app:xxx方法,而该方法的定义一般在MyBindings中,由Android databinding机制自动调用;在MyBindings中一般会存在setAdapter的调用,用于绑定list和Adapter,当然,Adapter一般是自定义的Adapter,例如MyAdapter;而Adapter的getView方法中,会涉及填充item项的相关逻辑。
其中MyDataList可以理解为model的集合,比如Users;而item_title的存放内容,则是单一的model,比如User。
如果用图形则关系可以表示为: