Androidの技術知識ポイント:データバインディングを使用してfindViewById()を排除する方法

 遭遇問題

findViewById()関数を使用してビューを作成または再作成してビューへの参照を取得するたびに、Androidシステムはビュー階層をトラバースして実行時にビューを検索します。アプリのビューが少ない場合、これは問題ではありません。ただし、本番アプリケーションでは、レイアウトに数十のビューが含まれる場合があり、最高のデザインであっても、ネストされたビューが存在します。

テキストビューを含むスクロールビューを含む線形レイアウトについて考えてみます。より大きなまたはより深いビュー階層の場合、ビューの検索には十分な時間がかかり、ユーザーのアプリケーションの速度が大幅に低下する可能性があります。変数にビューをキャッシュすると役立ちますが、それでも各名前空間のビューごとに変数を初期化する必要があります。多くのビューと複数のアクティビティがあるため、これらは合計され、コードの重複が増え、プロジェクトの保守性が低下します。これは、すべての開発者にとって技術的な問題です。

テクニカルソリューション

各ビューへの参照を含むオブジェクトを作成します。Bindingオブジェクトと呼ばれるこのオブジェクトは、アプリケーション全体で使用できます。この手法は「データバインディング」と呼ばれます。アプリのバインディングオブジェクトを作成すると、ビュー階層を移動したりデータを検索したりしなくても、バインディングオブジェクトを介してビューやその他のデータにアクセスできます。

データバインディングには次の利点があります。

  • コードは、findViewById()を使用するコードよりも短く、読みやすく、保守しやすいものです。
  • データとビューは明確に分離されています。
  • Androidシステムは、ビュー階層を1回トラバースするだけで、各ビューを取得できます。これは、ユーザーがアプリケーションを操作している実行時ではなく、アプリケーションの起動時に発生します。
  • ビューにアクセスするための型安全性が得られます。(型の安全性とは、コンパイラがコンパイル時に型を検証し、変数に間違った型を割り当てようとするとエラーをスローすることを意味します。)

このタスクでは、データバインディングを設定し、データバインディングを使用して、findViewById()への呼び出しをバインドされたオブジェクトへの呼び出しに置き換えます。

手順

手順1:データバインディングを有効にする

データバインディングを使用するには、Gradleファイルでデータバインディングを有効にする必要があります。これは、デフォルトでは有効になっていないためです。これは、データバインディングによってコンパイル時間が長くなり、アプリケーションの起動時間に影響を与える可能性があるためです。

1.次の図に示すように、build.gradle(モジュール:プロジェクト名.app)ファイルを開きます。

2.添加一个「buildFeatures」大括号并设置dataBinding为true,代码如下:

android {
  ...
  
  buildFeatures {
    dataBinding true
  }
}

3.出现同步项目的提示时,点击「立刻同步(Sync Now)」,如果没有提示,请依次执行「文件(File)> 使用Gradle文件来同步项目(Sync Project with Gradle Files)」操作,或直接点击工具栏右侧的Gradle图标,如下图所示:

第 2 步:更改布局文件以用于数据绑定 

要使用数据绑定,您需要使用标签来包装XML 布局。这样根类就不再是视图组,而是包含视图组和视图的布局。然后绑定对象可以识别出布局和其中的视图。

1.打开activity_main.xml文件,并切换到「代码(Code)」选项卡,如下图所示:

2.将之前的ConstraintLayout标签替换为标签。

通常的语法结构,代码如下:

<layout>
   <LinearLayout ... >
   ...
   </LinearLayout>
</layout>

示例代码,​如下:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center">

    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/btnText" />

    </LinearLayout>

</layout>

「小知识」

依次执行「代码(Code) > 重新格式化代码(Reformat Code)」操作,修复代码缩进即可,如下图所示:

第 3 步:在MainActivity类中创建绑定对象 

将绑定对象的引用添加到MainActivity类内,以便您可以使用它来访问视图。

1.打开MainActivity.kt或MainActivity.java文件,代码如下:

Kotlin

import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

}

Java

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

2.在onCreate()方法上为绑定对象创建一个变量。该变量通常称为binding。binding类型,ActivityMainBinding类是由编译器专门为此主活动创建的。该名称来自布局文件的名称,即activity_main+Binding。

流程思路,如下图所示:

「小知识」

小驼峰式命名法(lower camel case):第一个单字以小写字母开始,第二个单字的首字母大写。例如:firstName、lastName。
大驼峰式命名法(upper camel case):每一个单字的首字母都采用大写字母,例如:FirstName、LastName、CamelCase。

示例代码,如下:

// Kotlin
private lateinit var binding: ActivityMainBinding

// Java
ActivityMainBinding binding;

3.点击ActivityMainBinding,并按下「Alt+Enter(Win版)或Option+Enter(Mac版)」组合键,导入这个缺失的类即可。

导入前,提示「导入ActivityMainBinding」,如下图所示:

 Kotlin

Java

导入后,添加相关的import语句,代码如下:

// Kotlin
import com.fm.test.databinding.ActivityMainBinding

// Java
import com.fm.test.databinding.ActivityMainBinding;

4.使用来自DataBindingUtil类的setContentView()函数来与带有MainActivity类的activity_main布局相关联。此setContentView()函数还负责视图的一些数据绑定设置。在onCreate()中,用以下代码行替换之前的setContentView()函数调用。

替换前

//Kotlin
setContentView(R.layout.activity_main)

//Java
setContentView(R.layout.activity_main);

替换后

//Kotlin
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

//Java
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

5.导入DataBindingUtil类,代码如下:

//Kotlin
import androidx.databinding.DataBindingUtil

//Java
import androidx.databinding.DataBindingUtil;

第 4 步:使用绑定对象替换对findViewById()的所有调用

现在可以将对绑定对象中视图的引用替换为对findViewById()的所有调用。创建绑定对象时,编译器从从布局中视图的ID生成绑定对象中视图的名称。例如,按钮的id属性值是user_btn,和绑定对象中的userBtn一样。

在onCreate()中,将findViewById()替换为引用绑定对象中的ID属性值「注意:以小驼峰式命名法(lower camel case)为准」。将findViewById(R.id.btn)替换为binding.btn,并添加要执行的操作代码,代码如下:

Kotlin

import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.fm.test.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.btn.setOnClickListener(this::clickHandlerFunction)
    }

     private fun clickHandlerFunction(view: View) {
       Toast.makeText(this,"我是未来码匠",Toast.LENGTH_LONG).show()
    }

}

Java

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.fm.test.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.btn.setOnClickListener(this::clickHandlerFunction);
    }

    public void clickHandlerFunction(View view) {
        Toast.makeText(this,"我是未来码匠", Toast.LENGTH_LONG).show();
    }
}

提示

変更後にコンパイラエラーが表示された場合は、[ビルド]> [プロジェクトのクリーンアップ]を選択してから、[ビルド]>[プロジェクトの再ビルド]を選択します。そうすることで、通常、生成されたファイルが更新されます。それ以外の場合は、[ファイル]> [キャッシュの無効化/再起動]を選択して、より完全なクリーンアップを行います。

アプリケーション内のすべてのリソースへの参照を保持するResourcesオブジェクトについては前に学習しました。ビューを参照する場合も同様の方法でオブジェクトをバインドできますが、そのバインディングオブジェクトははるかに複雑です。

実行結果

要約する

findViewById()の呼び出しをデータバインディングに置き換える手順:

  1. build.gradle(モジュール:projectname.app)ファイルのandroidセクション内でデータバインディングを有効にします:buildFeatures {dataBinding true}
  2. XMLレイアウトのルートビューとして使用されます。
  3. バインディング変数を定義します:private lateinit var binding:ActivityMainBinding(Kotlin)またはActivityMainBindingバインディング
  4. MainActivityクラス内にバインディングオブジェクトを作成し、setContentView(R.layout.activity_main)をbinding = DataBindingUtil.setContentView(this、R.layout.activity_main)に置き換えます。
  5. findViewById()の呼び出しを、バインディングオブジェクトのビューIDプロパティの値への参照に置き換えます。例:findViewById
(R.id.btn)=> binding.btn、つまり、この例では、ビュー名はXMLファイル「注:小文字のキャメルケースが優先されます」のビューID属性値です。

実践は真の知識を与え、研究は知恵を与えます。どんなに困難であっても、賢明で勇敢な心を持ち、慎重に研究し、問題を分析し、慎重に考え、突破口を見つけてつかむと、問題を解決することができます。困難を克服するには、忍耐力が必要です。そうしないと、自分自身に挑戦して限界を突破することができなくなります。

到这里为止,欢迎大神们随便吐槽我所写的技术文章,抓住我的痛点,请献上最宝贵的最佳的技术方案吧。放心吧,我不会复仇大家,因为大家永远都是我最好的导师。若大家对此有疑惑的地方,就能找我讨论一下,开阔眼界,增长见识。我希望得到大家的鼓励和点赞,将是我创作的最大动力。

作者声明

本篇经验系本人依照真实经历原创,需要转载到博客、自媒体平台、技术网站等,未经许可,严格遵守本人的知识版权,谢绝转载。如想转载,请联系本人授权。

联系邮箱:[email protected]

微信号:X9267543839

QQ:3403978592

おすすめ

転載: juejin.im/post/7122379358064345101