View 编程(0): 认识 LayoutInflater

LayoutInflater详解
本文详细介绍了LayoutInflater在Android开发中的作用及使用方法。重点讲解了获取LayoutInflater实例的三种方式,并深入解析inflate方法的功能及其不同的重载形式。

LayoutInflater 在 android 开发中使用频率较高,需要留意!


该类是一个抽象类,在文档中如下声明:


public abstract class LayoutInflater extends Object


1.  获得 LayoutInflater 实例

三种方法可以获得该实例对象,方法如下:


a. LayoutInflater inflater = getLayoutInflater();


b. LayoutInflater localinflater =
  (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE); 


c. LayoutInflater inflater = LayoutInflater.from(context);


对于方法 a,主要是调用 Activity 的 getLayoutInflater() 方法。


继续跟踪研究 android 源码,Activity 中的该方法是调用 PhoneWindow 的 getLayoutInflater()方法!


那么,分享一下该源代码:


public PhoneWindow(Context context) {
        super(context);
        mLayoutInflater = LayoutInflater.from(context);


可以看出它其实是调用 LayoutInflater.from(context), 那么该方法其实是调用 b,看看源码,如下:


   /**
     * Obtains the LayoutInflater from the given context.
     */

    public static LayoutInflater from(Context context) {
        LayoutInflater LayoutInflater =
                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (LayoutInflater == null) {
            throw new AssertionError("LayoutInflater not found.");
        }
        return LayoutInflater;

    }


2. inflate 方法

inflate 愿意是充气之类的,在这里主要意思就是,扩张、使之膨胀。

换句话说就是将当前视图view 补充完整、扩展该视图。


通过 sdk 的 api 文档,可以知道该方法有以下几种过载形式,返回值均是 View 对象,如下:


public View inflate (int resource, ViewGroup root)

public View inflate (XmlPullParser parser, ViewGroup root)

public View inflate (XmlPullParser parser, ViewGroup root, boolean attachToRoot)

public View inflate (int resource, ViewGroup root, boolean attachToRoot)


示例代码:


LayoutInflater inflater = (LayoutInflater)
getSystemService(LAYOUT_INFLATER_SERVICE);


/* R.id.test 是 custom.xml 中根(root)布局 LinearLayout 的 id */
View view = inflater.inflate(R.layout.custom,

(ViewGroup)findViewById(R.id.test));


/* 通过该 view 实例化 EditText对象, 否则报错,因为当前视图不是custom.xml.

即没有 setContentView(R.layout.custom) 或者 addView() */

//EditText editText = (EditText)findViewById(R.id.content);// error

EditText editText = (EditText)view.findViewById(R.id.content);


对于上面代码,指定了第二个参数 ViewGroup root,当然你也可以设置为 null 值。


注意:该方法与 findViewById 方法不同。

inflater 是用来找 layout 下 xml 布局文件,并且实例化!

而 findViewById() 是找具体 xml 下的具体 widget 控件(如: Button,TextView 等)。



更多关于 inflate 方法,请看 LayoutInflater 源码。








<think> 我们有一个Kotlin函数声明需要解析。函数名为`addCardView`,它是一个泛型函数,带有类型参数`V`,该类型参数被限制为`ViewBinding`的子类型。 函数的参数列表如下: 1. `functionKey: FunctionKey` - 一个类型为`FunctionKey`的参数,可能用于标识该卡片视图的功能或类型。 2. `isLoad: Boolean` - 布尔值,表示是否加载该卡片视图。 3. `layoutType: LayoutType` - 布局类型,可能是一个枚举,指定卡片的布局方式。 4. `inflateBinding: (LayoutInflater, ViewGroup?, Boolean) -> V` - 一个lambda表达式,用于充气(inflate)视图绑定。它接受LayoutInflater、一个可空的ViewGroup和一个布尔值,并返回类型为`V`的视图绑定对象。 5. `cardViewDataBindCallback: (V) -> Unit` - 另一个lambda,用于数据绑定。它接受一个类型为`V`的视图绑定对象,并不返回任何值(Unit)。 函数返回一个`RootLayerBuilder`对象,这表明该函数可能是构建界面的一部分,用于添加一个卡片视图,并返回构建器本身以支持链式调用。 功能分析: 这个函数的作用可能是向某个界面构建器(RootLayerBuilder)添加一个卡片视图。它允许调用者提供两个关键lambda: - `inflateBinding`:用于创建视图绑定(ViewBinding)实例,这是Android中用于替代findViewById的一种方式,可以类型安全地访问视图。 - `cardViewDataBindCallback`:在视图绑定创建后,用于将数据绑定到视图上。 使用场景: 在Android应用开发中,特别是在使用视图绑定(ViewBinding)和自定义布局构建时,此函数可以用于动态添加卡片式的视图。例如,在一个可定制的仪表盘或卡片列表中,每个卡片可能有不同的布局和数据。 由于该函数返回`RootLayerBuilder`,它可能属于一个构建器模式(Builder Pattern)的实现,允许通过链式调用添加多个视图。 代码示例(假设的调用方式): 假设我们有一个布局文件`card_item.xml`,它生成了对应的视图绑定类`CardItemBinding`。我们可以这样调用: ```kotlin rootLayerBuilder.addCardView( functionKey = FunctionKey.CARD_1, isLoad = true, layoutType = LayoutType.VERTICAL, inflateBinding = { layoutInflater, parent, attachToParent -> CardItemBinding.inflate(layoutInflater, parent, attachToParent) }, cardViewDataBindCallback = { binding: CardItemBinding -> // 在这里进行数据绑定,例如: binding.title.text = "卡片标题" binding.icon.setImageResource(R.drawable.icon) } ) ``` 在这个例子中,我们传递了充气绑定的lambda(使用自动生成的`CardItemBinding`的inflate方法)和一个数据绑定的lambda(设置标题和图标)。 注意事项: - 该函数使用了Kotlin的高阶函数(以函数作为参数),这提供了灵活性,允许调用者自定义如何充气布局和绑定数据。 - 类型参数`V: ViewBinding`确保了传入的绑定类型是`ViewBinding`的子类,从而保证了类型安全。 因此,这个函数是一个用于动态添加卡片视图的构建工具,它封装了视图的创建和数据绑定的过程,使得添加卡片视图变得简洁和可配置。 </think>### Kotlin函数解析:`addCardView` #### 1. **函数定义** ```kotlin fun <V: ViewBinding> addCardView( functionKey: FunctionKey, isLoad: Boolean, layoutType: LayoutType, inflateBinding: (LayoutInflater, ViewGroup?, Boolean) -> V, cardViewDataBindCallback: (V) -> Unit ): RootLayerBuilder ``` #### 2. **核心功能** 这是一个**动态添加卡片视图的构建器函数**,用于在Android界面中灵活创建和配置卡片式UI组件。核心能力包括: - 通过泛型 `ViewBinding` 实现类型安全的视图绑定 - 分离视图创建(`inflateBinding`)和数据绑定(`cardViewDataBindCallback`) - 返回构建器实例支持链式调用 #### 3. **参数详解** | 参数名 | 类型 | 作用 | |-------------------------|----------------------------------------------------------------------|----------------------------------------------------------------------| | `functionKey` | `FunctionKey` | 标识卡片功能的唯一键(如`HomeCard`/`ProfileCard`) | | `isLoad` | `Boolean` | 控制卡片初始加载状态(`true`=立即加载,`false`=延迟加载) | | `layoutType` | `LayoutType` | 卡片布局类型(如`Linear`/`Grid`/`Staggered`) | | `inflateBinding` | `(LayoutInflater, ViewGroup?, Boolean) -> V` | **视图创建**:通过LayoutInflater生成ViewBinding实例 | | `cardViewDataBindCallback` | `(V) -> Unit` | **数据绑定**:获取ViewBinding实例后填充数据 | #### 4. **使用场景** 1. **动态界面构建** 适合需要运行时动态生成卡片的场景: ```kotlin buildDashboard().apply { addCardView(FunctionKey.NEWS, true, LayoutType.LINEAR, ::NewsBinding.inflate) { binding -> binding.title = "今日热点" binding.newsList = fetchNews() } addCardView(FunctionKey.WEATHER, false, LayoutType.GRID, ::WeatherBinding.inflate) { ... } } ``` 2. **多布局类型支持** 通过`LayoutType`枚举实现不同布局适配: ```kotlin enum class LayoutType { LINEAR, GRID, STAGGERED } // 示例定义 ``` 3. **延迟加载优化** 利用`isLoad`控制资源加载时机: ```kotlin // 首屏立即加载,次级屏延迟加载 addCardView(KEY_MAIN, true, ...) addCardView(KEY_SECONDARY, false, ...) ``` #### 5. **技术优势** - **类型安全**:泛型`V: ViewBinding`确保编译时检查 - **逻辑解耦**:分离视图创建与数据绑定(符合MVVM原则) - **链式构建**:返回`RootLayerBuilder`支持流畅API设计 - **资源优化**:通过`isLoad`实现按需加载 #### 6. **完整调用示例** ```kotlin class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) RootLayerBuilder(container).apply { addCardView( functionKey = FunctionKey.USER_CARD, isLoad = true, layoutType = LayoutType.CARD, inflateBinding = { inflater, parent, attach -> ItemUserBinding.inflate(inflater, parent, attach) }, cardViewDataBindCallback = { binding -> binding.userName = "张小明" binding.avatar = loadAvatar() binding.setOnClickListener { showProfile() } } ).build() } } } ``` ###
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值