想要使用Android数据绑定:dataBinding,大体分为6步:build.gradle中添加配置、编写bean数据类、编写Adapter适配器类、编写Adapter适配器的layout布局文件、编写java界面文件、编写java界面的layout布局文件。 本文以在Fragment中使用RecyclerView列表的界面来介绍。
1.build.gradle中添加配置:在主module的build.gradle中添加配置
android {
......
//开启dataBinding功能支持
dataBinding {
enabled = true
}
......
}
2.编写bean数据类:Scene、SceneViewBean
/**
* 原始bean数据类
*/
public class Scene {
public static final String TYPE_PLATFORM = "platform";
public static final String TYPE_MANUALLY = "manually";
private String id;
private String name;
private String type;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
/**
* 数据绑定bean数据类
*/
public class SceneViewBean {
private Scene scene;
public ObservableField<String> name = new ObservableField<>();
public ObservableBoolean isPlatform = new ObservableBoolean(false);
public ObservableInt background = new ObservableInt(0);
public void setArguments(Scene scene) throws Exception {
this.scene = scene;
name.set(scene.getName());
switch (scene.getType()) {
case Scene.TYPE_PLATFORM:
isPlatform.set(true);
background.set(R.drawable.bg_scene_platform);
break;
default:
background.set(R.drawable.bg_scene_manually);
break;
}
}
public Scene getScene() {
return scene;
}
}
3.编写Adapter适配器类:RecyclerViewSceneAdapter
import android.databinding.DataBindingUtil;
import com.test.databinding.AdapterSceneItemBinding; // Binding类的包路径为:app包名+.databinding.+layout文件名转为小驼峰方式+Binding
public class RecyclerViewSceneAdapter extends RecyclerView.Adapter<RecyclerViewSceneAdapter.ViewHolder> {
private static final String TAG = RecyclerViewSceneAdapter.class.getSimpleName();
private Context mContext;
private List<SceneViewBean> sceneViewList;
private int focusSelection = -1;
private Handler handler = new Handler();
public RecyclerViewSceneAdapter(Context context, List<SceneViewBean> sceneViewList) {
this.mContext = context;
this.sceneViewList = sceneViewList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(this.mContext);
AdapterSceneItemBinding binding = DataBindingUtil.inflate(inflater, R.layout.adapter_scene_item, parent, false);
return new ViewHolder(binding.getRoot());
}
@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
AdapterSceneItemBinding binding = DataBindingUtil.getBinding(holder.itemView);
binding.setBean(sceneViewList.get(position));
binding.executePendingBindings();
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onItemClicked(sceneViewList.get(position));
}
});
holder.itemView.setTag(UIUtil.TAG_SCENE_CARD);
if (position == focusSelection) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
holder.itemView.requestFocus();
}
}, 200);
focusSelection = -1;
}
}
/**
* 支持dataBinding方式设置ImageView的resource
* 不加此方法会导致drawable资源无法使用
* 如果项目中有多个文件使用了dataBinding方式设置drawable资源的背景,只需要添加一次即可
*/
@BindingAdapter({"android:background"})
public static void setBackgroundResource(ImageView imageView, int resource) {
imageView.setBackgroundResource(resource);
}
public void setFocusSelection(int focusPosition) {
this.focusSelection = focusPosition;
}
private void onItemClicked(SceneViewBean sceneViewBean) {
Scene scene = sceneViewBean.getScene();
String id = scene.getId();
String type = scene.getType();
if (Scene.TYPE_MANUALLY.equals(type)) {
Toast.makeText(mContext, "Click manually scene! id=" + id, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(mContext, "Click platform scene! id=" + id, Toast.LENGTH_SHORT).show();
}
}
@Override
public int getItemCount() {
return sceneViewList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
}
}
}
4.编写Adapter适配器的layout布局文件:R.layout.adapter_scene_item
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<!--使用dataBinding的话,根标签要用layout-->
<data>
<!--类似于java文件的import导入包-->
<import type="android.view.View" />
<!--类似于java文件的属性定义,name表示属性名,type表示属性类型-->
<variable
name="bean"
type="com.test.adapter.SceneViewBean" />
</data>
<RelativeLayout
android:layout_width="@dimen/scene_card_width"
android:layout_height="@dimen/scene_card_height"
android:clickable="true"
android:descendantFocusability="blocksDescendants"
android:focusable="true">
<ImageView
android:id="@+id/img_select_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@{bean.background}" />
<TextView
android:id="@+id/txt_scene_name"
style="@style/scene_card_title_text_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="@dimen/scene_card_title_margin_left"
android:layout_marginTop="@dimen/scene_card_title_margin_left"
android:layout_marginRight="@dimen/scene_card_title_margin_right"
android:ellipsize="end"
android:singleLine="true"
android:text="@{bean.name}" />
<TextView
android:id="@+id/txt_scene_auto"
style="@style/scene_card_auto_text_style"
android:layout_width="@dimen/scene_card_auto_width"
android:layout_height="@dimen/scene_card_auto_height"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_marginLeft="@dimen/scene_card_title_margin_left"
android:layout_marginBottom="@dimen/scene_card_auto_margin_bottom"
android:background="@drawable/bg_scene_auto"
android:gravity="center"
android:text="@string/scene_info_auto"
android:visibility="@{bean.isPlatform? View.VISIBLE : View.GONE}" />
</RelativeLayout>
</layout>
5.编写java界面文件:MainSceneFragment
import android.databinding.DataBindingUtil;
import com.test.databinding.FragmentMainDeviceBinding; // Binding类的包路径为:app包名+.databinding.+layout文件名转为小驼峰方式+Binding
public class MainSceneFragment extends Fragment {
private static final String TAG = MainSceneFragment.class.getSimpleName();
private Context mContext;
private FragmentMainSceneBinding dataBinding;
private DataManager dataManager;
private List<SceneViewBean> sceneList = new ArrayList<>();
private RecyclerViewSceneAdapter baseSceneAdapter;
public static MainSceneFragment newInstance() {
Bundle args = new Bundle();
MainSceneFragment fragment = new MainSceneFragment();
fragment.setArguments(args);
return fragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
dataBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_main_scene, container, false);
rootView = dataBinding.getRoot();
mContext = getContext();
this.dataManager = DataManager.getInstance();
initData();
return dataBinding.getRoot();
}
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (!hidden) {
initSceneList();
}
}
public void initData() {
initSceneData();
initDeviceData();
}
private void initSceneData() {
GridLayoutManager gridLayoutManager = new GridLayoutManager(mContext, 3);
gridLayoutManager.setOrientation(GridLayoutManager.VERTICAL);
dataBinding.recycleScene.setLayoutManager(gridLayoutManager); // Binding类中获取某个组件,也是转为小驼峰方式
baseSceneAdapter = new RecyclerViewSceneAdapter(mContext, sceneList);
dataBinding.recycleScene.setAdapter(baseSceneAdapter);
dataBinding.recycleScene.setFocusable(false);
dataBinding.recycleScene.setSelectedItemAtCentered(true);
initSceneList();
}
private void initSceneList() {
sceneList.clear();
List<Scene> scenes = dataManager.getMainSceneList();
for (Scene scene : scenes) {
SceneViewBean sceneViewBean = new SceneViewBean();
try {
sceneViewBean.setArguments(scene);
} catch (Exception x) {
x.printStackTrace();
}
sceneList.add(sceneViewBean);
}
rootView.post(new Runnable() {
@Override
public void run() {
baseSceneAdapter.notifyDataSetChanged();
}
});
}
}
6.编写java界面的layout布局文件:R.layout.fragment_main_scene
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<!--使用dataBinding的话,根标签要用layout-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/layout_scene"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="@dimen/main_tab_height"
android:orientation="vertical">
<TextView
style="@style/smart_scene_title_text_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/device_title_margin_left"
android:layout_marginTop="@dimen/scene_title_margin_top"
android:text="@string/smart_scene" />
<com.open.androidtvwidget.leanback.recycle.RecyclerViewTV
android:id="@+id/recycle_scene"
android:layout_width="match_parent"
android:layout_height="@dimen/scene_main_list_height"
android:paddingLeft="@dimen/scene_main_list_padding_left"
android:paddingTop="@dimen/scene_main_list_padding_top"
android:paddingRight="@dimen/scene_main_list_padding_right" />
</LinearLayout>
</RelativeLayout>
</layout>