Android ViewBinding 替換 findViewById 的神器

ViewBinding中文官網

ViewBinding 的出現就是爲了替代 findViewById 的。以前我們寫完佈局後就要在代碼中使用 findViewById 方法找到 xml 文件中對應的 view ,這樣耗時費力,還有可能會出錯,比如 view 跟 id 不一致等等,奇奇怪怪的問題,畢竟人力和時間有限,這種簡單繁雜的工作直接交給 IDE 去做不是更好,它們做的檢測工作肯定比人來更精準。

配置

Android Studio 3.6 Canary 11 之後的版本都支持使用ViewBinding這個功能模塊了,只需要在 app/build.gradle 文件添加如下代碼即可:

	android {
        ...
        viewBinding {
            enabled = true
        }
    }

Android Studio 4.0 後改成了這樣:

	android {
        ...
        buildFeatures {
            viewBinding = true
        }
    }

通過上面的配置後,我們工程目錄下的 xml 佈局文件,就會生成對應的 Binding 類。例如:activity_main.xml 就會生成 ActivityMainBinding 類。這個類就會完成 findViewById 的工作。

當然,如果我們不想我們的 xml 文件生成 Binding 類,我們可以在 xml 佈局文件中根 view 寫入
tools:viewBindingIgnore="true"

Binding 類生成的路徑在build/generated/data_binding_base_class_source_out/debug/out/com/xxx/yyy/databinding/目錄下。

我們來看下 ViewBinding 幫我們生成的類的代碼結構是怎麼樣的。

public final class ActivityMainBinding implements ViewBinding {
    @NonNull
    private final ConstraintLayout rootView;
    @NonNull
    public final TextView idText;

    private ActivityMainBinding(@NonNull ConstraintLayout rootView, @NonNull TextView idText) {
        this.rootView = rootView;
        this.idText = idText;
    }

    @NonNull
    public ConstraintLayout getRoot() {
        return this.rootView;
    }

    @NonNull
    public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater) {
        return inflate(inflater, (ViewGroup)null, false);
    }

    @NonNull
    public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable ViewGroup parent, boolean attachToParent) {
        View root = inflater.inflate(2131361820, parent, false);
        if (attachToParent) {
            parent.addView(root);
        }

        return bind(root);
    }

    @NonNull
    public static ActivityMainBinding bind(@NonNull View rootView) {
        int id = 2131165279;
        TextView idText = (TextView)rootView.findViewById(id);
        if (idText == null) {
            String missingId = rootView.getResources().getResourceName(id);
            throw new NullPointerException("Missing required view with ID: ".concat(missingId));
        } else {
            return new ActivityMainBinding((ConstraintLayout)rootView, idText);
        }
    }
}

Android Studio 主要幫我們實現了3個方法,getRoot, inflate, bind 。最重要的就是 bind 方法了。這個方法纔是真正實現 findViewById 的地方。

用法

  • Activity 中
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());
    binding.idText.setText("ViewBinding");
}
  • Fragment 中

inflate 方法

ActivityMainBinding binding;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    binding = FragmentMainBinding.inflate(inflater, container, false);
    binding.idText.setText("Fragment");
    return binding.getRoot();
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    binding = null;
}

或者 bind 方法

FragmentMainBinding binding;

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

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    binding = FragmentMainBinding.bind(view);
    binding.idText.setText("Fragment");
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    binding = null;
}

同類競品

  • ButterKnife

通過註解實現 findViewById。

  • Kotlin Android Extensions

通過 Kotlin 語言特性底層實現 findViewById。

  • DataBinding

通過 annotation processor 實現,會影響工程的構建速度。

優點

  • Null 安全

  • 類型安全

總結

ViewBinding 總的來說就是替換 findViewById 的。可以節省我們的開發時間,提高效率。從以前的人工查找綁定,改爲 Android Studio 幫助我們查找綁定並生成對應的類。從而幫助開發人員從繁瑣的 view 查找綁定中抽身出來,做更有意義的事情。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章