Android数据绑定dataBinding的使用方法

    技术2022-07-11  86

    想要使用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>

     

    Processed: 0.012, SQL: 9