GVKun编程网logo

ViewBinding脱坑之路(脱坑玩家)

9

本文将带您了解关于ViewBinding脱坑之路的新内容,同时我们还将为您解释脱坑玩家的相关知识,另外,我们还将为您提供关于actvity.findViewById()与view.findViewBy

本文将带您了解关于ViewBinding脱坑之路的新内容,同时我们还将为您解释脱坑玩家的相关知识,另外,我们还将为您提供关于actvity.findViewById() 与 view.findViewById()、Android Studio 3.6中新的视图绑定工具ViewBinding 用法详解、Android Studio 之 DataBing ,不需要再一个个findViewById了、Android Studio3.6新特性之视图绑定ViewBinding使用指南的实用信息。

本文目录一览:

ViewBinding脱坑之路(脱坑玩家)

ViewBinding脱坑之路(脱坑玩家)

一、结缘

在查找Butterknife的时候,发现了ViewBinding,说是Android Studio版本3.6及以上才可以使用。

二、入坑

因为自己的Android Studio是4.1.1版本,一直设置总是无法引用

import com.example.项目名称.databinding.ActivityMainBinding;

所以就降级为了Android Studio 3.6,发现可以使用,感觉升级为Android Studio 4.0也可以使用,确实升级Android Studio 4.0后可以使用,但是呢,后续再新建一个项目却无法使用。几乎比对了所有的项目还是没有找到方法。

三、脱坑

发现控件必需有ID才能导入布局,如下图:

在这里插入图片描述

至此结束了,终于可以愉快的玩耍了。

actvity.findViewById() 与 view.findViewById()

actvity.findViewById() 与 view.findViewById()

自从学习android的hello world开始

我们就知道了这样一个函数findViewById(),他已经成为了家喻户晓,坑蒙拐骗,杀人越货必备的一个函数(好吧,这句是扯淡)

但一直用也没细致研究过它,直到写程序的时候发现一个由这个函数引起的一个莫名其妙的bug,遂决定好好研究下次函数~

我们调用的findViewById()函数其实有两种(目前我只看到两种,不确定还有没有其他的),一种是Activity类中findViewById()函数

另外一种是View类中定义的findViewById()函数

一般我们在oncreate()方法中使用的(**view)findViewById(R.id.**)既是调用的Activity中的findViewById()函数

而在其他情况写出的***view.findViewById()中调用的是view类中的findViewById()

分别看一下源代码中的实现方法及介绍

Activity类中定义的findViewById()

[java]
/**
 * Finds a view that was identified by the id attribute from the XML that
 * was processed in {@link  #onCreate}.
 *
 * @return  The view if found or null otherwise.
 */ 
public View findViewById(int id) { 
    return getWindow().findViewById(id); 

/**
 * Retrieve the current {@link  android.view.Window} for the activity.
 * This can be used to directly access parts of the Window API that
 * are not available through Activity/Screen.
 *
 * @return Window The current window, or null if the activity is not
 *         visual.
 */ 
public Window getWindow() { 
    return mWindow; 

从这里可以看出这个函数是在寻找在xml中定义的指定id的对象
View类中的findViewById()

[java]
/**
 * Look for a child view with the given id.  If this view has the given
 * id, return this view.

 *
 * @param id The id to search for.
 * @return The view that has the given id in the hierarchy or null
 */ 
public final View findViewById(int id) { 
    if (id < 0) { 
        return null; 
    } 
    return findViewTraversal(id); 
    /**
 * {@hide}
 * @param id the id of the view to be found
 * @return the view of the specified id, null if cannot be found
 */ 
protected View findViewTraversal(int id) { 
    if (id == mID) { 
        return this; 
    } 
    return null; 

从这里可以看出我们是从一个view的child view中寻找指定id的对象,所以即使几个layout的XML文件中的View的id号相同的话,只要他们没有相同的父节点,或有相同的父亲节点,但不在父节点及以上节点调用findViewById通过id来查找他们就是没有问题。(这句引用自这里http://www.2cto.com/kf/201204/127404.html)
使用这个函数的常见问题:
1.既然Activity中的findViewById()是从R.java中寻找东西,那么我们就要杜绝相同名字的控件
今天自己的bug就是因为这个产生的


\


说到控件的命名,今天还有一个小发现

仔细看下边两段代码代码

[xml]
< ?xml version="1.0" encoding="utf-8"?> 
< LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/LinearLayout" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" > 
< /LinearLayout> 
[xml]
< ?xml version="1.0" encoding="utf-8"?> 
< LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" > 
< /LinearLayout> 
一段里边Layout没有id这个参数,一段里边有id,虽然代码不同但在outline中显示出来都是\


 

这样在第一种情况下R.id中可以找到LinearLayout这个控件,第二种是没有的哈,这些也是以后要注意的细节

2.在调用view中的findViewById()一定要想好父View是谁!即**view.findViewById()中的**view要找对,如果没有找对父View,返回基本都是null了

Android Studio 3.6中新的视图绑定工具ViewBinding 用法详解

Android Studio 3.6中新的视图绑定工具ViewBinding 用法详解

前言

我们在Android开发的过程中总是需要获取XML布局中的ViewId,以便给其赋值进行显示,早期我们只能使用 findViewById 这个API,会导致很多的模版代码出现。2013年左右Android界大神 Jake Wharton开源了Butter Knife框架,通过Bind("viewid")方式方便开发者获取ViewId。近两年由于谷歌对Kotlin的支持,我们开始使用 Android Kotlin extensions。 在文件中导入布局文件直接引用viewId。无需做其他额外操作,最为方便。

目前,谷歌在 Android Studio 3.6 Canary 11 及更高版本中加入了新的视图绑定工具 ViewBinding。

下面我们一起看下具体使用。

ViewBinding的使用

我们现在开发很多项目都是使用模块化来进行开发的。ViewBinding也是很机智的可以按照模块来启用。如果要在某个模块中启用ViewBinding,则需要在模块的build.gradle中添加如下配置即可:

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

如果在使用的过程中开发者不想为某个布局文件生成binding类,则可以使用如下属性添加到布局的根视图中即可:

<LinearLayout
  ...
  tools:viewBindingIgnore="true" > 
 ...
</LinearLayout>

当模块开启视图绑定功能后,系统会为该模块中的每一个XML文件生成对应的绑定类。每一个绑定类均包含对根视图以及定义了ID的所有视图的引用。

绑定类的名称生成规则是将XML文件的名称按照驼峰命名规则加上Binding进行结尾。

比如我们的 activity_main.xml文件。

<LinearLayout ... >
 <TextView android:id="@+id/name" />
 <ImageView android:cropToPadding="true" />
 <Button android:id="@+id/button"
  android:background="@drawable/rounded_button" />
</LinearLayout>

那么生产的绑定类名称为 ActivityMainBinding。此类具有两个字段:一个是名为 name 的 TextView,另一个是名为 button 的 Button。该布局中的 ImageView 没有 ID,因此绑定类中不存在对它的引用。

每个绑定类还包含一个 getRoot() 方法,提供为布局文件的根视图的直接引用。在此示例中,ActivityMainBinding 类中的 getRoot() 方法会返回 LinearLayout 根视图。

自动生成的绑定类也并不复杂,主要就是两个inflate重载方法以及一个bind方法。我们获取的对viewId引用就是在bind方法中进行的,内部其实也是通过findViewById来获取相关view的。

我们通常设置布局文件是通过setContentView("layoutId"),但是使用了ViewBinding后我们需要按照如下方式进行设置layout:

class MainActivity : AppCompatActivity() {
 
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
 
  val binding = ActivityMainBinding.inflate(layoutInflater)
  setContentView(binding.root)
  //获取name进行赋值
  binding.name.text = "viewBinding"
 }
}

这样就可以直接使用了。是不是很简单呢。

但是需要注意的是,如果我们的布局文件分为 layout和layout-land,我们我们在定义布局的时候可能会存在不同的viewId,如果是使用findViewById 或者 Butter Knife 那么肯定就异常了。

我们在使用 ViewBinding 的时候,绑定类贴心的为我们做了相关的判断。通过 @Nullable 和 @NonNull 两个注解来告诉开发者,哪些view可能为空。并在可能为空的view上添加了相关的注视说明。

/**
 * This binding is not available in all configurations.
 * <p>
 * Present:
 * <ul>
 * <li>layout/</li>
 * </ul>
 *
 * Absent:
 * <ul>
 * <li>layout-land/</li>
 * </ul>
 */
 @Nullable
 public final TextView mAppTv;

提醒开发者在使用的时候注意异常的处理。

总结

目前 ViewBinding 的功能还不够完善,比如XML中使用了 inClude 标签时无法对view进行引用。但总体来说已经很不错了。相比较于 findViewById 和 Butter Knife两种方式还是方便很多的。而且 ViewBinding 在使用的过程中不存在类型转换以及空指针异常的问题。因为在绑定类中已经全部定义好了。开发者直接使用就可以。和 Android Kotlin extensions 相比较我觉得都二者差不多。说不上谁更好。和databinding相比较就是数据绑定库仅处理使用 <layout> 代码创建的数据绑定布局。它具有局限性。

目前 Jake Wharton 也在 Butter Knife开源库中添加了如下一句话:

Attention: Development on this tool is winding down. Please consider switching to view binding in the coming months.

补充:与findViewById的区别

与使用findViewById相比,视图绑定具有重要的优势:
•空安全性:由于视图绑定会创建对视图的直接引用,因此不会因无效的视图ID而导致空指针异常的风险。 此外,当视图仅在布局的某些配置中存在时,在绑定类中包含其引用的字段将用@Nullable
•类型安全性:每个绑定类中的字段具有与其在XML文件中引用的视图匹配的类型。 这意味着没有类强制转换异常的风险。

这些差异意味着布局和代码之间的不兼容性将导致编译在编译时而不是在运行时失败。

与data binding 库的区别

视图绑定和数据绑定库都生成可用于直接引用视图的绑定类。 但是,有明显的区别:
•data binding库仅处理使用标记创建的数据绑定布局。
•view binding不支持布局变量或布局表达式,因此不能用于将布局与XML数据绑定。

到此这篇关于Android Studio 3.6中新的视图绑定工具ViewBinding 用法详解的文章就介绍到这了,更多相关android 视图绑定工具ViewBinding 使用内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

您可能感兴趣的文章:
  • Android使用ViewBinding的详细步骤(Kotlin简易版)
  • Android ViewBinding的使用详解
  • Android Studio3.6新特性之视图绑定ViewBinding使用指南
  • Android基础入门之dataBinding的简单使用教程
  • Android开发Jetpack组件DataBinding用例详解
  • Android DataBinding手把手入门教程
  • 在Android中如何使用DataBinding详解(Kotlin)
  • Android DataBinding的官方双向绑定示例
  • Android浅析viewBinding和DataBinding

Android Studio 之 DataBing ,不需要再一个个findViewById了

Android Studio 之 DataBing ,不需要再一个个findViewById了

使用DataBinding,不需要再一个个findViewById了

1.在 build.gradel 中 添加下面语句
dataBinding{
enabled true
}


2.在 activity_main.xml 文件中 点小灯炮,自动生成 data 结点

3.在 MainActivity.java 中能得到一个新的类, ActivityMainBinding(此类取Activity名称,这个类不是固定的) ActivityMainBinding binding

4.对 绑定的实例 进行绑定 binding = DataBindingUtil.setContentView(this,R.layout.activity_main);

5.然后在MainActivity.java 文件中,直接用 binding.控件名,进行访问控件,不需要再像之前一样,一个个定义控件变量了,也不需要一个个控件进行 findViewById() 了

6.之前的 setContentView(R.layout.activity_main); 这句方法也不需要写了,直接屏蔽掉

7.在 activity_main.xml 文件中,对控件进行数据回绑
<data>
<variable
name="data"
type="com.example.databinding.MyViewModel" />
</data>
在 <data> 结点中声明 数据变量,
在 textView 或 其他内容控件中,都可以使用 data 这个变量进行数据绑定
如:android:text="@{String.valueOf(data.number)}" 直接把 MyViewModel 中的 number 值绑定到控件上
android:onClick="@{()->data.add()}" 调用 MyViewModel 中的方法

 

1. ViewModel 类

package com.example.databinding;

import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class MyViewModel extends ViewModel {
    private MutableLiveData<Integer> number;
    public MutableLiveData<Integer> getNumber(){
        if(number==null)
        {
            number = new MutableLiveData<>();
            number.setValue(0);
        }
        return number;
    }

    public void add(){
        number.setValue(number.getValue()+1);
    }
}

  

2.MainActivity 类

package com.example.databinding;

import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.ViewModelProviders;

import com.example.databinding.databinding.ActivityMainBinding;


public class MainActivity extends AppCompatActivity {
    TextView textView;
    Button button;
    MyViewModel myViewModel;
    ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /*
        改造步骤:使用DataBinding
        1.在 build.gradel 中 添加下面语句
                  dataBinding{
                    enabled true
                }
        2.在 activity_main.xml 文件中 点小灯炮,自动生成 data 结点
        3.在 MainActivity.java 中能得到一个新的类, ActivityMainBinding(此类取Activity名称,这个类不是固定的)  ActivityMainBinding binding
        4.对 绑定的实例 进行绑定 binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        5.然后在MainActivity.java 文件中,直接用 binding.控件名,进行访问控件,不需要再像之前一样,一个个定义控件变量了,
          也不需要一个个控件进行 findViewById() 了
        6.之前的 setContentView(R.layout.activity_main); 这句方法也不需要写了,直接屏蔽掉
        7.在 activity_main.xml 文件中,对控件进行数据回绑
          <data>
                <variable
                    name="data"
                    type="com.example.databinding.MyViewModel" />
          </data>
          在 <data> 结点中声明 数据变量,
          在 textView 或 其他内容控件中,都可以使用 data 这个变量进行数据绑定
          如:android:text="@{String.valueOf(data.number)}"     直接把 MyViewModel 中的 number 值绑定到控件上
              android:onClick="@{()->data.add()}"               调用   MyViewModel 中的方法
         */

        //setContentView(R.layout.activity_main);
        binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        /*
        textView = findViewById(R.id.textView);
        button   = findViewById(R.id.button); */

        myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
        binding.setData(myViewModel);     //监听用它来替换了
        binding.setLifecycleOwner(this);  //这句不能少,否则数据不显示
        /*
        myViewModel.getNumber().observe(this, new Observer<Integer>() {
                    @Override
                    public void onChanged(Integer integer) {
                        binding.textView.setText(String.valueOf(integer));
                    }
                });


        binding.button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        myViewModel.add();
                    }
        });

         */


    }
}

  

Android Studio3.6新特性之视图绑定ViewBinding使用指南

Android Studio3.6新特性之视图绑定ViewBinding使用指南

View Binding是一项功能,使您可以更轻松地编写与视图交互的代码。在模块中启用视图绑定后,它将为该模块中存在的每个XML布局文件生成一个绑定类。绑定类的实例包含对在相应布局中具有ID的所有视图的直接引用。

正文

Android Studio 3.6 Canary 11 及更高版本中推出了ViewBinding功能,ViewBinding将逐步替换掉findViewById,还等什么,抓紧时间学习吧!
谷歌官方文档的ViewBinding Demo是用Kotlin语言写的,看起来比较生疏,花了点时间,我在Java上实现了类似的代码,还是看Java比较亲切!

下面简单介绍下如何使用ViewBinding:

修改build.gradle

将 viewBinding 元素添加到其 build.gradle 文件中,添加完后需要重新sync

// Android Studio 3.6.0
android {
 ...
 viewBinding {
  enabled = true
 }
 }

在 Android Studio 4.0 中,viewBinding 将被变成属性整合到了buildFeatures 选项中,配置要改成:

// Android Studio 4.0
android {
 buildFeatures {
 viewBinding = true
 }
}

修改java代码

如果你的布局文件是activity_main.xml,则会生成一个ActivityMainBinding的类,如果你的布局文件是result_profile.xml,则会生成一个ResultProfileBinding的类,以此类推。
下面以activity_main.xml及其对应的MainActivity.java为例说明:

假设activity_main.xml放置了三个控件:TextView(Id为text)、Button(Id为button)、ImageView(没有设置Id),其中ImageView因为没有设置Id,因此绑定类中不存在对它的引用,所以在代码中无法被引用。

MainActivity.java的部分代码如下:

@Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
 LayoutInflater layoutInflater = LayoutInflater.from(this);
 ActivityMainBinding binding = ActivityMainBinding.inflate(layoutInflater);
 setContentView(binding.getRoot());

 binding.text.setText("文字已变化");
 binding.button.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
  Toast.makeText(getApplicationContext(), "Button被点击", Toast.LENGTH_SHORT).show();
  }
 });
 }

注意事项

注意:原先的setContentView(R.layout.activity_main)需要注释掉,否则会重复设置ContentView。
布局的根视图(activity_main.xml)会自动生成一个名为 rootView 的成员变量。在 Activity 的 onCreate()方法中,要将 rootView传入 setContentView()方法,从而让 Activity 可以使用绑定对象中的布局,rootView是私有变量,需要使用getRoot()方法拿到。

工程代码

完整的工程欢迎到码云或Github上下载(ViewBindingTest目录):
https://gitee.com/lwjobs/AndroidStudy
https://github.com/lwjobs/AndroidStudy

视图绑定ViewBinding的详细说明请参考:

使用视图绑定替代 findViewById

总结

到此这篇关于Android Studio3.6新特性之视图绑定ViewBinding使用指南的文章就介绍到这了,更多相关android studio3.6 视图绑定ViewBinding内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

您可能感兴趣的文章:
  • Android使用ViewBinding的详细步骤(Kotlin简易版)
  • Android ViewBinding的使用详解
  • Android Studio 3.6中新的视图绑定工具ViewBinding 用法详解
  • Android基础入门之dataBinding的简单使用教程
  • Android开发Jetpack组件DataBinding用例详解
  • Android DataBinding手把手入门教程
  • 在Android中如何使用DataBinding详解(Kotlin)
  • Android DataBinding的官方双向绑定示例
  • Android浅析viewBinding和DataBinding

关于ViewBinding脱坑之路脱坑玩家的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于actvity.findViewById() 与 view.findViewById()、Android Studio 3.6中新的视图绑定工具ViewBinding 用法详解、Android Studio 之 DataBing ,不需要再一个个findViewById了、Android Studio3.6新特性之视图绑定ViewBinding使用指南等相关内容,可以在本站寻找。

本文标签: