[JAVA] Nettoyer findViewById du code source avec DataBindingLibrary

Aperçu

Un des composants de * Android Jetpack *, [* Data Binding Library *](https: // developer. Un mémorandum qui utilise android.com/topic/libraries/data-binding/?hl=JA) pour effacer l'acquisition de View par findViewById à partir du code source.

1. Activez * Data Binding Library * depuis build.gradle

app/build.gradle


android { 
    //Omission
    dataBinding {
        enabled = true
    }
}

Ajouter ce qui précède

2. Insérez les paramètres de mise en page dans le fichier layout / *. Xml dans <layout> </ layout>

layout/*.xml


<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <!--Paramètres de mise en page-->
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".HogeActivity">

        <!--Omission-->

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

Ajoutez <layout> </ layout> à la tête et à la queue et déplacez uniquement xmlns: vers <layout>. Ensuite, une classe * Binding qui hérite de ViewDataBinding est automatiquement générée en fonction de layout / *. Xml. Le nom de la classe est le nom xml converti en UpperCamelCase. S'il n'est pas généré automatiquement, il peut sortir si vous le reconstruisez une fois.

4. Utilisez la classe Binding

La méthode diffère légèrement selon la cible à spécifier.

Pour l'activité

Activity.java


 @Override
 protected void onCreate(@Nullable Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
-    setContentView(R.layout.activity);
+    final ActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.activity);

-    final TextView textView = findViewById(R.is.text_view);
-    textView.setText("HogeFuga");
+    binding.textView.setText("HogeFuga");

Notez le type de retour de DataBindingUtil.setContentView. (Comme il s'agit d'un type générique, toute classe qui hérite de ViewDataBinding sera acceptée)

Pour le fragment (modèle 1)

Fragment.java


+private FragmentBinding binding;

 @Override
 public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                          @Nullable Bundle savedInstanceState) {
-    return inflater.inflate(R.layout.fragment, container, false);
+    binding = FragmentBinding.inflate(inflater, container, false);
+    return binding.getRoot();
 }

 @Override
 public void onActivityCreated(Bundle savedInstanceState) {
     super.onActivityCreated(savedInstanceState);
-    final TextView textView = findViewById(R.is.text_view);
-    textView.setText("HogeFuga");
+    binding.textView.setText("HogeFuga");
 }

Un modèle qui crée une vue à partir de la classe Binding. N'est-il pas bon d'avoir une classe Binding sur le terrain?

Pour le fragment (modèle 2)

Fragment.java


+private FragmentBinding binding;

 @Override
 public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                          @Nullable Bundle savedInstanceState) {
     return inflater.inflate(R.layout.fragment, container, false);
 }

 @Override
 public void onActivityCreated(Bundle savedInstanceState) {
     super.onActivityCreated(savedInstanceState);
-    final TextView textView = findViewById(R.is.text_view);
-    textView.setText("HogeFuga");
+    final FragmentBinding binding = FragmentBinding.bind(getView());
+    binding.textView.setText("HogeFuga");
 }

Un modèle qui crée d'abord une vue, puis crée une instance de liaison basée sur celle-ci. Dans ce cas, il n'est pas nécessaire de l'avoir sur le terrain.

Pour RecyclerView.Adapter

diff:RecyclerView.Adapter.java


 @NonNull
 @Override
 public MainViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
-    final View view = inflater.inflate(R.layout.recycler_row, parent, false);
-    return new ViewHolder(view);
+    final RecyclerViewAdapterBinding binding = RecyclerViewAdapterBinding.inflate(inflater, parent, false);
+    return new ViewHolder(binding);
 }

 @Override
 public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
     holder.bind("HogeFuga");
 }

 class ViewHolder extends RecyclerView.ViewHolder {
     @NonNull
-    private final TextView textView;
+    private final RecyclerRowBinding binding;

-    private MainViewHolder(@NonNull View view) {
-        super(view);
-        textView = view.findViewById(R.id.text_view);
+    private MainViewHolder(@NonNull RecyclerRowBinding binding) {
+        super(binding.getRoot());
+        this.binding = binding;
     }

     void bind(@NonNull String text) {
-        textView.setText(text);
+        binding.textView.setText(text);
     }
 }

Si vous l'utilisez pour * RecyclerView.Adapter *, vous devez utiliser * groupie * ou * epoxy * pour éliminer le besoin de * RecyclerView.ViewHolder *.

Points à craindre

Recommended Posts

Nettoyer findViewById du code source avec DataBindingLibrary
Nettoyez votre code avec Butter Knife
Coder Java depuis Emacs avec Eclim
Installez samba4 à partir du code source sur CentOS8
[Java] Flux du code source à l'exécution
Générer le code source à partir du fichier JAR avec JD-GUI du projet Java Decompiler
Exécutez du code Java à partir de cpp sur cocos2dx
Mémorandum pour nettoyer le code Ruby