android{
...
dataBinding {
enabled = true
}
...
}
複製代碼
(抄的介紹。。。真多)android
public class User {
private String text;
public User(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
複製代碼
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><!--佈局以layout做爲根佈局-->
<layout>
<data>
<!--綁定Model
name:
user是User的一個實例的引用 相似於
User user_ex=new User()
這個user 等待activity/fragment或其餘地方進行注入
type:
User類的全路徑
>
<variable
name="user"
type="lzf.one.adapter.UserInfo" />
</data>
<!--咱們須要展現的佈局 熟悉的佈局吧-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/main_btn3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.text}" />
<!--這裏user.text至關於user.getText()-->
</LinearLayout>
</layout>
複製代碼
public class MainActivity extends AppCompatActivity {
//注意
//注意
//注意
//注意
//引入前 要makeProject 生成代碼
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//經過DataBInding加載佈局都會對應的生成一個對象,如ActivityMainBinding,對象名在佈局文件名稱後加上了一個後綴Binding
binding = DataBindingUtil.setContentView(MainActivity.this, R.layout.activity_main);
//綁定model對象數據
User user = new User("綁定Model數據類型");
binding.setUser(user);
//或者 binding.setVariable(BR.user,user);
}
//運行就會發現TextView的text已經改變
}
複製代碼
//老規矩 先寫佈局 佈局很簡單 就一個textView 一個recycler
<?xml version="1.0" encoding="utf-8"?>
<layout>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="lzf.one.adapter.MainActivity">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="9dp"
android:text="點擊顯示recycler"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/text" />
</android.support.constraint.ConstraintLayout>
</layout>
複製代碼
//實體類 給recycler的item用 爲了方便 寫的簡單
public class UserInfo {
private String name;
private String age;
public UserInfo(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
//model 提供數據 提供一個userInfoList 沒啥毛病
public class UserViewModel {
private List<UserInfo> userInfoList;
public UserViewModel() {
this.userInfoList = new ArrayList<>();
}
public List<UserInfo> getUserInfoList(){
userInfoList.add(new UserInfo("張三","25歲"));
userInfoList.add(new UserInfo("張三","25歲"));
userInfoList.add(new UserInfo("張三","25歲"));
userInfoList.add(new UserInfo("張三","25歲"));
return userInfoList;
}
}
複製代碼
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding mBind;
private UserViewModel userViewModel;
private MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBind = DataBindingUtil.setContentView(this, R.layout.activity_main);
mBind.text.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mBind.recycler.setVisibility(View.VISIBLE);
}
});
mBind.recycler.setLayoutManager(new LinearLayoutManager(this));
userViewModel=new UserViewModel();
adapter=new MyAdapter(this,userViewModel.getUserInfoList());
mBind.recycler.setAdapter(adapter);
}
}
//接下來 咱們開始寫adapter 咱們先正常寫
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{
private Context context;
private List<UserInfo> userInfoList;
MyAdapter(Context context, List<UserInfo> userInfoList) {
this.context = context;
this.userInfoList = userInfoList;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
UserItemBinding userItemBinding= DataBindingUtil.inflate(LayoutInflater.from(context),R.layout.user_item,parent,false);
return new MyViewHolder(userItemBinding);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
UserItemBinding userItemBinding=holder.getUserItemBinding();
userItemBinding.setUser(userInfoList.get(position));
userItemBinding.executePendingBindings();
}
@Override
public int getItemCount() {
return userInfoList==null?0:userInfoList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
UserItemBinding userItemBinding;
MyViewHolder(UserItemBinding userItemBinding) {
super(userItemBinding.getRoot());
this.userItemBinding=userItemBinding;
}
UserItemBinding getUserItemBinding() {
return userItemBinding;
}
}
}
複製代碼
咱們先來優化ViewHoldergit
class MyViewHolder extends RecyclerView.ViewHolder{
UserItemBinding userItemBinding;
MyViewHolder(UserItemBinding userItemBinding) {
super(userItemBinding.getRoot());
this.userItemBinding=userItemBinding;
}
UserItemBinding getUserItemBinding() {
return userItemBinding;
}
}
UserItemBinding 繼承 ViewDataBinding
根據多態 那麼 咱們能夠把viewholder裏的UserItemBinding改爲ViewDataBinding
class MyViewHolder extends RecyclerView.ViewHolder{
ViewDataBinding viewDataBinding;
MyViewHolder(ViewDataBinding viewDataBinding) {
super(viewDataBinding.getRoot());
this.viewDataBinding=viewDataBinding;
}
ViewDataBinding getViewDataBinding() {
return viewDataBinding;
}
}
這樣來看 viewholder就再也不依賴一個具體的databinding而是依賴ViewDataBinding(父類)
那麼viewHolder如今是通用的了 我能夠一直使用
複製代碼
咱們再來優化adapter 要adapter實現萬能最起碼的 要實現多類型item 關於 Android Adapter,你的實現方式可能一直都有問題 咱們能夠相似的實現 將Item的layoutId看成Itme的viewType。咱們先來改造實體類UserInfogithub
//寫個接口 定義一個規範
public interface BindAdapterType {
int getType();
}
//userInfo實現接口
public class UserInfo implements BindAdapterType {
private String name;
private String age;
public UserInfo(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
//注意
@Override
public int getType() {
//返回layoutId 看成userItem的viewType
return R.layout.user_item;
}
}
複製代碼
那麼 如今咱們的adapter變成什麼樣了呢bash
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{
private Context context;
private List<UserInfo> userInfoList;
MyAdapter(Context context, List<UserInfo> userInfoList) {
this.context = context;
this.userInfoList = userInfoList;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(DataBindingUtil.
inflate(LayoutInflater.from(context),
viewType,parent,false));
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
//這裏編譯過不去 別急 一點點改
UserItemBinding userItemBinding=holder.getViewDataBinding();
userItemBinding.setUser(userInfoList.get(position));
userItemBinding.executePendingBindings();
}
@Override
public int getItemCount() {
return userInfoList==null?0:userInfoList.size();
}
@Override
public int getItemViewType(int position) {
return userInfoList.get(position).getType();
}
}
複製代碼
這時候 咱們會看到onCreateViewHolder()再也不依賴具體的layoutId啦,而是userInfo固有的屬性Type,viewholder也是通用的了,那麼咱們的onCreateViewHolder()算是改造完成了 接着咱們來改造onBindViewHolder()app
//這裏有個前置的知識
//對於每一個<layout></layout>中使用的變量名稱 databind都會生成一個id
//舉個例子
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
//注意注意
//對於user這個引用 databind會生成一個(int類型)BR.user的資源
name="user"
type="lzf.one.adapter.UserInfo" />
</data>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
//節省空間 裏面的內容刪掉了 就是user_item.xml
</android.support.constraint.ConstraintLayout>
</layout>
那麼onBindViewHolder()咱們就能夠改形成這樣
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.getViewDataBinding().setVariable(BR.user,userInfoList.get(position));
holder.getViewDataBinding().executePendingBindings();
}
//在這裏BR.user這個id是user_item.xml的user的資源id
//user_item又引用了userInfo,咱們是否是能夠相似viewType的方式 把id看成userInfo的屬性呢?
//咱們來試試
複製代碼
改造接口ide
public interface BindAdapterType {
int getType();
int getId();
}
複製代碼
userInfo 實現getId()方法佈局
//get/set方法去掉 展現主要內容
public class UserInfo implements BindAdapterType {
private String name;
private String age;
public UserInfo(String name, String age) {
this.name = name;
this.age = age;
}
@Override
public int getType() {
return R.layout.user_item;
}
@Override
public int getId() {
return BR.user;
}
}
複製代碼
那麼如今onBindViewHolder()就變成什麼樣了呢?咱們來看一下:post
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.getViewDataBinding().setVariable(
userInfoList.get(position).getId(),
userInfoList.get(position));
holder.getViewDataBinding().executePendingBindings();
}
複製代碼
到如今咱們已經基本改造完成了 如今咱們能夠把List的泛型換掉了 他已經再也不單純的是userInfo 而是list<? extend BindAdapterType> data(userInfo 實現了接口BindAdapterType); 如今 咱們已經改形成功了 咱們來看看完整的代碼gradle
//如今adapter再也不限定接受userInfo的集合了 而是任何實現了BingAdapterType接口的實體
//能夠是userInfo 也能夠是studentInfo
//只要實現了BindAdapterType接口就行(getType()、getId()的返回值仍是要給的(0.0)
//至於item的交互 你就在對應的實體裏面寫唄
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{
private Context context;
private List<? extends BindAdapterType> userInfoList;
MyAdapter(Context context, List<? extends BindAdapterType> userInfoList) {
this.context = context;
this.userInfoList = userInfoList;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(DataBindingUtil.
inflate(LayoutInflater.from(context),
viewType,parent,false));
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.getViewDataBinding().setVariable(userInfoList.get(position).getId(),userInfoList.get(position));
holder.getViewDataBinding().executePendingBindings();
}
@Override
public int getItemCount() {
return userInfoList==null?0:userInfoList.size();
}
@Override
public int getItemViewType(int position) {
return userInfoList.get(position).getType();
}
class MyViewHolder extends RecyclerView.ViewHolder{
ViewDataBinding viewDataBinding;
MyViewHolder(ViewDataBinding viewDataBinding) {
super(viewDataBinding.getRoot());
this.viewDataBinding=viewDataBinding;
}
ViewDataBinding getViewDataBinding() {
return viewDataBinding;
}
}
}
複製代碼
代碼地址優化