<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>润物无声 &#187; Layout</title>
	<atom:link href="http://blog.zhourunsheng.com/tag/layout/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.zhourunsheng.com</link>
	<description>天空一朵雨做的云</description>
	<lastBuildDate>Sat, 08 May 2021 05:17:21 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.41</generator>
	<item>
		<title>Android开发之布局加载LayoutInflater</title>
		<link>http://blog.zhourunsheng.com/2013/08/android%e5%bc%80%e5%8f%91%e4%b9%8b%e5%b8%83%e5%b1%80%e5%8a%a0%e8%bd%bdlayoutinflater/</link>
		<comments>http://blog.zhourunsheng.com/2013/08/android%e5%bc%80%e5%8f%91%e4%b9%8b%e5%b8%83%e5%b1%80%e5%8a%a0%e8%bd%bdlayoutinflater/#comments</comments>
		<pubDate>Sun, 04 Aug 2013 10:11:45 +0000</pubDate>
		<dc:creator><![CDATA[润物无声]]></dc:creator>
				<category><![CDATA[移动开发]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Layout]]></category>

		<guid isPermaLink="false">http://blog.zhourunsheng.com/?p=1715</guid>
		<description><![CDATA[<p>在开发Android的过程中，涉及到list view什么的，应该经常会碰到加载layout的状况，那么平时使 [&#8230;]</p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2013/08/android%e5%bc%80%e5%8f%91%e4%b9%8b%e5%b8%83%e5%b1%80%e5%8a%a0%e8%bd%bdlayoutinflater/">Android开发之布局加载LayoutInflater</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></description>
				<content:encoded><![CDATA[<p>在开发Android的过程中，涉及到list view什么的，应该经常会碰到加载layout的状况，那么平时使用inflate函数的时候，经常是怎么传递参数的？在不同的场合，比如list view的adapter中加载layout与在自定义Dialog中加载Layout，它们有没有特殊区别的地方，本文就会介绍inflate函数的正确使用方法，请学习一下。</p>
<div>
<h3>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.</h3>
</div>
<div>
<p>It’s common practice in the Android SDK, but you may be surprised to find that there is a wrong way to use<em>LayoutInflater</em>, and your application might be one of the offenders. If you’ve ever written something like the following code using <em>LayoutInflater</em> in your Android application:</p>
<div>
<pre>inflater.inflate(R.layout.my_layout, null);</pre>
</div>
<p>PLEASE read on, because you’re doing it wrong and I want to explain to you why.<span id="more-1715"></span></p>
<h3>Get to Know LayoutInflater</h3>
<p>Let’s first take a look at how <em>LayoutInflater</em> works. There are two usable versions of the <em>inflate()</em> method for a standard application:</p>
<div>
<pre>inflate(int resource, ViewGroup root)</pre>
</div>
<div>
<pre>inflate(int resource, ViewGroup root, boolean attachToRoot)</pre>
</div>
<p>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.</p>
<p>It is these last two parameters that can cause a bit of confusion. With the two parameter version of this method, <em>LayoutInflater</em> will automatically attempt to attach the inflated view to the supplied root. However, the framework has a check in place that if you pass <em>null</em> for the root it bypasses this attempt to avoid an application crash.</p>
<p>Many developers take this behavior to mean that the proper way to disable attachment on inflation is by passing <em>null</em> as root; in many cases not even realizing that the three parameter version of <em>inflate()</em> exists. By doing things this way, we also disable another very important function the root view has…but I’m getting ahead of myself.</p>
<h3>Examples from the Framework</h3>
<p>Let’s examine some situations in Android where the framework expects you as a developer to interactively inflate portions of the view.</p>
<p><strong>Adapters</strong> are the most common case for using LayoutInflater is custom ListView adapters overriding<em>getView()</em>, which has the following method signature:</p>
<div>
<pre>getView(int position, View convertView, ViewGroup parent)</pre>
</div>
<p><strong>Fragments</strong> also use inflation often when creating views via <em>onCreateView()</em>; notice its method signature:</p>
<div>
<pre>onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)</pre>
</div>
<p>Have you noticed that every time the framework wants you to inflate a layout, they also pass you the parent<em>ViewGroup</em> 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 <em>LayoutInflater</em> is allowed to automatically attach the inflated view to the root.</p>
<p>So why do you suppose we are given this <em>ViewGroup</em> 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<em>LayoutParams</em> 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.”</p>
<p>The problem with this is <em>android:layout_xxx</em> attributes are always be evaluated in the context of the parent view. <strong>As a result, without any known parent, all <strong><em>LayoutParams</em></strong> you declared on the root element of your XML tree will just get thrown away</strong>, 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.”</p>
<p>Without LayoutParams, the <em>ViewGroup</em> 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.</p>
<h3>Application Example</h3>
<p>So you claim you’ve never seen this happen in an application? Take the following simple layout that we want to inflate for a <em>ListView</em> row:</p>
<p><strong>R.layout.item_row</strong></p>
<div>
<pre>&lt;LinearLayout xmlns:android="&lt;a href="http://schemas.android.com/apk/res/android"&gt;http://schemas.android.com/apk/res/android&lt;/a&gt;"
    android:layout_width="match_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:orientation="horizontal"&gt;
    &lt;TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingRight="15dp"
        android:text="Text1" /&gt;
    &lt;TextView
        android:id="@+id/text2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Text2" /&gt;
&lt;/LinearLayout&gt;</pre>
</div>
<p>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.</p>
<p>However, when we inflate this layout the wrong way</p>
<div>
<pre>public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = inflate(R.layout.item_row, null);
    }

    return convertView;
}</pre>
</div>
<p>we end up with a result that looks like this</p>
<p><a href="http://www.doubleencore.com/2013/05/layout-inflation-as-intended/image1-2/" rel="attachment wp-att-3597"><img title="Image1" alt="" src="http://www.doubleencore.com/wp-content/uploads/2013/05/Image11-300x187.png" width="300" height="187" /></a></p>
<p>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 <em>wrap_content</em>, and move on without really knowing why it broke (you may have even cursed at Google in the process).</p>
<p>If we instead inflate the same layout this way</p>
<div>
<pre>public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = inflate(R.layout.item_row, parent, false);
    }

    return convertView;
}</pre>
</div>
<p>we end up with what we expected in the first place.</p>
<p><a href="http://www.doubleencore.com/2013/05/layout-inflation-as-intended/image2-2/" rel="attachment wp-att-3598"><img title="Image2" alt="" src="http://www.doubleencore.com/wp-content/uploads/2013/05/Image21-300x187.png" width="300" height="187" /></a></p>
<p>Hooray!</p>
<h3>Every Rule Has An Exception</h3>
<p>There are of course instances where you can truly justify a <em>null</em> parent during inflation, but they are few. One such instance occurs when you are inflating a custom layout to be attached to an <em>AlertDialog</em>. Consider the following example where we want to use our same XML layout but set it as the dialog view:</p>
<div>
<pre>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();</pre>
</div>
<p>The issue here is that <em>AlertDialog.Builder</em> supports a custom view, but does not provide an implementation of<em>setView()</em> 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<em>AlertDialog</em> will erase any <em>LayoutParams</em> on the layout anyway and replace them with <em>match_parent</em>.</p>
<p>So the next time your fingers are tempted to just type <em>null</em> into <em>inflate()</em>, you should stop and ask yourself “do I really not know where this view will end up?”</p>
<p>Bottom line, you should think of the two parameter version of <em>inflate()</em> as a convenience shortcut to omit true as the third paramter. You should not think of passing <em>null</em> as a convenience shortcut to omit false.</p>
</div>
<p>文章选自：<a href="http://www.doubleencore.com/2013/05/layout-inflation-as-intended/">layout-inflation-as-intended</a></p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2013/08/android%e5%bc%80%e5%8f%91%e4%b9%8b%e5%b8%83%e5%b1%80%e5%8a%a0%e8%bd%bdlayoutinflater/">Android开发之布局加载LayoutInflater</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zhourunsheng.com/2013/08/android%e5%bc%80%e5%8f%91%e4%b9%8b%e5%b8%83%e5%b1%80%e5%8a%a0%e8%bd%bdlayoutinflater/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
