Layout inflation is the term used within the context of Android to indicate when an XML layout resou

本文详细解释了在Android开发中如何正确使用LayoutInflater来解析和转换XML布局资源。通过对比正确的和错误的inflate方法调用方式,文章强调了传递正确ViewGroup的重要性。

Layout inflation is the term used within the context of Android to indicate when an XML layout resource is parsed and converted into a hierarchy of View objects.

It’s common practice in the Android SDK, but you may be surprised to find that there is a wrong way to use LayoutInflater, and your application might be one of the offenders. If you’ve ever written something like the following code using LayoutInflater in your Android application:

inflater.inflate(R.layout.my_layout, null );

PLEASE read on, because you’re doing it wrong and I want to explain to you why.

Get to Know LayoutInflater

Let’s first take a look at how LayoutInflater works. There are two usable versions of the inflate() method for a standard application:

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

The first parameter points to the layout resource you want to inflate. The second parameter is the root view of the hierarchy you are inflating the resource to attach to. When the third parameter is present, it governs whether or not the inflated view is attached to the supplied root after inflation.

It is these last two parameters that can cause a bit of confusion. With the two parameter version of this method, LayoutInflater will automatically attempt to attach the inflated view to the supplied root. However, the framework has a check in place that if you pass null for the root it bypasses this attempt to avoid an application crash.

Many developers take this behavior to mean that the proper way to disable attachment on inflation is by passing null as root; in many cases not even realizing that the three parameter version of inflate() exists. By doing things this way, we also disable another very important function the root view has…but I’m getting ahead of myself.

Examples from the Framework

Let’s examine some situations in Android where the framework expects you as a developer to interactively inflate portions of the view.

Adapters are the most common case for using LayoutInflater is custom ListView adapters overriding getView(), which has the following method signature:

getView( int position, View convertView, ViewGroup parent)

Fragments also use inflation often when creating views via onCreateView(); notice its method signature:

onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)

Have you noticed that every time the framework wants you to inflate a layout, they also pass you the parent ViewGroup it will eventually be attached to? Notice also that in most cases (including the above two examples), it will throw an Exception later on if LayoutInflater is allowed to automatically attach the inflated view to the root.

So why do you suppose we are given this ViewGroup if we are not supposed to attach to it? It turns out the parent view is a very important part of the inflation process because it is necessary in order to evaluate the LayoutParams declared in the root element of the XML being inflated. Passing nothing here is akin to telling the framework “I don’t know what parent this view will be attached to, sorry.”

The problem with this is android:layout_xxx attributes are always be evaluated in the context of the parent view. As a result, without any known parent, all LayoutParams you declared on the root element of your XML tree will just get thrown away, and then you’ll be left asking “why is the framework ignoring the layout customizations I defined? I’d better check SO and then file a bug.”

Without LayoutParams, the ViewGroup that eventually hosts the inflated layout is left to generate a default set for you. If you are lucky (and in many cases you are) these default parameters are the same as what you had in XML…masking the fact that something is amiss.

Application Example

So you claim you’ve never seen this happen in an application? Take the following simple layout that we want to inflate for a ListView row:

R.layout.item_row

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
     android:layout_width = "match_parent"
     android:layout_height = "?android:attr/listPreferredItemHeight"
     android:gravity = "center_vertical"
     android:orientation = "horizontal" >
     < TextView
         android:id = "@+id/text1"
         android:layout_width = "wrap_content"
         android:layout_height = "wrap_content"
         android:paddingRight = "15dp"
         android:text = "Text1" />
     < TextView
         android:id = "@+id/text2"
         android:layout_width = "0dp"
         android:layout_height = "wrap_content"
         android:layout_weight = "1"
         android:text = "Text2" />
</ LinearLayout >

We want to set the height of our row to be a fixed height, in this case the preferred item height for the current theme…seems reasonable.

However, when we inflate this layout the wrong way

1
2
3
4
5
6
7
public View getView( int position, View convertView, ViewGroup parent) {
     if (convertView == null ) {
         convertView = inflate(R.layout.item_row, null );
     }
 
     return convertView;
}

we end up with a result that looks like this

What happened to the fixed height we set?? This is usually where you end up setting the fixed height on all your child views, switching the root elements height to wrap_content, and move on without really knowing why it broke (you may have even cursed at Google in the process).

If we instead inflate the same layout this way

1
2
3
4
5
6
7
public View getView( int position, View convertView, ViewGroup parent) {
     if (convertView == null ) {
         convertView = inflate(R.layout.item_row, parent, false );
     }
 
     return convertView;
}

we end up with what we expected in the first place.

Hooray!

Every Rule Has An Exception

There are of course instances where you can truly justify a null parent during inflation, but they are few. One such instance occurs when you are inflating a custom layout to be attached to an AlertDialog. Consider the following example where we want to use our same XML layout but set it as the dialog view:

1
2
3
4
5
6
7
AlertDialog.Builder builder = new AlertDialog.Builder(context);
View content = LayoutInflater.from(context).inflate(R.layout.item_row, null );
 
builder.setTitle( "My Dialog" );
builder.setView(content);
builder.setPositiveButton( "OK" , null );
builder.show();

The issue here is that AlertDialog.Builder supports a custom view, but does not provide an implementation of setView() that takes a layout resource; so you must inflate the XML manually. However, because the result will go into the dialog, which does not expose its root view (in fact, it doesn’t exist yet), we do not have access to the eventual parent of the layout, so we cannot use it for inflation. It turns out, this is irrelevant, because AlertDialog will erase any LayoutParams on the layout anyway and replace them with match_parent.

So the next time your fingers are tempted to just type null into inflate(), you should stop and ask yourself “do I really not know where this view will end up?”

Bottom line, you should think of the two parameter version of inflate() as a convenience shortcut to omit true as the third paramter. You should not think of passing null as a convenience shortcut to omit false.

For future insights, please subscribe to our email list at the bottom of the page (below the comments)!




转载自:http://www.doubleencore.com/2013/05/layout-inflation-as-intended/

<think>嗯,用户遇到了Fluent中的警告信息“region based printout is limited to 25 cell zones”,需要解决这个问题以及使用诊断工具定位质量问题的办法。首先,我得回忆一下这个警告的原因。Fluent的区域打印功能可能确实有单元格区域数量的限制,超过25个就会触发警告。用户可能需要检查他们的模型是否划分了过多的cell zones,比如在复杂的几何体划分时可能不小心生成了太多的小区域。 接下来,解决方案可能包括合并不必要的cell zones。我需要确认在Fluent中如何合并这些区域,比如在Mesh Interfaces或者通过合并相同材料或边界类型的区域。另外,用户可能需要简化模型,比如将一些不影响分析的细小区域删除或合并,以减少cell zones的数量。 然后是诊断质量问题的部分。Fluent的Mesh Quality工具应该能提供帮助,检查扭曲度、长宽比等指标。TUI命令mesh/check可能可以快速发现问题区域。此外,使用报告工具生成统计信息,找出质量差的区域,然后通过调整网格划分参数,比如尺寸函数或局部加密,来优化网格质量。 用户可能不太清楚具体操作步骤,所以需要给出明确的步骤,比如在哪里找到Mesh Quality工具,如何执行TUI命令,以及如何调整网格参数。同时,引用官方文档或常见解决方案作为参考,比如提到Fluent用户手册中的相关章节或者技术支持建议,能增加回答的可信度。 还要考虑用户是否有其他潜在需求,例如如何预防此类问题再次发生,或者在网格划分时的最佳实践。可能需要建议用户在划分网格前合理规划区域,避免不必要的细分,使用合适的网格划分策略,如分块网格或扫掠网格,以减少cell zones的数量。 最后,生成的相关问题需要覆盖用户可能进一步询问的内容,比如如何合并cell zones的具体步骤,或者如何解读网格质量报告中的各项指标,以及常见的网格优化技巧有哪些。确保这些问题能够帮助用户深入理解并彻底解决问题。</think>### Fluent警告“region based printout is limited to 25 cell zones”的解决方案 #### 问题分析 当Fluent提示`region based printout is limited to 25 cell zones`时,表明模型中定义的**单元格区域(Cell Zones)数量超过了25个**。此限制会影响区域相关输出(如残差监测、后处理等)的准确性,通常由以下原因导致: 1. **网格划分复杂**:几何体被分割为过多独立区域; 2. **重复导入网格**:多次合并网格文件导致区域冗余; 3. **自动分区错误**:并行计算时自动分区生成过多临时区域。 #### 解决步骤 1. **合并冗余Cell Zones** - 在Fluent界面中,通过`Mesh Interfaces`或`Boundary Conditions`合并相同材料或边界类型的区域。 - 使用TUI命令快速合并: ```text /mesh/modify-zones/merge-zones ``` 按提示选择需合并的区域[^1]。 2. **简化模型复杂度** - 删除不影响分析的细小区域(如螺栓孔、倒角等); - 使用`Group`功能将同类区域归类为同一组(需在ANSYS Meshing或SCDM中预先定义)。 3. **检查网格划分策略** - 避免过度细分几何体,优先使用**扫掠网格(Sweep)**或**多区域划分(Multizone)**; - 在ANSYS Meshing中启用`Merge Topology`功能,减少自动生成的区域数量。 #### 诊断质量问题的工具 1. **Mesh Quality工具** - 路径:`General → Mesh → Check` 检查扭曲度(Skewness)、长宽比(Aspect Ratio)等关键指标,阈值建议: $$ \text{Skewness} < 0.95,\quad \text{Aspect Ratio} < 100 $$ - 使用TUI命令快速定位问题区域: ```text mesh/check improve-quality ``` 2. **报告工具(Report Tools)** - 生成区域统计:`Reports → Zones → Cell Zones`,筛选体积过小或节点数异常的区域; - 通过`Surface Integrals`计算特定物理量(如压力梯度)的突变,定位网格质量问题[^2]。 3. **调整网格参数** - 在问题区域应用局部加密:`Mesh → Local Sizing`; - 使用`Inflation Layer`优化边界层网格,避免过度拉伸。 #### 示例代码(TUI命令) ```text ; 合并区域示例 /mesh/modify-zones/merge-zones yes ; 确认操作 1-5 ; 合并前5个区域 ``` ```text ; 检查网格质量 mesh/check improve-quality ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值