当前位置: 首页> 房产> 家装 > 葆婴保健品_公司简介模板文字版_西安seo建站_网页制作接单平台

葆婴保健品_公司简介模板文字版_西安seo建站_网页制作接单平台

时间:2025/7/8 21:41:46来源:https://blog.csdn.net/2301_78494721/article/details/148944916 浏览次数:0次
葆婴保健品_公司简介模板文字版_西安seo建站_网页制作接单平台

前置条件:在一个activity的布局文件中,我们通过设置一个按钮,分别通过三种方式获取,并说明各自优缺点

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> //新增的Button元素按钮<Button android:id="@+id/button1" //定义idandroid:layout_width="match_parent" //宽度和父元素一样宽android:layout_height="wrap_content" //高度自适应android:text="Button 1" /> </LinearLayout>

1.findViewById详解

        安卓开发中,activity获取xml文件中控件,最开始的方法是findViewById,那么它是如何去实现查找并绑定视图ID的。下面我们详细介绍

首先,findViewById的使用方法:

//Java代码
public class MainActivity extends AppCompatActivity {private TextView textView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 手动查找并转换类型textView = findViewById(R.id.textView);textView.setText("Hello Java!");}
}
//kotlin代码
class MainActivity : AppCompatActivity() {private lateinit var textView: TextViewoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 手动查找并转换类型textView = findViewById(R.id.textView)textView.text = "Hello Kotlin!"}
}

那么其内部是如何实现

        手机布局其实就像一个一个树状图,

  • 树根:整个屏幕的最外层布局(如 DecorView
  • 树枝:有子布局的容器(如 LinearLayoutRelativeLayout 等 ViewGroup
  • 树叶:没有子布局的单个控件(如 TextViewButton 等 View

        每个节点(View/ViewGroup)都有一个唯一的 ID。

总结查找过程:其就是先从树根(屏幕布局DecorView)开始查找,然后遍历树枝,检查当前树枝节点ID是否匹配,如果匹配直接返回,如果当前布局不匹配且含有子布局(即是ViewGroup),则递归检查其所有的子布局。如果没有子布局,则对比ID,匹配返回,不匹配则返回null或检查下一个。

核心方法:ViewGroup中的findViewTraversal()方法,是通过递归的方式从树根部,再到树枝-再到树叶,逐个查找,直到找到为止。

全局查找,从 DecorView 开始遍历整个视图树,时间复杂度为 O(n)(n 为视图总数)。

注意缺陷

  • 代码冗余:每个控件都需手动调用 findViewById
  • 类型不安全:若类型转换错误(如将 TextView 转为 Button),运行时会抛出 ClassCastException
  • 空指针风险:若 ID 不存在,返回 null(Java)或 NullPointerException(Kotlin)。
  • 性能开销:每次访问控件都需遍历视图树,影响性能。

实现代码:

// ViewGroup.java
@Override
protected View findViewTraversal(int id) {// 先检查自身if (id == mID) {return this;}// 遍历子 Viewfinal View[] children = mChildren;for (int i = 0; i < childrenCount; i++) {View child = children[i];if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {// 递归查找子 ViewView v = child.findViewTraversal(id);if (v != null) {return v; // 找到即返回,终止递归}}}return null; // 未找到
}// View.java
public View findViewById(int id) {if (id == mID) {return this;}return null; // View 没有子 View,直接返回
}

2.kotlin-android-extensions详解(注意,已废弃)

Kotlin Android Extensions 于 2016 年随 Kotlin 1.0 版本推出,作为官方解决方案,旨在提供更简洁、高效的视图绑定方式。

其核心功能:Kotlin Android Extensions 的核心是 合成属性(Synthetic Properties),它允许开发者直接通过布局文件中的 ID 访问视图,无需显式绑定:

1.使用方法:

        添加依赖:

plugins {id 'kotlin-android-extensions'
}

        直接引入空间ID

//kotlin代码
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 直接使用布局文件中的 IDtextView.text = "Hello Extensions!"// 设置点击事件button.setOnClickListener { /* ... */ }}
}

那么它是如何实现的呢?下面我们详细介绍

详解:这个插件呢其实是一个编译时插件,它的工作流程如下:

        

  1. 编译时处理:在编译阶段,插件分析布局文件(.xml),生成对应的访问器代码。
  2. 合成属性生成:为每个布局文件生成一个 Kotlin 文件(如 R.layout.activity_main 对应生成 ActivityMainKt),其中包含布局中所有视图 ID 的属性访问器。
  3. 运行时优化:访问合成属性时,插件会缓存首次查找的视图实例,避免重复调用 findViewById,提升性能。

整体来说,其不仅简化代码,高效快捷,合成属性的类型由视图文件自动推断还能保证类型安全,那么为什么废弃呢。主要是其缺陷

  • 性能隐患:虽然缓存机制避免了重复 findViewById,但首次访问仍需反射查找,在频繁创建视图的场景下(如 RecyclerView)可能影响性能。
  • 布局依赖:合成属性与布局文件强绑定,若布局文件修改但代码未同步更新,可能导致运行时异常。
  • IDE 支持有限:在复杂场景下(如动态加载布局),IDE 可能无法正确提示合成属性。

3.ViewBinding详解

Android 团队于 2019 年 Android Gradle Plugin 3.6 版本引入了 View Binding。主要是这些方案均存在不同程度的缺陷,尤其是在大型项目中维护成本高。为解决这些问题,引入ViewBinding

使用方法:

1.在 build.gradle 中启用 View Binding

android {viewBinding {enabled = true}
}

若需排除特定布局文件,可在布局文件中添加 tools:viewBindingIgnore="true"

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"tools:viewBindingIgnore="true"><!-- ... -->
</LinearLayout>

2.在Activity中使用

class MainActivity : AppCompatActivity() {private lateinit var binding: ActivityMainBindingoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)binding.button.setOnClickListener { /* ... */ }}
}

3.在fragment中使用

class MyFragment : Fragment(R.layout.fragment_my) {private var _binding: FragmentMyBinding? = nullprivate val binding get() = _binding!!override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)_binding = FragmentMyBinding.bind(view)binding.textView.text = "Hello from Fragment"}override fun onDestroyView() {super.onDestroyView()_binding = null // 防止内存泄漏}
}

4.RecyclerView Adapter使用

class MyAdapter : RecyclerView.Adapter<MyAdapter.ViewHolder>() {class ViewHolder(private val binding: ItemMyBinding) : RecyclerView.ViewHolder(binding.root) {fun bind(item: MyItem) {binding.textView.text = item.name}}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {val binding = ItemMyBinding.inflate(LayoutInflater.from(parent.context), parent, false)return ViewHolder(binding)}override fun onBindViewHolder(holder: ViewHolder, position: Int) {holder.bind(items[position])}
}

在设计ViewBinding时,它的初衷就是

  • 类型安全:编译时验证视图 ID 是否存在,避免运行时 NullPointerException
  • 性能优化:直接访问视图引用,无需反射或缓存,提升运行效率。
  • 零配置:无需编写注解或额外代码,自动生成绑定类。
  • 兼容性:支持与 Data Binding、Kotlin Android Extensions 共存。

那么其工作原理:通过 编译时生成绑定类 实现视图访问。对于每个布局文件(如 activity_main.xml),系统会自动生成对应的绑定类(如 ActivityMainBinding)。该类包含:布局中所有具有 ID 的视图的直接引用。根视图的引用。创建绑定实例的静态方法

与 Kotlin Android Extensions 的对比

特性Kotlin Android ExtensionsView Binding
类型安全部分支持(布局修改可能导致运行时崩溃)完全支持(编译时验证)
性能首次访问需反射,后续缓存直接访问,无反射
布局依赖强依赖(布局修改需同步代码)弱依赖(绑定类自动更新)
空安全不支持(可能返回 null)支持(非空类型或可空类型)
IDE 支持有限(动态布局提示不足)完善(自动补全、类型提示)
数据绑定支持不支持支持(与 Data Binding 集成)
Fragment/RecyclerView需要额外处理生命周期内置生命周期管理
关键字:葆婴保健品_公司简介模板文字版_西安seo建站_网页制作接单平台

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: