<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_谦虚的天下</title><subtitle type="text">深入探索android,多总结,多创新... ...</subtitle><id>http://feed.cnblogs.com/blog/u/35328/rss</id><updated>2012-01-01T15:45:24Z</updated><author><name>谦虚的天下</name><uri>http://www.cnblogs.com/qianxudetianxia/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/qianxudetianxia/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/35328/rss"/><entry><id>http://www.cnblogs.com/qianxudetianxia/archive/2012/01/01/2309102.html</id><title type="text">Android学习系列(24)--App代码规范之使用CheckStyle</title><summary type="text">最近经常思考团队开发的一些东西，其中代码风格不统一是最常见的问题之一。按理说，大家协商和沟通一下，风格统一一下就可以了，其实不然，因为这是个个性张扬的时代！工作code review中用了CheckStyle小半年了，觉得很好很强大很方便，使用起来也很方便，大家写出来的代码就像一个人写出来的一样，值此辞旧迎新，特简做说明，与尔同飨。1.简介官方网站：http://checkstyle.sourceforge.net/CheckStyle提供了一个帮助JAVA开发人员遵守某些编码规范的工具。它能够自动化代码规范检查过程，从而使得开发人员从这项重要，但是枯燥的任务中解脱出来。CheckStyle检</summary><published>2012-01-01T15:45:00Z</published><updated>2012-01-01T15:45:00Z</updated><author><name>谦虚的天下</name><uri>http://www.cnblogs.com/qianxudetianxia/</uri></author><link rel="alternate" href="http://www.cnblogs.com/qianxudetianxia/archive/2012/01/01/2309102.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/qianxudetianxia/archive/2012/01/01/2309102.html"/><content type="html">&lt;p&gt;最近经常思考团队开发的一些东西，其中代码风格不统一是最常见的问题之一。按理说，大家协商和沟通一下，风格统一一下就可以了，其实不然，因为这是个个性张扬的时代！&lt;br /&gt;工作code review中用了CheckStyle小半年了，觉得很好很强大很方便，使用起来也很方便，大家写出来的代码就像一个人写出来的一样，值此辞旧迎新，特简做说明，与尔同飨。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.简介&lt;/strong&gt;&lt;br /&gt;官方网站：&lt;a href="http://checkstyle.sourceforge.net/"&gt;http://checkstyle.sourceforge.net/&lt;br /&gt;&lt;/a&gt;&lt;span&gt;CheckStyle提供了一个帮助JAVA开发人员遵守某些编码规范的工具。它能够自动化代码规范检查过程，从而使得开发人员从这项重要，但是枯燥的任务中解脱出来。&lt;br /&gt;&lt;/span&gt;CheckStyle检验的主要内容&lt;br /&gt;(1). Javadoc注释&lt;br /&gt;(2).&amp;nbsp;命名约定&lt;br /&gt;(3).&amp;nbsp;标题&lt;br /&gt;(4).&amp;nbsp;Import语句&lt;br /&gt;(5).&amp;nbsp;体积大小&lt;br /&gt;(6).&amp;nbsp;空白&lt;br /&gt;(7).&amp;nbsp;修饰符&lt;br /&gt;(8).&amp;nbsp;块&lt;br /&gt;(9).&amp;nbsp;代码问题&lt;br /&gt;(10).&amp;nbsp;类设计&lt;br /&gt;(11).&amp;nbsp;混合检查（包活一些有用的比如非必须的System.out和printstackTrace）&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.定制&lt;/strong&gt;&lt;br /&gt;官方提供的代码规范往往太过严格，在工作中使用不太现实，所以有必要根据具体情况来定制具体的代码规范，CheckStyle对代码规范的定制提供了很多大灵活性。&lt;br /&gt;下面我们来定义一些基本的规范，后续有增加我们再修改。&lt;br /&gt;(1). 不要tab键;&lt;br /&gt;(2).&amp;nbsp;&lt;span&gt;避免重复的import, 多余的import和import *&lt;/span&gt;&lt;br /&gt;(3).&amp;nbsp;常量全部大写字母(static final);&lt;br /&gt;(4).&amp;nbsp;成员变量以m开头;&lt;br /&gt;(5).&amp;nbsp;&lt;span&gt;当有多重修饰符时,修饰符采用以下顺序:(&lt;/span&gt;&lt;span&gt;public,&lt;/span&gt;&lt;span&gt;protected,&lt;/span&gt;&lt;span&gt;private,&lt;/span&gt;&lt;span&gt;abstract,&lt;/span&gt;&lt;span&gt;static,&lt;/span&gt;&lt;span&gt;final,&lt;/span&gt;&lt;span&gt;transient,&lt;/span&gt;&lt;span&gt;volatile,&lt;/span&gt;&lt;span&gt;synchronized,&lt;/span&gt;&lt;span&gt;native,&lt;/span&gt;&lt;span&gt;strictfp)&lt;br /&gt;&amp;nbsp;... ...&lt;br /&gt;其他的我们后面慢慢的修改。&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.配置文件&lt;/strong&gt;&lt;br /&gt;在运行checkstyle时，需要一个参数(注:我的ubuntu服务器上安装的checkstyle5.4版本，最新的是5.5版本)：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/31770/2012010123012888.png" alt="" /&gt;&lt;br /&gt;这个配置文件就是用来定义你自己定制的代码规范，你可以参考官方说明：&lt;a href="http://checkstyle.sourceforge.net/availablechecks.html"&gt;http://checkstyle.sourceforge.net/availablechecks.html&lt;/a&gt;&lt;br /&gt;这里，我们根据上面说的，来写这样一个code_check.xml :&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;&amp;lt;?xml version="1.0"?&amp;gt;&#xD;
&amp;lt;!DOCTYPE module PUBLIC&#xD;
    "-//Puppy Crawl//DTD Check Configuration 1.2//EN"&#xD;
    "http://www.puppycrawl.com/dtds/configuration_1_2.dtd"&amp;gt;&#xD;
&#xD;
&amp;lt;module name="Checker"&amp;gt;&#xD;
&#xD;
    &amp;lt;!-- 检查文件是否以一个新行结束--&amp;gt;&#xD;
    &amp;lt;module name="NewlineAtEndOfFile"/&amp;gt;&#xD;
    &#xD;
	&amp;lt;!-- 检查文件中是否含有tab键--&amp;gt;&#xD;
	&amp;lt;module name="FileTabCharacter"/&amp;gt;&#xD;
		&#xD;
	&amp;lt;module name="TreeWalker"&amp;gt;&#xD;
&#xD;
	    &amp;lt;!-- 常量全部用大写--&amp;gt;&#xD;
	    &amp;lt;module name="ConstantName"/&amp;gt;&#xD;
&#xD;
		&amp;lt;!-- 避免.*,重复多余的和不使用的import--&amp;gt;&#xD;
		&amp;lt;module name="AvoidStarImport"/&amp;gt;&#xD;
        &amp;lt;module name="RedundantImport"/&amp;gt;&#xD;
        &amp;lt;module name="UnusedImports"/&amp;gt;&#xD;
		&#xD;
	    &amp;lt;!-- 成员变量格式为:m+大写+字母--&amp;gt;&#xD;
		&amp;lt;module name="MemberName"&amp;gt;&#xD;
			&amp;lt;property name="format" value="^m[A-Z][a-zA-Z0-9]*$"/&amp;gt;&#xD;
		&amp;lt;/module&amp;gt;&#xD;
&#xD;
		&amp;lt;!-- 检查代码块:起始大括号和if等同行，不能有空的代码块，结束大括号另起一行--&amp;gt;&#xD;
		&amp;lt;module name="LeftCurly"/&amp;gt;&#xD;
        &amp;lt;module name="NeedBraces"/&amp;gt;&#xD;
        &amp;lt;module name="RightCurly"/&amp;gt;&#xD;
        &amp;lt;!-- 当有多重修饰符时,修饰符采用以下顺序:&#xD;
             (public,protected,private,abstract,static,final,&#xD;
             transient,volatile,synchronized,native,strictfp) --&amp;gt;&#xD;
		&amp;lt;module name="ModifierOrder"/&amp;gt;&#xD;
    &amp;lt;/module&amp;gt;&#xD;
&#xD;
&amp;lt;/module&amp;gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;更多检查规范中文说明参考园子里地址： http://www.cnblogs.com/liugang/archive/2010/10/26/1860903.html&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4.使用checkstyle&lt;/strong&gt;&lt;br /&gt;插件工具的使用我就不介绍了，我只想起个抛砖引玉的作用，checkstyle命令非常简单，这里我只说明3个参数：-c, -r, -o。&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;/*******************&#xD;
 ***CheckStyle Usage**&#xD;
 ******************/&#xD;
/***&#xD;
 *参数&#xD;
 *1. -c  配置文件,并验证文件&#xD;
 *2. -o 输出结果&#xD;
 *3. -r  遍历目录&#xD;
 **/&#xD;
&#xD;
//用我们定制的code_checks.xml检查文件&#xD;
$&amp;gt;checkstyle -c ~/GitProj/world/code_checks.xml &#xD;
  ~/GitProj/world/floworld/src/com/tianxia/app/floworld/appreciate/AppreciateLatestActivity.java&#xD;
&#xD;
//用我们定制的code_checks.xml检查目录下的所有源文件，并把结果输出到result.txt中&#xD;
$&amp;gt;checkstyle -c ~/GitProj/world/code_checks.xml  &#xD;
  -r ~/GitProj/world/floworld/src/com/tianxia/app/floworld/appreciate/&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;我们打开result.txt来看下输出结果：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/31770/2012010123370275.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;又是tab又是命名不规范，非常的准确。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;5.与Git挂钩&lt;/strong&gt;&lt;br /&gt;快12点了，我先把文章发表出来，这部分随后我再补写。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/qianxudetianxia/aggbug/2309102.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2012/01/01/2309102.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/qianxudetianxia/archive/2011/12/11/2283794.html</id><title type="text">Android学习系列(17)--App列表之圆角ListView(续)</title><summary type="text">本来这篇文章想并到上篇Android学习系列(16)--App列表之圆角ListView中的，但是若是如此就让大家错过一篇新的好的文章，着实可惜。上篇中我们使用shape，corners，gradient实现了一个渐变的圆角效果，但是在完文之后的实践中，我发现有时效果不甚满意，选中和放手的事件监听没有去正确的判断，然后渐变效果也比较单一，性能也觉得不是很快，不如用图片来的惊艳和迅速，又懒的去改原来的，所以我又用图片来实现一个更完美的效果。1. 准备您可能需要参考我之前的两篇文章:(1).Android学习系列(16)--App列表之圆角ListView(2).Android学习系列(4)--A</summary><published>2011-12-11T03:47:00Z</published><updated>2011-12-11T03:47:00Z</updated><author><name>谦虚的天下</name><uri>http://www.cnblogs.com/qianxudetianxia/</uri></author><link rel="alternate" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/12/11/2283794.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/12/11/2283794.html"/><content type="html">&lt;p&gt;本来这篇文章想并到上篇&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2011/09/19/2068760.html"&gt;Android学习系列(16)--App列表之圆角ListView&lt;/a&gt;中的，但是若是如此就让大家错过一篇新的好的文章，着实可惜。&lt;br /&gt;上篇中我们使用shape，corners，gradient实现了一个渐变的圆角效果，但是在完文之后的实践中，我发现有时效果不甚满意，选中和放手的事件监听没有去正确的判断，然后渐变效果也比较单一，性能也觉得不是很快，不如用图片来的惊艳和迅速，又懒的去改原来的，所以我又用图片来实现一个更完美的效果。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1. 准备&lt;/strong&gt;&lt;br /&gt;您可能需要参考我之前的两篇文章:&lt;br /&gt;(1).&amp;nbsp;&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2011/09/19/2068760.html"&gt;Android学习系列(16)--App列表之圆角ListView&lt;br /&gt;&lt;/a&gt;(2).&amp;nbsp;&lt;a id="homepage1_HomePageDays_DaysList_DayItem_3_DayList_3_TitleUrl_0"  href="http://www.cnblogs.com/qianxudetianxia/archive/2011/04/17/2017591.html"&gt;Android学习系列(4)--App自适应draw9patch不失真背景&lt;br /&gt;&lt;/a&gt;了解圆角的基本实现原理和9patch图片的制作和注意事项。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2. 效果图(我准备了3套皮肤)&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011121110540598.png" alt="" width="360" height="600" /&gt;&amp;nbsp;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011121110542816.png" alt="" width="360" height="600" /&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011121110544738.png" alt="" width="360" height="600" /&gt;&amp;nbsp;&amp;nbsp;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011121110550356.png" alt="" width="360" height="600" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3. 圆角类CornerListView的实现：&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;/**&#xD;
 * 圆角ListView&#xD;
 */&#xD;
public class CornerListView extends ListView {&#xD;
&#xD;
    public CornerListView(Context context) {&#xD;
        this(context, null);&#xD;
    }&#xD;
&#xD;
    public CornerListView(Context context, AttributeSet attrs) {&#xD;
        super(context, attrs);&#xD;
        //整个listview的圆角背景&#xD;
        this.setBackgroundResource(R.drawable.corner_list_bg);&#xD;
    }&#xD;
&#xD;
    @Override&#xD;
    public boolean onInterceptTouchEvent(MotionEvent ev) {&#xD;
        switch (ev.getAction()) {&#xD;
        case MotionEvent.ACTION_DOWN:&#xD;
                int x = (int) ev.getX();&#xD;
                int y = (int) ev.getY();&#xD;
                int itemnum = pointToPosition(x, y);&#xD;
&#xD;
                if (itemnum == AdapterView.INVALID_POSITION){&#xD;
                    break;&#xD;
                } else {&#xD;
                        if (itemnum == 0){&#xD;
                                if (itemnum == (getAdapter().getCount()-1)) {&#xD;
                                    //只有一项&#xD;
                                    setSelector(R.drawable.corner_list_single_item);&#xD;
                                } else {&#xD;
                                    //第一项&#xD;
                                    setSelector(R.drawable.corner_list_first_item);&#xD;
                                }&#xD;
                        } else if (itemnum==(getAdapter().getCount()-1)){&#xD;
                             //最后一项&#xD;
                            setSelector(R.drawable.corner_list_last_item);&#xD;
                        } else {&#xD;
                            //中间项&#xD;
                            setSelector(R.drawable.corner_list_item);&#xD;
                        }&#xD;
                }&#xD;
                break;&#xD;
        case MotionEvent.ACTION_UP:&#xD;
                break;&#xD;
        }&#xD;
        return super.onInterceptTouchEvent(ev);&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;从上面看到，我们用到了一张ListView的背景图片和4个项选择器。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4. 素材&lt;/strong&gt;&lt;br /&gt;一种5张图片素材：1张背景图片和4个项选择器对应的选中图片，都是9patch图片：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011121111121364.png" alt="" /&gt;&amp;nbsp;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011121111122486.png" alt="" /&gt;&amp;nbsp;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011121111123767.png" alt="" /&gt;&amp;nbsp;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011121111125596.png" alt="" /&gt;&amp;nbsp;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011121111130278.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;分别对应的是：&lt;br /&gt;R.drawable.corner_list_bg，&lt;br /&gt;R.drawable.corner_list_first_pressed，&lt;br /&gt;R.drawablecorner_list_last_pressed，&lt;br /&gt;R.drawablecorner_list_pressed，&lt;br /&gt;R.drawablecorner_list_single_pressed&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;5.选择器构造&lt;/strong&gt;&lt;br /&gt;根据前面的后4张图片我们来构造选中时的对应选择器：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;&amp;lt;!-- corner_list_first_item.xml --&amp;gt;&#xD;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&#xD;
&amp;lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;&#xD;
    &amp;lt;item android:state_enabled="true" android:state_selected="true" android:drawable="@drawable/corner_list_first_pressed" /&amp;gt;&#xD;
    &amp;lt;item android:state_enabled="true" android:state_pressed="true" android:drawable="@drawable/corner_list_first_pressed" /&amp;gt;&#xD;
&amp;lt;/selector&amp;gt;&#xD;
&#xD;
&amp;lt;!-- corner_list_last_item.xml --&amp;gt;&#xD;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&#xD;
&amp;lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;&#xD;
    &amp;lt;item android:state_enabled="true" android:state_selected="true" android:drawable="@drawable/corner_list_last_pressed" /&amp;gt;&#xD;
    &amp;lt;item android:state_enabled="true" android:state_pressed="true" android:drawable="@drawable/corner_list_last_pressed" /&amp;gt;&#xD;
&amp;lt;/selector&amp;gt;&#xD;
&#xD;
&amp;lt;!-- corner_list_item.xml --&amp;gt;&#xD;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&#xD;
&amp;lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;&#xD;
    &amp;lt;item android:state_enabled="true" android:state_selected="true" android:drawable="@drawable/corner_list_pressed" /&amp;gt;&#xD;
    &amp;lt;item android:state_enabled="true" android:state_pressed="true" android:drawable="@drawable/corner_list_pressed" /&amp;gt;&#xD;
&amp;lt;/selector&amp;gt;&#xD;
&#xD;
&amp;lt;!-- corner_list_single_item.xml --&amp;gt;&#xD;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&#xD;
&amp;lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;&#xD;
    &amp;lt;item android:state_enabled="true" android:state_selected="true" android:drawable="@drawable/corner_list_single_pressed" /&amp;gt;&#xD;
    &amp;lt;item android:state_enabled="true" android:state_pressed="true" android:drawable="@drawable/corner_list_single_pressed" /&amp;gt;&#xD;
&amp;lt;/selector&amp;gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;strong&gt;6. 应用&lt;/strong&gt;&lt;br /&gt;我直接把使用圆角的Activity代码贴出来：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;public class SettingTabActivity extends Activity{&#xD;
&#xD;
    private CornerListView cornerListView = null;&#xD;
&#xD;
    private List&amp;lt;Map&amp;lt;String,String&amp;gt;&amp;gt; listData = null;&#xD;
    private SimpleAdapter adapter = null;&#xD;
&#xD;
    @Override&#xD;
    protected void onCreate(Bundle savedInstanceState) {&#xD;
        super.onCreate(savedInstanceState);&#xD;
        setContentView(R.layout.main_tab_setting);&#xD;
&#xD;
        cornerListView = (CornerListView)findViewById(R.id.setting_list);&#xD;
        setListData();&#xD;
&#xD;
        adapter = new SimpleAdapter(getApplicationContext(), listData, R.layout.main_tab_setting_list_item , &#xD;
new String[]{"text"}, new int[]{R.id.setting_list_item_text});&#xD;
        cornerListView.setAdapter(adapter);&#xD;
    }&#xD;
    &#xD;
    /**&#xD;
     * 设置列表数据&#xD;
     */&#xD;
    private void setListData(){&#xD;
        listData = new ArrayList&amp;lt;Map&amp;lt;String,String&amp;gt;&amp;gt;();&#xD;
&#xD;
        Map&amp;lt;String,String&amp;gt; map = new HashMap&amp;lt;String, String&amp;gt;();&#xD;
        map.put("text", "图库更新");&#xD;
        listData.add(map);&#xD;
&#xD;
        map = new HashMap&amp;lt;String, String&amp;gt;();&#xD;
        map.put("text", "检查新版本");&#xD;
        listData.add(map);&#xD;
&#xD;
        map = new HashMap&amp;lt;String, String&amp;gt;();&#xD;
        map.put("text", "反馈意见");&#xD;
        listData.add(map);&#xD;
&#xD;
        map = new HashMap&amp;lt;String, String&amp;gt;();&#xD;
        map.put("text", "关于我们");&#xD;
        listData.add(map);&#xD;
&#xD;
        map = new HashMap&amp;lt;String, String&amp;gt;();&#xD;
        map.put("text", "支持我们，请点击这里的广告");&#xD;
        listData.add(map);&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;ps：记得设置cacheColorHit属性为0或者"#00000000"！&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;7. 总结&lt;/strong&gt;&lt;br /&gt;在平时Android使用的过程中，发现很多设置界面的选项大量应用到了这种圆角效果，非常的漂亮，同时也发现很多应用，这个效果做的很不如意，包括一些大公司，要么没有选中效果，要么listview整个的背景是圆角，但是选中的第一项和最后一项的选中效果还是直角，要么干脆为圆角里设定一定像素的内边距等等，我对此总结，算是对这个问题有一个比较好的解决方案（我已经在网上搜过，未发现有人把这个效果分享过来），独乐乐不如众乐乐。&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;ps：附上3套皮肤素材：&lt;a href="http://files.cnblogs.com/qianxudetianxia/cornerlist-skin.zip"&gt;/Files/qianxudetianxia/cornerlist-skin.zip&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/qianxudetianxia/aggbug/2283794.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2011/12/11/2283794.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/qianxudetianxia/archive/2011/09/27/2193590.html</id><title type="text">Android拓展系列(5)--CyanogenMod源码下载和编译(Android ROM定制基础篇)</title><summary type="text">本来想下载Android官方源代码，没想到android.git.kernel.org维护，不能访问，非常遗憾，并因此还郁闷了几天。后来转投MIUI,没找到它的源码，不知道它的&amp;quot;超过40万人社区开发团队&amp;quot;是什么意思，求解具体开发人员几何，都是谁？后来一想，竟然忘记了CyanogenMod这茬，这可是的的确确的开源啊，我的手机一直也在用CyanogenMod系统的，感觉确实不错。1.准备我得环境如下，VirtualBox 4.1.2.r73507Ubuntu11.10 Beta2(32位)下载CyanogenMod的gingerbread分支Ubuntu的环境配置大家可以参考</summary><published>2011-09-27T14:19:00Z</published><updated>2011-09-27T14:19:00Z</updated><author><name>谦虚的天下</name><uri>http://www.cnblogs.com/qianxudetianxia/</uri></author><link rel="alternate" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/09/27/2193590.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/09/27/2193590.html"/><content type="html">&lt;p&gt;本来想下载Android官方源代码，没想到android.git.kernel.org维护，不能访问，非常遗憾，并因此还郁闷了几天。&amp;nbsp;&lt;br /&gt;后来转投MIUI,没找到它的源码，不知道它的"超过40万人社区开发团队"是什么意思，求解具体开发人员几何，都是谁？&lt;br /&gt;后来一想，竟然忘记了CyanogenMod这茬，这可是的的确确的开源啊，我的手机一直也在用CyanogenMod系统的，感觉确实不错。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.准备&lt;br /&gt;&lt;/strong&gt;我得环境如下，&lt;br /&gt;VirtualBox 4.1.2.r73507&lt;br /&gt;Ubuntu11.10 Beta2(32位)&lt;br /&gt;下载CyanogenMod的gingerbread分支&lt;br /&gt;Ubuntu的环境配置大家可以参考我前面写的《&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2011/05/29/2060636.html"&gt;Android拓展系列(3)--Android源码下载&lt;/a&gt;》，也可以参考&lt;a href="http://source.android.com/"&gt;http://source.android.com/&lt;/a&gt;。&lt;br /&gt;这里着重说下Android 2.3以上需要借助JAVA6，安装Java6，我推荐如下安装：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;$ sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"&#xD;
$ sudo add-apt-repository "deb-src http://archive.canonical.com/ubuntu lucid partner"&#xD;
$ sudo apt-get update&#xD;
$ sudo apt-get install sun-java6-jdk&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;其中第二句可能会出错，不过没关系，跳过即可。&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.安装repo&lt;/strong&gt;&lt;br /&gt;因为android.git官方已经不能访问，所以我这里提供一个repo文件的下载地址，免的大家到处搜索：&lt;a href="http://115.com/file/cl15goo2#repo"&gt;http://115.com/file/cl15goo2#repo&lt;/a&gt;&amp;nbsp;&lt;br /&gt;把repo拷贝到ubuntu根目录下得bin下&lt;br /&gt;操作方法：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;$mkdir bin&#xD;
//下载的repo脚本拷贝本地bin文件夹下&#xD;
//设置本地repo的可执行权限&#xD;
$chmod a+x ~/bin/repo&#xD;
$alias repo="~/bin/repo"&#xD;
//这里我用特意用别名，大家也可以按常规方法把repo的路径添加到PATH中&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.ubuntu中环境的配置&lt;/strong&gt;&lt;br /&gt;JDK前面已经说了，其他的软件列表如下：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;$sudo apt-get install git-core gnupg flex bison gperf libsdl1.2-dev libesd0-dev libwxgtk2.6-dev squashfs-tools build-essential zip curl libncurses5-dev zlib1g-dev sun-java6-jdk pngcrush schedtool  &#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;这些软件都安装好之后我们开始下载CyanogenMod源码。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4.下载CyanogenMod源码&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;//从用户根目录下开始&#xD;
//创建CyanogenMod文件夹来放置后面所有的代码&#xD;
$mkdir CyanogenMod&#xD;
//获取gingerbread的分支源代码&#xD;
$repo init -u git://github.com/CyanogenMod/android.git -b gingerbread  &#xD;
//同步服务器代码到本地，-j16据网友反应是多开网络连接，从而能提高下载速度&#xD;
$repo sync -j16&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;这个过程非常的漫长，大家慢慢的等吧，本人是晚上睡觉的时候下载，第二天早上醒来就Done了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;5.编译源码&lt;/strong&gt;&lt;br /&gt;在CyanogenMod/device目录下有很多款手机的对应版本：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011092720560175.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;br /&gt;里面有个htc，本人是htc G9，也就是Liberty，我们点击看看：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011092720563435.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;br /&gt;我的liberty静静的优雅的舒服的躺在那里。&lt;br /&gt;所以本人决定编译一个我手头上的liberty对应的系统版本，编译完成后我们直接刷机。&lt;br /&gt;&lt;em&gt;&lt;strong&gt;第一步：读取手机上的一些私有配置文件&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;$cd CyanogenMod/device/htc/liberty&#xD;
$./extract-files.sh&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;图示如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011092721025486.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;第二步：生成编译脚本文件&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;$cd ~/CyanogenMod/vendor/cyanogen  &#xD;
$./get-rommanager&#xD;
$./extract-google-files&#xD;
//复制编译脚本文件到CyanogenMod目录下，后面编译整个系统用的就是这个文件&#xD;
$cp ~/CyanogenMod/vendor/cyanogen/products/cyanogen_lieberty.mk  ~/CyanogenMod/buildspec.mk&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;贴上进行时图片：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011092721064981.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;第三步：编译脚本&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;回到CyanogenMod目录下，执行脚本。&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;//初始化脚本，这个是后面的重要基础步骤&#xD;
$source build/envsetup.sh&#xD;
//选择编译的产品&#xD;
//这个命令需要一小会儿时间，但是又没提示，耐性等待一下&#xD;
$lunch cyanogen_liberty-eng&#xD;
//开始编译&#xD;
$make -j4 CYANOGEN_WITH_GOOGLE=true otapackage &#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;这个过程也是相当的漫长，还好一般情况下我们只是第一次需要项目整个编译，后面只需要编译某个模块。&lt;br /&gt;可惜完成的时候我忘记截图了，可惜不能上图了。&lt;br /&gt;在编译的过程中，我们有一点要特别注意，虚拟机的内存不要太小，本人刚开始分配虚拟机512M内存，一会儿就出错，重新编译又一会儿出错，如此重复，而且还导致某个文件被破坏掉了（values-cs/strings.xml中某行少一个右尖括号，这个我百思不得其解），后来我把虚拟机内存调到1024M就一直编译通过了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;第四步：生产刷机zip包。&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;./vendor/cyanogen/tools/squisher&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;有图为赏：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011092721195018.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;br /&gt;用这个zip包，我刷到我手机上，一切正常。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;6.定制ROM&lt;/strong&gt;&lt;br /&gt;有了以上的环境后，我们就可以大展手脚，深度定制ROM, 做自己的操作系统，自己的CyanogenMod，自己的MIUI，自己的Android系统。&lt;br /&gt;举个最简单的例子：&lt;br /&gt;我们换一下默认menu菜单的选中背景图，我们进入CyanogenMod/frameworks/base/core/res/res/mdpi目录下(因为htc liberty的分辨率是480x320)，找到图片highlight_pressed.png，替换为绿色的背景：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011092721295436.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;br /&gt;那么修改资源文件后，我们需要重新编译framework-res.apk:&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;//回到根目录&#xD;
$cd&#xD;
//切换到管理员权限&#xD;
$sudo -s&#xD;
//进入CyanogenMod目录，并初始化脚本文件&#xD;
$cd CyanogenMod&#xD;
$source build/envsetup.h&#xD;
//选择产品&#xD;
$lunch cyanogen_liberty-eng&#xD;
//进入资源编译目录(或者它的子目录也可以)&#xD;
$cd frameworks/base/core/res&#xD;
//开始编译framework-res.apk&#xD;
$mm&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;编译完成，示意图如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011092721494456.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在CyanogenMod/out/target/product/liberty/system/framework目录下生成了一个framework-res.apk文件，就是我们修改Menu选中项图片后新打的资源包。&lt;br /&gt;现在我们需要把这个资源包更新到手机中。&lt;br /&gt;USB连上手机后，一切正常的话(adb当然也是事前要装好的哦)，打开终端：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;//使其可写&#xD;
$adb remount&#xD;
//替换手机中资源包&#xD;
$adb push ~/CyanogenMod/out/target/product/liberty/system/framework/framework-res.apk /system/framework/&#xD;
//重启手机后生效&#xD;
$adb reboot&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;重启后，进入桌面，我们点击Menu，选择一项：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011092721573548.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;修改资源包，可以修改样式，显示图片，调整布局等等。&lt;br /&gt;你也可以直接修改framework代码，在framework/base/core/java目录下，修改对应的类，比如逻辑处理，样式重绘等等，然后同上面类似编译，把生成的framework.jar替换掉手机的/system/framework下的framework.jar，重启手机即可看到效果。&lt;br /&gt;你也可以添加系统应用，删除系统应用等等，这里特别提到一点，系统应用可以通过如下命令删除(具有root权限)：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;$adb remount&#xD;
$adb shell&#xD;
#cd system/app&#xD;
//用rm删除系统FM应用&#xD;
#rm FM.apk&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;有了这些基础知识，我相信我们后面的深度定制ROM一定非常精彩！&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;7.小结&lt;/strong&gt;&lt;br /&gt;本文以CyanogenMod源码编译总结了Android改造系统的一个基本环境，是我们之后ROM系统定制，优化的基础，是android深入学习的必会技能，特此分享，共勉！&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/qianxudetianxia/aggbug/2193590.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2011/09/27/2193590.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/qianxudetianxia/archive/2011/09/25/2189863.html</id><title type="text">Android拓展系列(4)--vim编辑器的基本使用</title><summary type="text">从接触Linux到现在，也已经好几年了，对于linux的感觉一直是分分离离，充满了遗憾，最大的遗憾之一就是一直没能精通vim，不能完全适应vim下的代码开发。最近工作中又广泛接触到vim的使用，我觉得有必要总结一下。但是我又无法针对vim的所有命令使用展开叙述，反而认为针对android，或者说java的一些常用编辑相关的操作命令做一个解说更具有效性。1.vim的三种命令模式(1).命令模式：用于输入命令，简单更改(2).插入模式：用于插入文本，修改文本(3).末行模式：用于输入命令，视化操作，查找替换等这三种模式熟悉后，颠覆了windows里面编辑+工具栏（或者菜单栏）的方式，是我们进入命令</summary><published>2011-09-24T17:34:00Z</published><updated>2011-09-24T17:34:00Z</updated><author><name>谦虚的天下</name><uri>http://www.cnblogs.com/qianxudetianxia/</uri></author><link rel="alternate" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/09/25/2189863.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/09/25/2189863.html"/><content type="html">&lt;p&gt;从接触Linux到现在，也已经好几年了，对于linux的感觉一直是分分离离，充满了遗憾，最大的遗憾之一就是一直没能精通vim，不能完全适应vim下的代码开发。&lt;br /&gt;最近工作中又广泛接触到vim的使用，我觉得有必要总结一下。&lt;br /&gt;但是我又无法针对vim的所有命令使用展开叙述，反而认为针对android，或者说java的一些常用编辑相关的操作命令做一个解说更具有效性。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.vim的三种命令模式&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;em&gt;(1).命令模式：&lt;/em&gt;&lt;/strong&gt;&lt;em&gt;用于输入命令，简单更改&lt;/em&gt;&lt;br /&gt;&lt;strong&gt;&lt;em&gt;(2).插入模式：&lt;/em&gt;&lt;/strong&gt;&lt;em&gt;用于插入文本，修改文本&lt;/em&gt;&lt;br /&gt;&lt;strong&gt;&lt;em&gt;(3).末行模式：&lt;/em&gt;&lt;/strong&gt;&lt;em&gt;用于输入命令，视化操作，查找替换等&lt;/em&gt;&lt;br /&gt;这三种模式熟悉后，颠覆了windows里面编辑+工具栏（或者菜单栏）的方式，是我们进入命令介面的重要认知，经过使用之后，相信大家一定会喜欢这种操作模式的。&lt;br /&gt;三种模式之间的切换方式如下：&lt;br /&gt;&lt;em&gt;&lt;strong&gt;(1).命令模式进入到插入模式&lt;/strong&gt;&lt;/em&gt;：&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;输入文本插入命令&lt;/span&gt;&lt;/strong&gt;。&lt;br /&gt;文本插入命令有:i,I,a,A,o,O&lt;br /&gt;&lt;em&gt;&lt;strong&gt;(2).插入模式退出到命令模式&lt;/strong&gt;&lt;/em&gt;：&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;ESC&lt;/span&gt;&lt;/strong&gt;。&lt;br /&gt;&lt;em&gt;&lt;strong&gt;(3).命令模式进入到末行模式&lt;/strong&gt;&lt;/em&gt;：&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;冒号：&lt;/span&gt;&lt;/strong&gt;。&lt;br /&gt;如：:set nu &amp;nbsp; &amp;nbsp; &amp;nbsp; 表示行号显示&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; :set nonu &amp;nbsp; 取消行号显示&lt;br /&gt;&lt;strong&gt;&lt;em&gt;(4).末行模式推出到命令模式&lt;/em&gt;&lt;/strong&gt;：&lt;span style="color: #ff0000;"&gt;&lt;strong&gt;Enter或者ESC&lt;/strong&gt;&lt;/span&gt;。&lt;br /&gt;由此我们也看出命令模式是这里还起了一个枢纽的作用，非常重要。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.文本插入命令&lt;/strong&gt;&lt;br /&gt;上面说到文本插入命令了，正好我们就趁势说完。&lt;br /&gt;文本插入命令主要是这几个i,I,a,A,o,O。&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;i(insert)         在光标前插入文本&#xD;
I                 在光标所在行首插入文本&#xD;
a(append)         在光标后插入文本&#xD;
A                 在光标所在行尾添加文本&#xD;
o(open)           在光标所在行下面添加一行&#xD;
O                 在光标所在行上面添加一行&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;说句实话，这几个命令都还真是有用，必须掌握，我建议先记住小写的即可，大写先不管，到后面熟悉之后，大写的自然就记住了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.vim的退出和保存&lt;/strong&gt;&lt;br /&gt;退出vim也是基本操作基本涉及如下几个命令：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;:q                     退出vim返回到shell，若有修改未被保存，vi在末行给出提示信息并不退出vim到shell&#xD;
:q!                    退出vim返回到shell，放弃未保存的修改&#xD;
:wq                    先保存，然后退出vim返回到shell&#xD;
:x                     和wq命令功能类似，区别是如果是文件没有修改的话，x不会更新文件的修改时间，而wq则会更新文件的修改时间，无论是否有修改。&#xD;
:w filename            写入当前文件到filename文件&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;wq和x应该用的很多吧。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4.命令模式的常用操作&lt;/strong&gt;&lt;br /&gt;在命令模式最常用操作大概包括，删除，复制，粘贴，撤销，移动等等，我列举几个最常用的如下 ：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;dd       删除当前1行&#xD;
5dd      删除当前行向下5行&#xD;
x        删除光标后字符&#xD;
X        删除光标前字符&#xD;
&#xD;
yy       复制当前1行&#xD;
5yy      复制当前行向下5行&#xD;
&#xD;
p        粘贴&#xD;
&#xD;
u        撤销&#xD;
&#xD;
hjkl     向左下上右方向移动光标&#xD;
^        光标移动到本行行首&#xD;
$        光标移动到本行行尾&#xD;
gg       跳到文件首行&#xD;
5gg      跳到第5行&#xD;
G        跳到文件尾行&#xD;
&#xD;
Ctrl + f 向后滚一页。&#xD;
Ctrl + d 向后滚半页。&#xD;
Ctrl + b 向前滚一页。&#xD;
Ctrl + u 向前滚半页。&#xD;
Ctrl + e 屏幕向下滚一行。&#xD;
Ctrl + y 屏幕项上滚一行。&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;上述命令是我们编辑文件经常使用的一些操作，必须掌握，非常有用。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;5.查找替换&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;/android                 查找android，然后如果按n，表示向下查找，如果按N，表示向上查找&#xD;
?android                 查找android，然后如果按n，表示向上查找，如果按N，表示向下查找&#xD;
&#xD;
shift+8                  向后搜索当前光标指向的单词&#xD;
shift+3                  向前搜索当前光标指向的单词      &#xD;
&#xD;
:%s/old/new/g            将编辑器的缓冲区的"old"替换为new&#xD;
:19,20s/old/new/g        将文件的19到20行的的"old"替换为new &#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;用vim查找和替换还是挺方便的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;6.小结&lt;/strong&gt;&lt;br /&gt;差不多，上述是vim编辑器的基本用法，今天写在这里，做一总结，同时与大家共勉。&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/qianxudetianxia/aggbug/2189863.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2011/09/25/2189863.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/qianxudetianxia/archive/2011/09/19/2068760.html</id><title type="text">Android学习系列(16)--App列表之圆角ListView</title><summary type="text">有些东西看多了，就厌烦了：extjs对我这种感觉最为强烈。甚至，有时觉得设计之殇是审美疲劳。直角看多了，就想看看圆角，不知何时，这几年刮起了一阵阵的圆角设计风：CSS新标准纳入圆角元素，iphone中几乎随处可见圆角设计，也开始出现很多圆角名片了...今天我们就实现一个圆角的ListView效果。圆角的设计，我们并不追求到处都用，无处不用，android中有少数界面用直角确实容易显得锋利，和周边界面太过对比而显得不协调，比如大栏目列表，设置等等，而采用圆角实现，则会活泼，轻松的多，也融合的特别好。1.感觉实际上在Android中因为SDK中没有默认对圆角的一个完整的支持，需要麻烦自定义设置才能</summary><published>2011-09-19T13:23:00Z</published><updated>2011-09-19T13:23:00Z</updated><author><name>谦虚的天下</name><uri>http://www.cnblogs.com/qianxudetianxia/</uri></author><link rel="alternate" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/09/19/2068760.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/09/19/2068760.html"/><content type="html">&lt;p&gt;有些东西看多了，就厌烦了：extjs对我这种感觉最为强烈。甚至，有时觉得设计之殇是审美疲劳。&lt;br /&gt;直角看多了，就想看看圆角，不知何时，这几年刮起了一阵阵的圆角设计风：CSS新标准纳入圆角元素，iphone中几乎随处可见圆角设计，也开始出现很多圆角名片了...&lt;br /&gt;今天我们就实现一个圆角的ListView效果。&lt;br /&gt;圆角的设计，我们并不追求到处都用，无处不用，android中有少数界面用直角确实容易显得锋利，和周边界面太过对比而显得不协调，比如大栏目列表，设置等等，而采用圆角实现，则会活泼，轻松的多，也融合的特别好。&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.感觉&lt;/strong&gt;&lt;br /&gt;实际上在Android中因为SDK中没有默认对圆角的一个完整的支持，需要麻烦自定义设置才能实现完美的圆角效果，所以绝大多数应用都是采用分组直角列表这种样式。&lt;br /&gt;所以我觉得很有必要让大家看看这些少数的不一样的东西，看看有什么不一样的感觉。&lt;br /&gt;先让我们来看两张图片：&lt;/p&gt;&#xD;
&lt;p style="text-align: center;"&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011091900353965.png" alt="" /&gt;&amp;nbsp;&amp;nbsp;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011091900354753.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;左边的是Android的一个应用的设置界面，右边是iphone系统的设置界面。&lt;br /&gt;ps:上述只是效果，并不是说左边的圆角列表就是用listview是实现的，事实上它是用LinearLayout布局一个一个堆起来的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.原理&lt;/strong&gt;&lt;br /&gt;通过判断ListView上点击的项的位置，我们切换不同的选择器，当然这个切换的动作我们需要定义在重写ListView的onInterceptTouchEvent()方法中。&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;if(itemnum==0){&#xD;
    if(itemnum==(getAdapter().getCount()-1)){&#xD;
        //只有一项&#xD;
        setSelector(R.drawable.app_list_corner_round);&#xD;
    }else{&#xD;
        //第一项                            &#xD;
        setSelector(R.drawable.app_list_corner_round_top);&#xD;
    }&#xD;
}else if(itemnum==(getAdapter().getCount()-1))&#xD;
    //最后一项&#xD;
    setSelector(R.drawable.app_list_corner_round_bottom);&#xD;
else{&#xD;
    //中间一项                            &#xD;
    setSelector(R.drawable.app_list_corner_shape);&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.定义选择器&lt;/strong&gt;&lt;br /&gt;如果只有一项，我们需要四个角都是圆角，app_list_corner_round.xml文件定义如下：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&#xD;
&amp;lt;shape xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;&#xD;
    &amp;lt;gradient android:startColor="#B5E7B8" &#xD;
        android:endColor="#76D37B" &#xD;
        android:angle="270"/&amp;gt;&#xD;
    &amp;lt;corners android:topLeftRadius="4dip"&#xD;
        android:topRightRadius="4dip"&#xD;
        android:bottomLeftRadius="4dip"&#xD;
        android:bottomRightRadius="4dip"/&amp;gt;&#xD;
&amp;lt;/shape&amp;gt; &#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;如果是顶部第一项，则上面两个角为圆角，app_list_corner_round_top.xml定义如下：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&#xD;
&amp;lt;shape xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;&#xD;
    &amp;lt;gradient android:startColor="#B5E7B8" &#xD;
        android:endColor="#76D37B" &#xD;
        android:angle="270"/&amp;gt;&#xD;
    &amp;lt;corners android:topLeftRadius="4dip"&#xD;
        android:topRightRadius="4dip"/&amp;gt;&#xD;
&amp;lt;/shape&amp;gt; &lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;如果是底部最后一项，则下面两个角为圆角，app_list_corner_round_bottom.xml定义如下：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&#xD;
&amp;lt;shape xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;&#xD;
    &amp;lt;gradient android:startColor="#B5E7B8" &#xD;
        android:endColor="#76D37B" &#xD;
        android:angle="270"/&amp;gt;&#xD;
    &amp;lt;corners android:bottomLeftRadius="4dip"&#xD;
        android:bottomRightRadius="4dip" /&amp;gt;&#xD;
&amp;lt;/shape&amp;gt; &#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;如果是中间项，则应该不需要圆角，&amp;nbsp;app_list_corner_shape.xml定义如下：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&#xD;
&amp;lt;shape xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;&#xD;
    &amp;lt;gradient android:startColor="#B5E7B8" &#xD;
        android:endColor="#76D37B" &#xD;
        android:angle="270"/&amp;gt;&#xD;
&amp;lt;/shape&amp;gt; &lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4.背景图片&lt;/strong&gt;&lt;br /&gt;因为默认的情况下，ListView就要显示一个圆角的边框，这个我们使用一张9patch背景图片来实现app_list_corner_border.9.png：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011091920011428.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;br /&gt;在这里提示一下，做9patch背景图片的时候，记得把内容区域定义为边框线以内的区域。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;5. 初步实现&lt;/strong&gt;&lt;br /&gt;参考前面提供的素材和核心代码，我们初步实现如下:&lt;br /&gt;&lt;strong&gt;&lt;em&gt;(1).自定义CornerListView.java:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;/**&#xD;
 * 圆角ListView&#xD;
 */&#xD;
public class CornerListView extends ListView {&#xD;
&#xD;
    public CornerListView(Context context) {&#xD;
        super(context);&#xD;
    }&#xD;
&#xD;
    public CornerListView(Context context, AttributeSet attrs, int defStyle) {&#xD;
        super(context, attrs, defStyle);&#xD;
    }&#xD;
&#xD;
    public CornerListView(Context context, AttributeSet attrs) {&#xD;
        super(context, attrs);&#xD;
    }&#xD;
&#xD;
    @Override&#xD;
    public boolean onInterceptTouchEvent(MotionEvent ev) {&#xD;
        switch (ev.getAction()) {&#xD;
        case MotionEvent.ACTION_DOWN:&#xD;
                int x = (int) ev.getX();&#xD;
                int y = (int) ev.getY();&#xD;
                int itemnum = pointToPosition(x, y);&#xD;
&#xD;
                if (itemnum == AdapterView.INVALID_POSITION)&#xD;
                        break;                 &#xD;
                else&#xD;
                {  &#xD;
                        if(itemnum==0){&#xD;
                                if(itemnum==(getAdapter().getCount()-1)){                                    &#xD;
                                    setSelector(R.drawable.app_list_corner_round);&#xD;
                                }else{&#xD;
                                    setSelector(R.drawable.app_list_corner_round_top);&#xD;
                                }&#xD;
                        }else if(itemnum==(getAdapter().getCount()-1))&#xD;
                                setSelector(R.drawable.app_list_corner_round_bottom);&#xD;
                        else{                            &#xD;
                            setSelector(R.drawable.app_list_corner_shape);&#xD;
                        }&#xD;
                }&#xD;
&#xD;
                break;&#xD;
        case MotionEvent.ACTION_UP:&#xD;
                break;&#xD;
        }&#xD;
        return super.onInterceptTouchEvent(ev);&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;这个CornerListView主要处理了点击项的选择器的切换。&lt;br /&gt;&lt;em&gt;&lt;strong&gt;(2).列表布局文件和列表项布局文件：&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;列表布局文件main_tab_setting.xml：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&#xD;
&amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"&#xD;
    android:orientation="vertical"&#xD;
    android:layout_width="fill_parent"&#xD;
    android:layout_height="fill_parent"&amp;gt;&#xD;
    &amp;lt;com.tianxia.app.floworld.view.CornerListView android:id="@+id/setting_list"&#xD;
        android:layout_width="fill_parent" &#xD;
        android:layout_height="wrap_content"&#xD;
        android:layout_margin="10dip"&#xD;
        android:background="@drawable/app_list_corner_border"&#xD;
        android:cacheColorHint="#00000000"&amp;gt;&#xD;
    &amp;lt;/com.tianxia.app.floworld.view.CornerListView&amp;gt;&#xD;
&amp;lt;/LinearLayout&amp;gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;列表项布局文件main_tab_setting_list_item.xml：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&#xD;
&amp;lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"&#xD;
    android:layout_width="fill_parent"&#xD;
    android:layout_height="fill_parent"&amp;gt;&#xD;
    &amp;lt;ImageView android:id="@+id/setting_list_item_arrow"&#xD;
        android:layout_alignParentRight="true"&#xD;
        android:layout_centerVertical="true"&#xD;
        android:layout_width="wrap_content"&#xD;
        android:layout_height="fill_parent"&#xD;
        android:layout_marginLeft="15dip"&#xD;
        android:layout_marginRight="15dip"&#xD;
        android:src="@drawable/appreciate_tab_list_item_arrow_small"/&amp;gt;&#xD;
    &amp;lt;TextView  android:id="@+id/setting_list_item_text"&#xD;
        android:layout_toLeftOf="@id/setting_list_item_arrow"&#xD;
        android:layout_width="fill_parent" &#xD;
        android:layout_height="wrap_content"&#xD;
        android:textSize="16dip"&#xD;
        android:textColor="#000000"&#xD;
        android:paddingTop="10dip"&#xD;
        android:paddingBottom="10dip"&#xD;
        android:paddingLeft="10dip" /&amp;gt;&#xD;
&amp;lt;/RelativeLayout&amp;gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;(3)界面实现&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;显示界面SettingTabActivity.java:&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;public class SettingTabActivity extends Activity{&#xD;
    &#xD;
    private CornerListView cornerListView = null;&#xD;
    &#xD;
    private List&amp;lt;Map&amp;lt;String,String&amp;gt;&amp;gt; listData = null;&#xD;
    private SimpleAdapter adapter = null;&#xD;
    &#xD;
    &#xD;
    @Override&#xD;
    protected void onCreate(Bundle savedInstanceState) {&#xD;
        super.onCreate(savedInstanceState);&#xD;
        setContentView(R.layout.main_tab_setting);&#xD;
        &#xD;
        cornerListView = (CornerListView)findViewById(R.id.setting_list);&#xD;
        setListData();&#xD;
        &#xD;
        adapter = new SimpleAdapter(getApplicationContext(), listData, R.layout.main_tab_setting_list_item , new String[]{"text"}, new int[]{R.id.setting_list_item_text});&#xD;
        cornerListView.setAdapter(adapter);&#xD;
    }&#xD;
    &#xD;
    /**&#xD;
     * 设置列表数据&#xD;
     */&#xD;
    private void setListData(){&#xD;
        listData = new ArrayList&amp;lt;Map&amp;lt;String,String&amp;gt;&amp;gt;();&#xD;
        &#xD;
        Map&amp;lt;String,String&amp;gt; map = new HashMap&amp;lt;String, String&amp;gt;();&#xD;
        map.put("text", "图库更新");&#xD;
        listData.add(map);&#xD;
        &#xD;
        map = new HashMap&amp;lt;String, String&amp;gt;();&#xD;
        map.put("text", "收藏图片");&#xD;
        listData.add(map);&#xD;
        &#xD;
        map = new HashMap&amp;lt;String, String&amp;gt;();&#xD;
        map.put("text", "下载目录");&#xD;
        listData.add(map);&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;(4).效果图&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;通过以上实现，我们基本达到了圆角的ListView的效果：&lt;/p&gt;&#xD;
&lt;p style="text-align: center;"&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011091920171662.png" alt="" /&gt;&amp;nbsp;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011091920173056.png" alt="" /&gt;&amp;nbsp;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011091920432620.png" alt="" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/qianxudetianxia/aggbug/2068760.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2011/09/19/2068760.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/qianxudetianxia/archive/2011/09/03/2155875.html</id><title type="text">Android学习系列(23)--App主界面实现</title><summary type="text">在上篇文章《Android学习系列(22)--App主界面比较》中我们浅略的分析了几个主界面布局，选了一个最大众化的经典布局。今天我们就这个经典布局，用代码具体的实现它。1.预览图先看下最终的界面设计图：上面顶部是一个9patch背景图片+标题文字；下面底部是5个tab标签，表示应用的5大模块。中间内容部分则是各个模块的具体内容，可以再分类，或者直接显示内容。2.准备素材按照上篇文章的界面，我们需要事先提供两大方面的素材：顶部+底部。顶部的素材非常简单，最重要的是背景（9patch的图片）：底部的素材稍微多一点：(1).每个tab的背景都需要正常和选中两种，一共10张图片;(2).每个tab之</summary><published>2011-09-03T08:45:00Z</published><updated>2011-09-03T08:45:00Z</updated><author><name>谦虚的天下</name><uri>http://www.cnblogs.com/qianxudetianxia/</uri></author><link rel="alternate" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/09/03/2155875.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/09/03/2155875.html"/><content type="html">&lt;p&gt;在上篇文章《&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2011/08/28/2155872.html"&gt;Android学习系列(22)--App主界面比较&lt;/a&gt;》中我们浅略的分析了几个主界面布局，选了一个最大众化的经典布局。&lt;br /&gt;今天我们就这个经典布局，用代码具体的实现它。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.预览图&lt;/strong&gt;&lt;br /&gt;先看下最终的界面设计图：&lt;/p&gt;&#xD;
&lt;p style="text-align: center;"&gt;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090311520834.png" /&gt;&amp;nbsp;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090311531184.png" /&gt;&amp;nbsp;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090311534811.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;上面顶部是一个9patch背景图片+标题文字；&lt;br /&gt;下面底部是5个tab标签，表示应用的5大模块。&lt;br /&gt;中间内容部分则是各个模块的具体内容，可以再分类，或者直接显示内容。&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.准备素材&lt;/strong&gt;&lt;br /&gt;按照上篇文章的界面，我们需要事先提供两大方面的素材：顶部+底部。&lt;br /&gt;顶部的素材非常简单，最重要的是背景（9patch的图片）：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090315302146.png" /&gt;&lt;br /&gt;底部的素材稍微多一点：&lt;br /&gt;(1).每个tab的背景都需要正常和选中两种，一共10张图片;&lt;br /&gt;(2).每个tab之间有一张分割线，1张图片;&lt;br /&gt;(3).为了自适应屏幕宽度，并保持图形不变形，必须tab背景和下面botton这个背景色一致，所以需要1张同背景的背景图片。&lt;br /&gt;如下：&lt;br /&gt;(1).&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p style="text-align: center;"&gt;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090315350627.png" /&gt;&amp;nbsp;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090315351852.png" /&gt;&amp;nbsp;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090315353378.png" /&gt;&amp;nbsp;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090315354341.png" /&gt;&amp;nbsp;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090315360032.png" /&gt;&amp;nbsp;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090315361197.png" /&gt;&amp;nbsp;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090315362743.png" /&gt;&amp;nbsp;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090315364087.png" /&gt;&amp;nbsp;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090315365566.png" /&gt;&amp;nbsp;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090315370692.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;(2).&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090315382245.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;(3).&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090315384513.png" /&gt;在这里呢，我再三考量，决定还是把图片和文字放在一起，这样一能大大降低代码的复杂性，而且能保证漂亮的样式，我们通过Photoshop来控制，灵活性大大增强。&lt;br /&gt;以上是我在网上随便找了几张照片，稍微处理了一下，作为下面我们实现的素材。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.实现原理&lt;/strong&gt;&lt;br /&gt;这里，我采用了getDecorView方法，发现这种方法布局和代码比较简洁，看上去性能也不错(待查)。&lt;br /&gt;用核心代码来说明一下原理：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;//mainTabContainer是一个空布局，做为每个tab的容器&#xD;
        //activity是每个tab对应的activity&#xD;
        //getDecorView是对应的activity的视图，添加到tab容器中，就能实现切换activity的效果了&#xD;
        mainTabContainer.removeAllViews();&#xD;
        mainTabIntent = new Intent(this,activity);&#xD;
        mainTabContainer.addView(localActivityManager.startActivity(id, mainTabIntent).getDecorView());&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;通过切换不同的activity的decorView,实现tab的视图切换。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4.基本框架&lt;/strong&gt;&lt;br /&gt;布局界面思路非常清晰，顶部+底部+中间tab内容&lt;br /&gt;我采用相对布局(相对于线性布局，我经常选择帧布局和相对布局，我更喜欢这两个小巧的布局)：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;&amp;lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"&#xD;
    android:orientation="vertical"&#xD;
    android:layout_width="fill_parent"&#xD;
    android:layout_height="fill_parent"&amp;gt;&#xD;
    &amp;lt;LinearLayout android:id="@+id/main_tab_banner"&#xD;
        android:layout_width="fill_parent"&#xD;
        android:layout_height="wrap_content"&#xD;
        android:paddingLeft="10dip"&#xD;
        android:orientation="horizontal"&#xD;
        android:gravity="center"&#xD;
        android:background="@drawable/main_banner_bg"&#xD;
        android:layout_alignParentTop="true"&amp;gt;&#xD;
        &amp;lt;!-- 标题 --&amp;gt;&#xD;
    &amp;lt;/LinearLayout&amp;gt;&#xD;
    &amp;lt;LinearLayout android:id="@+id/main_tab"&#xD;
        android:layout_width="fill_parent"&#xD;
        android:layout_height="wrap_content"&#xD;
        android:orientation="horizontal"&#xD;
        android:gravity="center"&#xD;
        android:background="@drawable/tab_bg"&#xD;
        android:layout_alignParentBottom="true"&amp;gt;&#xD;
        &amp;lt;!-- 内容 --&amp;gt;&#xD;
    &amp;lt;/LinearLayout&amp;gt;&#xD;
    &amp;lt;LinearLayout android:id="@+id/main_tab_container"&#xD;
        android:layout_above="@id/main_tab"&#xD;
        android:layout_below="@id/main_tab_banner"&#xD;
        android:layout_width="fill_parent"&#xD;
        android:layout_height="fill_parent"&#xD;
        android:background="#FFFFE0"&amp;gt;&#xD;
    &amp;lt;/LinearLayout&amp;gt;&#xD;
&amp;lt;/RelativeLayout&amp;gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;看起来很复杂的东西，分解一下就简单的多了。&lt;br /&gt;在标题处，加上一个TextView，做为标题显示。&lt;br /&gt;在内容处，我们需要填充5个Tab背景和1个分割线，请参考《&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2011/04/29/2033057.html"&gt;Android学习系列(5)--App布局初探之简单模型&lt;/a&gt;》 中的模型四,使用了layout_weight的属性，平均分割了5个tab.&lt;br /&gt;最终我们的布局文件如下：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&#xD;
&amp;lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"&#xD;
    android:orientation="vertical"&#xD;
    android:layout_width="fill_parent"&#xD;
    android:layout_height="fill_parent"&amp;gt;&#xD;
    &amp;lt;LinearLayout android:id="@+id/main_tab_banner"&#xD;
        android:layout_width="fill_parent"&#xD;
        android:layout_height="wrap_content"&#xD;
        android:paddingLeft="10dip"&#xD;
        android:orientation="horizontal"&#xD;
        android:gravity="center"&#xD;
        android:background="@drawable/main_banner_bg"&#xD;
        android:layout_alignParentTop="true"&amp;gt;&#xD;
        &amp;lt;TextView android:id="@+id/main_tab_banner_title"&#xD;
            android:layout_width="fill_parent"&#xD;
            android:layout_height="wrap_content"&#xD;
            android:text="欣赏美花"&#xD;
            android:textSize="20dip"&#xD;
            android:textColor="#000000"/&amp;gt;&#xD;
    &amp;lt;/LinearLayout&amp;gt;&#xD;
    &amp;lt;LinearLayout android:id="@+id/main_tab"&#xD;
        android:layout_width="fill_parent"&#xD;
        android:layout_height="wrap_content"&#xD;
        android:orientation="horizontal"&#xD;
        android:gravity="center"&#xD;
        android:background="@drawable/tab_bg"&#xD;
        android:layout_alignParentBottom="true"&amp;gt;&#xD;
        &amp;lt;ImageView android:id="@+id/appreciate_tab_btn"&#xD;
            android:layout_weight="1"&#xD;
            android:layout_width="wrap_content"&#xD;
            android:layout_height="fill_parent"&#xD;
            android:gravity="center_horizontal|bottom"&#xD;
            android:src="@drawable/appreciate_press"/&amp;gt;&#xD;
        &amp;lt;ImageView android:gravity="center"&#xD;
            android:layout_gravity="center_vertical"&#xD;
            android:layout_width="5dip"&#xD;
            android:layout_height="wrap_content"&#xD;
            android:src="@drawable/tab_split"/&amp;gt;&#xD;
        &amp;lt;ImageView android:id="@+id/discuss_tab_btn"&#xD;
            android:layout_weight="1"&#xD;
            android:layout_width="wrap_content"&#xD;
            android:layout_height="wrap_content"&#xD;
            android:gravity="center_horizontal|bottom"&#xD;
            android:textSize="16dip"&#xD;
            android:src="@drawable/discuss_normal"&#xD;
            android:textColor="#000000"/&amp;gt;&#xD;
        &amp;lt;ImageView android:gravity="center"&#xD;
            android:layout_gravity="center_vertical"&#xD;
            android:layout_width="5dip"&#xD;
            android:layout_height="wrap_content"&#xD;
            android:src="@drawable/tab_split"/&amp;gt;&#xD;
        &amp;lt;ImageView android:id="@+id/identification_tab_btn"&#xD;
            android:layout_weight="1"&#xD;
            android:layout_width="wrap_content"&#xD;
            android:layout_height="wrap_content"&#xD;
            android:gravity="center_horizontal|bottom"&#xD;
            android:textSize="16dip"&#xD;
            android:src="@drawable/identification_normal"&#xD;
            android:textColor="#000000"/&amp;gt;&#xD;
        &amp;lt;ImageView android:gravity="center"&#xD;
            android:layout_gravity="center_vertical"&#xD;
            android:layout_width="5dip"&#xD;
            android:layout_height="wrap_content"&#xD;
            android:src="@drawable/tab_split"/&amp;gt;&#xD;
        &amp;lt;ImageView android:id="@+id/favorite_tab_btn"&#xD;
            android:layout_weight="1"&#xD;
            android:layout_width="wrap_content"&#xD;
            android:layout_height="wrap_content"&#xD;
            android:gravity="center_horizontal|bottom"&#xD;
            android:textSize="16dip"&#xD;
            android:textColor="#000000"&#xD;
            android:src="@drawable/favorite_normal"/&amp;gt;&#xD;
        &amp;lt;ImageView android:gravity="center"&#xD;
            android:layout_gravity="center_vertical"&#xD;
            android:layout_width="5dip"&#xD;
            android:layout_height="wrap_content"&#xD;
            android:src="@drawable/tab_split"/&amp;gt;&#xD;
        &amp;lt;ImageView android:id="@+id/setting_tab_btn"&#xD;
            android:layout_weight="1"&#xD;
            android:layout_width="wrap_content"&#xD;
            android:layout_height="wrap_content"&#xD;
            android:gravity="center_horizontal|bottom"&#xD;
            android:textSize="16dip"&#xD;
            android:src="@drawable/setting_normal"&#xD;
            android:textColor="#000000"/&amp;gt;&#xD;
    &amp;lt;/LinearLayout&amp;gt;&#xD;
    &amp;lt;LinearLayout android:id="@+id/main_tab_container"&#xD;
        android:layout_above="@id/main_tab"&#xD;
        android:layout_below="@id/main_tab_banner"&#xD;
        android:layout_width="fill_parent"&#xD;
        android:layout_height="fill_parent"&#xD;
        android:background="#FFFFE0"&amp;gt;&#xD;
    &amp;lt;/LinearLayout&amp;gt;&#xD;
&amp;lt;/RelativeLayout&amp;gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;其中的main_tab_container是容器布局，到时候动态存放切换的activity的视图。&lt;br /&gt;这时候，效果图如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" alt="" src="http://pic002.cnblogs.com/images/2011/31770/2011090316145711.png" /&gt;&lt;br /&gt;中间的内容为空，tab点击也没有任何效果，我们继续实现。&lt;br /&gt;这就是布局文件main_tab_frame.xml.&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;5.事件效果&lt;/strong&gt;&lt;br /&gt;现在我们把点击效果，切换标题，这些效果关联起来。&lt;br /&gt;选择不同的tab，显示不同的标题，同时切换不同的activity.&lt;br /&gt;以点击评花的主要代码为例子：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;//评花&#xD;
        discussImageView.setOnClickListener(new OnClickListener() {&#xD;
            @Override&#xD;
            public void onClick(View v) {&#xD;
                //标题&#xD;
                mainTabTitleTextView.setText("评花论花");&#xD;
                //切换内容&#xD;
                setContainerView("discuss", DiscussTabActivity.class);&#xD;
                //切换tab页背景                   &#xD;
                appreciateImageView.setImageResource(R.drawable.appreciate_normal);&#xD;
                discussImageView.setImageResource(R.drawable.discuss_press);&#xD;
                identificationImageView.setImageResource(R.drawable.identification_normal);&#xD;
                favoriteImageView.setImageResource(R.drawable.favorite_normal);&#xD;
                settingImageView.setImageResource(R.drawable.setting_normal);&#xD;
            }&#xD;
        });&#xD;
        //切换activity&#xD;
        public void setContainerView(String id,Class&amp;lt;?&amp;gt; activity){&#xD;
            mainTabContainer.removeAllViews();&#xD;
            mainTabIntent = new Intent(this,activity);&#xD;
            mainTabContainer.addView(localActivityManager.startActivity(id, mainTabIntent).getDecorView());&#xD;
        }&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;我们继承ActivityGroup这个类，实现这个完整的类MainTabFrame.java:&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;public class MainTabFrame extends ActivityGroup {&#xD;
    &#xD;
    //Tab Activity Layout&#xD;
    private LocalActivityManager localActivityManager = null;&#xD;
    private LinearLayout mainTabContainer = null;&#xD;
    private Intent mainTabIntent = null;&#xD;
&#xD;
    //Tab banner title&#xD;
    private TextView mainTabTitleTextView = null; &#xD;
    //Tab ImageView&#xD;
    private ImageView appreciateImageView = null;&#xD;
    private ImageView discussImageView = null;&#xD;
    private ImageView identificationImageView = null;&#xD;
    private ImageView favoriteImageView = null;&#xD;
    private ImageView settingImageView = null;&#xD;
    &#xD;
    &#xD;
    @Override&#xD;
    protected void onCreate(Bundle savedInstanceState) {&#xD;
        super.onCreate(savedInstanceState);&#xD;
        setContentView(R.layout.main_tab_frame);&#xD;
        &#xD;
        mainTabContainer = (LinearLayout)findViewById(R.id.main_tab_container);&#xD;
        localActivityManager = getLocalActivityManager();&#xD;
        setContainerView("appreciate", AppreciateTabActivity.class);&#xD;
        &#xD;
        initTab();&#xD;
        &#xD;
    }&#xD;
&#xD;
    &#xD;
    /**&#xD;
     * 初始化Tab项&#xD;
     */&#xD;
    private void initTab() {&#xD;
        mainTabTitleTextView = (TextView)findViewById(R.id.main_tab_banner_title);&#xD;
        appreciateImageView = (ImageView)findViewById(R.id.appreciate_tab_btn);&#xD;
        discussImageView = (ImageView)findViewById(R.id.discuss_tab_btn);&#xD;
        identificationImageView = (ImageView)findViewById(R.id.identification_tab_btn);&#xD;
        favoriteImageView = (ImageView)findViewById(R.id.favorite_tab_btn);&#xD;
        settingImageView = (ImageView)findViewById(R.id.setting_tab_btn);&#xD;
        &#xD;
        //赏花&#xD;
        appreciateImageView.setOnClickListener(new OnClickListener() {&#xD;
            @Override&#xD;
            public void onClick(View v) {&#xD;
                mainTabTitleTextView.setText("欣赏美花");&#xD;
                setContainerView("appreciate", AppreciateTabActivity.class);&#xD;
                appreciateImageView.setImageResource(R.drawable.appreciate_press);&#xD;
                discussImageView.setImageResource(R.drawable.discuss_normal);&#xD;
                identificationImageView.setImageResource(R.drawable.identification_normal);&#xD;
                favoriteImageView.setImageResource(R.drawable.favorite_normal);&#xD;
                settingImageView.setImageResource(R.drawable.setting_normal);&#xD;
            }&#xD;
        });&#xD;
        &#xD;
        //评花&#xD;
        discussImageView.setOnClickListener(new OnClickListener() {&#xD;
            @Override&#xD;
            public void onClick(View v) {&#xD;
                mainTabTitleTextView.setText("评花论花");&#xD;
                setContainerView("discuss", DiscussTabActivity.class);&#xD;
                appreciateImageView.setImageResource(R.drawable.appreciate_normal);&#xD;
                discussImageView.setImageResource(R.drawable.discuss_press);&#xD;
                identificationImageView.setImageResource(R.drawable.identification_normal);&#xD;
                favoriteImageView.setImageResource(R.drawable.favorite_normal);&#xD;
                settingImageView.setImageResource(R.drawable.setting_normal);&#xD;
            }&#xD;
        });&#xD;
        &#xD;
        //识花&#xD;
        identificationImageView.setOnClickListener(new OnClickListener() {&#xD;
            @Override&#xD;
            public void onClick(View v) {&#xD;
                mainTabTitleTextView.setText("亮眼识花");&#xD;
                setContainerView("identification", IdentificationTabActivity.class);&#xD;
                appreciateImageView.setImageResource(R.drawable.appreciate_normal);&#xD;
                discussImageView.setImageResource(R.drawable.discuss_normal);&#xD;
                identificationImageView.setImageResource(R.drawable.identification_press);&#xD;
                favoriteImageView.setImageResource(R.drawable.favorite_normal);&#xD;
                settingImageView.setImageResource(R.drawable.setting_normal);&#xD;
            }&#xD;
        });&#xD;
        &#xD;
        //收藏&#xD;
        favoriteImageView.setOnClickListener(new OnClickListener() {&#xD;
            @Override&#xD;
            public void onClick(View v) {&#xD;
                mainTabTitleTextView.setText("我的收藏");&#xD;
                setContainerView("favorite", FavoriteTabActivity.class);&#xD;
                appreciateImageView.setImageResource(R.drawable.appreciate_normal);&#xD;
                discussImageView.setImageResource(R.drawable.discuss_normal);&#xD;
                identificationImageView.setImageResource(R.drawable.identification_normal);&#xD;
                favoriteImageView.setImageResource(R.drawable.favorite_press);&#xD;
                settingImageView.setImageResource(R.drawable.setting_normal);&#xD;
            }&#xD;
        });&#xD;
        &#xD;
        //设置&#xD;
        settingImageView.setOnClickListener(new OnClickListener() {&#xD;
            @Override&#xD;
            public void onClick(View v) {&#xD;
                mainTabTitleTextView.setText("定义设置");&#xD;
                setContainerView("setting", SettingTabActivity.class);&#xD;
                appreciateImageView.setImageResource(R.drawable.appreciate_normal);&#xD;
                discussImageView.setImageResource(R.drawable.discuss_normal);&#xD;
                identificationImageView.setImageResource(R.drawable.identification_normal);&#xD;
                favoriteImageView.setImageResource(R.drawable.favorite_normal);&#xD;
                settingImageView.setImageResource(R.drawable.setting_press);&#xD;
            }&#xD;
        });&#xD;
    }&#xD;
    &#xD;
    public void setContainerView(String id,Class&amp;lt;?&amp;gt; activity){&#xD;
        mainTabContainer.removeAllViews();&#xD;
        mainTabIntent = new Intent(this,activity);&#xD;
        mainTabContainer.addView(localActivityManager.startActivity(id, mainTabIntent).getDecorView());&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;具体的每个activity怎么显示的，再通过AppreciateTabActivity，DiscussTabActivity，IdentificationTabActivity，FavoriteTabActivity，SettingTabActivity这些独自实现，不再累述。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;6.扩展建议&lt;/strong&gt;&lt;br /&gt;这里补充两点：&lt;br /&gt;(1).标题栏在上述示例中，我是放在MainTabFrame，这样做的好处是，统一了，方便了；这样做的缺点是，如果每个activity的标题栏是不同的按钮，不同的操作，会有些膨胀。所以，标题栏放在主Acvtivity和子Activity中，考虑一下即可。&lt;br /&gt;(2).tab的切换效果，我做的非常简单，具体的图片阴影，凹凸，文字色彩区分都没有去做（本人对Photoshop实在不熟），美化方面还可以大大改进。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;7.小结&amp;nbsp;&lt;/strong&gt;&lt;br /&gt;通过实现这么个简单的主界面框架，能使我们快速的开始我们相应的感兴趣项目，提供了一种大众化得参考，是android学习者必备基础。&amp;nbsp;&lt;br /&gt;这种东西的积累和分析也是能提高我们感觉应用的审美感。&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/qianxudetianxia/aggbug/2155875.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2011/09/03/2155875.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/qianxudetianxia/archive/2011/08/28/2155872.html</id><title type="text">Android学习系列(22)--App主界面比较</title><summary type="text">本文算是一篇漫谈，谈一谈当前几个流行应用的主界面布局，找个经典的布局我们自己也来实现一个。不是为了追求到底有多难，而是为了明白我们确实需要这么做。走个题，android的UI差异化市场依然很大，依然值得去挖掘。铸就经典，是为了超越经典！下面我们以下面10个应用来分析比较它们的主界面：1.QQ20112.新浪微博3.凤凰周刊4.小米读书5.微信6.太平洋电脑网7.360卫士8.Camera3609.大众点评网10.挖财1.QQ2011QQ应用最新版本QQ2011 Beta3，从最新的版本看，界面比之前简洁了一些。我以夜间模式为例子：从图中可以看出来，QQ分为3大模块：空间动态，QQ聊天，其他QQ</summary><published>2011-08-28T02:33:00Z</published><updated>2011-08-28T02:33:00Z</updated><author><name>谦虚的天下</name><uri>http://www.cnblogs.com/qianxudetianxia/</uri></author><link rel="alternate" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/08/28/2155872.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/08/28/2155872.html"/><content type="html">&lt;p&gt;本文算是一篇漫谈，谈一谈当前几个流行应用的主界面布局，找个经典的布局我们自己也来实现一个。&lt;br /&gt;不是为了追求到底有多难，而是为了明白我们确实需要这么做。&amp;nbsp;&lt;br /&gt;走个题，android的UI差异化市场依然很大，依然值得去挖掘。&amp;nbsp;&lt;br /&gt;铸就经典，是为了超越经典！&lt;br /&gt;下面我们以下面10个应用来分析比较它们的主界面：&lt;br /&gt;&lt;em&gt;1.QQ2011&lt;/em&gt;&lt;br /&gt;&lt;em&gt;2.新浪微博&lt;/em&gt;&lt;br /&gt;&lt;em&gt;3.凤凰周刊&lt;/em&gt;&lt;br /&gt;&lt;em&gt;4.小米读书&lt;/em&gt;&lt;br /&gt;&lt;em&gt;5.微信&lt;/em&gt;&lt;br /&gt;&lt;em&gt;6.太平洋电脑网&lt;/em&gt;&lt;br /&gt;&lt;em&gt;7.360卫士&lt;/em&gt;&lt;br /&gt;&lt;em&gt;8.Camera360&lt;/em&gt;&lt;br /&gt;&lt;em&gt;9.大众点评网&lt;/em&gt;&lt;br /&gt;&lt;em&gt;10.挖财&lt;/em&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.QQ2011&lt;/strong&gt;&lt;br /&gt;QQ应用最新版本QQ2011 Beta3，从最新的版本看，界面比之前简洁了一些。&lt;br /&gt;我以夜间模式为例子：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082800344088.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;从图中可以看出来，QQ分为3大模块：空间动态，QQ聊天，其他QQ应用。这些最大的模块现实在底部&lt;br /&gt;因为QQ聊天业务本身也有很多重要东西，如好友，qq群，历史记录等等，所以qq聊天在上部分又分成3部分了。这也算是较大的模块。&lt;br /&gt;基本上这么一分，qq上该用的东西我们都能直觉上都看的见，寥寥数笔，就已经勾画出最基本最重要的轮廓。&lt;br /&gt;除此之外，qq有大量的设置和子功能，如状态设置，搜索好友，添加好友，皮肤设置等等， qq做法很简单，就是分类分级，然后通过menu菜单显示。&lt;br /&gt;因为这部分功能不是聊天的最主要的需求，这样分类分级非常的合理，不影响用户界面，又能无声无影的添加到应用中。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082800503750.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;总而言之，qq能把这么多斑驳的功能融合一体，简约而不失强大，合理而不失风采。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.新浪微博&lt;/strong&gt;&lt;br /&gt;新浪微博很早的版本给我得印象好像是挺垃圾的，不知道什么时候升级的，现在的界面看行。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082801002162.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;br /&gt;这个界面就不比qq了：&lt;br /&gt;底部bottom则是业务划分。&lt;br /&gt;顶部banner为当前页面的一个标题（主要标志），能携带若干功能的快捷方式；&amp;nbsp;&lt;br /&gt;qq之前的版本好像也是这种划分，这种布局的特点就是简简单单，大众化，用户一打开就知道怎么找相应的功能。&lt;br /&gt;缺点就是大众化，没什么特色，不够炫。&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.凤凰周刊&lt;/strong&gt;&lt;br /&gt;凤凰周刊的主界面不是一般的简陋：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082801143354.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;br /&gt;模块的划分在顶部，这种布局个人觉得不如在底部进行模块的划分。&lt;br /&gt;主要是这个应用是提供杂志下载的，并没有提供其他的功能和设置，不然在顶部简单的划分，打开界面第一眼就看到一排模块挤挤的，确实不大美观。&lt;br /&gt;而且最重要的是，它和新浪微博的布局比较，无形中少了顶部banner，导致无法直接添加若干主要的功能快捷方式。&lt;br /&gt;所以说，这个布局的特点就是简单，简单还是简单，对应用的要求也是要简单。&lt;br /&gt;顺便扯一个，其实凤凰移动台的应用主界面还是挺大气的：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082801244349.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4.小米读书、微信、太平洋电脑网、挖财&lt;/strong&gt;&lt;br /&gt;这几个应用的主界面和新浪微博接近，一个top&amp;nbsp;banner+ bottom menu,在bottom中划分模块，在top中做功能切入点，如果子模块还需要划分，则top banner下面增加一个类似bottom的业务模块划分。&lt;/p&gt;&#xD;
&lt;p style="text-align: center;"&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082809354452.png" alt="" /&gt;&amp;nbsp;&amp;nbsp;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082809362225.png" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;p style="text-align: center;"&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082809373955.png" alt="" /&gt;&amp;nbsp;&amp;nbsp;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082809395097.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这种布局的特点就是模块划分分明，每个模块在第一界面能携带一两个功能或者功能快捷方式。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;5.360卫士、大众点评网、Camera360&lt;/strong&gt;&lt;br /&gt;下面这几个应用的界面又是一类，它们或许也有bottom的模块划分，但是它们更喜欢把功能通过更直接的方式显示在界面的正中央，这样做的目的是凸显这些功能在此应用的重要性，而的确如此，没有这些功能，或者看不到这些功能，我们甚至就不知道这个应用意欲何为，如何使用等等。&lt;/p&gt;&#xD;
&lt;p style="text-align: center;"&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082809374889.png" alt="" style="border-style: initial; border-color: initial;" /&gt;&amp;nbsp;&amp;nbsp;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082809500417.png" alt="" /&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082809515962.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这类应用与前面的应用最大的不同，应该从应用本身的服务目的来分析，这类应用强调的是用户的主动交互性，而前面应用强调的是提供用户最新的资讯。&lt;br /&gt;目的不同，界面的设计相应的不同，各尽其用，都非常的合理。&lt;br /&gt;当然，这类应用主界面布局和前面布局的不同，从效果上强调二级功能点，而且掩盖了直接内容，从这点上资讯类应用一般不采用这种布局，但是反过来这类应用布局却可以采用资讯类布局，比如360卫士就介如两者之间。&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;6.小结&lt;/strong&gt;&lt;br /&gt;从上面我们看到这些流行应用的主要布局方式，各有特点。&lt;br /&gt;本文只是从整体布局分析，并没有考虑局部布局和色彩调配的因素。&lt;br /&gt;接下来我们选择第四种模式作为我们的经典模式，草图如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082810305547.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;下篇文章中我们来实现这样的一个经典界面。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/qianxudetianxia/aggbug/2155872.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2011/08/28/2155872.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/qianxudetianxia/archive/2011/08/20/2147011.html</id><title type="text">Android设计模式系列(8)--SDK源码之工厂方法模式</title><summary type="text">工厂方法模式，往往是设计模式初学者入门的模式，的确，有人称之为最为典型最具启发效果的模式。android中用到了太多的工厂类，其中有用工厂方法模式的，当然也有很多工厂并不是使用工厂方法模式的，只是工具管理类。今天以ThreadFactory举例说明一下简单工厂模式和工厂方法模式。工厂方法模式，Factory Method,简单的方式，不简单的应用。1.意图定义一个用于创建对象的接口，让子类决定实例化哪个类。工厂方式模式使一个类的实例化延迟到其子类。热门词汇:虚构造器 延迟 创建对象 子类2.结构图和代码我们先看看标准的工厂方法结构图：先抽象的产品类，抽象的工厂类，然后用客户端具体的工厂生产相应</summary><published>2011-08-20T03:07:00Z</published><updated>2011-08-20T03:07:00Z</updated><author><name>谦虚的天下</name><uri>http://www.cnblogs.com/qianxudetianxia/</uri></author><link rel="alternate" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/08/20/2147011.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/08/20/2147011.html"/><content type="html">&lt;p&gt;工厂方法模式，往往是设计模式初学者入门的模式，的确，有人称之为最为典型最具启发效果的模式。&lt;br /&gt;android中用到了太多的工厂类，其中有用工厂方法模式的，当然也有很多工厂并不是使用工厂方法模式的，只是工具管理类。&lt;br /&gt;今天以ThreadFactory举例说明一下简单工厂模式和工厂方法模式。&amp;nbsp;&lt;br /&gt;工厂方法模式，Factory Method,简单的方式，不简单的应用。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.意图&lt;/strong&gt;&lt;br /&gt;定义一个用于创建对象的接口，让子类决定实例化哪个类。工厂方式模式使一个类的实例化延迟到其子类。&lt;br /&gt;热门词汇:&lt;em&gt;&lt;strong&gt;虚构造器 延迟 创建对象 子类&lt;/strong&gt;&lt;/em&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.结构图和代码&lt;/strong&gt;&lt;br /&gt;我们先看看标准的工厂方法结构图：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082010063542.jpg" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;br /&gt;先抽象的产品类，抽象的工厂类，然后用客户端具体的工厂生产相应的具体的产品，但是客户端并不知道具体的产品是怎么生产的，生产的过程封装在工厂里。所以说，某种程度上，工厂方法模式改变了我们直接用new创建对象的方式，一个很好的开始，意义重大。&lt;br /&gt;以ThreadFactory为例：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082010345754.jpg" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这张图其实和原本的结构图有细微的区别，那就是参数化得工厂，而且从业务意义上也有些不同，但是思想是一样的。&lt;br /&gt;我们来看下具体的代码：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;//抽象产品&#xD;
public interface Runnable {&#xD;
    public abstract void run();&#xD;
}&#xD;
&#xD;
//抽象工厂&#xD;
public interface ThreadFactory {&#xD;
    Thread newThread(Runnable r);&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;下面是具体的实现：&lt;br /&gt;比如AsyncTask类中工厂的具体实现如下：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;//工厂实现类&#xD;
    private static final ThreadFactory sThreadFactory = new ThreadFactory() {&#xD;
        private final AtomicInteger mCount = new AtomicInteger(1);&#xD;
&#xD;
        public Thread newThread(Runnable r) {&#xD;
            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());&#xD;
        }&#xD;
    };&#xD;
    //那么产品类在哪里呢？&#xD;
    //做为参数Runnable r，我们可以创建千千万万个此系列的产品类&#xD;
    //同理，我们可以创建另外类似的工厂，生产某种专门的线程，非常容易扩展&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;看到这里，我们一方面为它的生产便利性感叹，一方面又为没创建某类产品都要创建一个工厂而感到繁琐，所以我们下面介绍简单工厂，它的结构图如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082010462450.jpg" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;br /&gt;简单工厂把抽象工厂去掉了，你就创建一个专门生产某类产品就好。在一些特定而又不负责的领域非常实用方便套用这个模式。&lt;br /&gt;在android中的Connection类中使用到了这个类：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011082010544272.jpg" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;br /&gt;其中Connection这个抽象类，既充当抽象产品类，也充当具体工厂类。&lt;br /&gt;因为这种情况下，我们往往需要的是马上生产子类，getConnection方法往往是静态的，所以简单工厂，也叫静态工厂方法。&lt;br /&gt;我们看看代码如下：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;abstract class Connection{    &#xD;
    static Connection getConnection(&#xD;
            Context context, HttpHost host, HttpHost proxy,&#xD;
            RequestFeeder requestFeeder) {&#xD;
&#xD;
        if (host.getSchemeName().equals("http")) {&#xD;
            return new HttpConnection(context, host, requestFeeder);&#xD;
        }&#xD;
&#xD;
        // Otherwise, default to https&#xD;
        return new HttpsConnection(context, host, proxy, requestFeeder);&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;这就是简单工厂，一个很简单的参数化工厂，真的很简单。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.效果&lt;/strong&gt;&lt;br /&gt;1. 创建型模式;&lt;br /&gt;2.参数化工厂方法模式得到相应的对象;&lt;br /&gt;3.为子类提供挂钩;&lt;br /&gt;4.连接平行的类层次。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/qianxudetianxia/aggbug/2147011.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2011/08/20/2147011.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/qianxudetianxia/archive/2011/08/13/2135478.html</id><title type="text">Android设计模式系列(7)--SDK源码之命令模式</title><summary type="text">命令模式，在.net，java平台的事件机制用的非常多，几乎每天都与之打交道。android中对我印象最深的就是多线程多进程的环境，所以必然大量使用到Runbable,Thread,其实用的就是最简单的命令模式。命令模式，Command Pattern，把请求封装为一个对象，多么巧妙的一个说法啊。1.意图将一个请求封装为一个对象，从而使你可用不同的请求对客户进行参数化，对请求排队或记录请求日志，以及支持可撤销的操作。热门词汇：动作 事物 请求封装 排队 打包 异步2.结构Command接口提供了Execute方法，客户端通过Invoker调用命令操作来调用Recriver，绕了一大圈，但是却把</summary><published>2011-08-12T16:36:00Z</published><updated>2011-08-12T16:36:00Z</updated><author><name>谦虚的天下</name><uri>http://www.cnblogs.com/qianxudetianxia/</uri></author><link rel="alternate" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/08/13/2135478.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/08/13/2135478.html"/><content type="html">&lt;p&gt;命令模式，在.net，java平台的事件机制用的非常多，几乎每天都与之打交道。&lt;br /&gt;android中对我印象最深的就是多线程多进程的环境，所以必然大量使用到Runbable,Thread,其实用的就是最简单的命令模式。&lt;br /&gt;命令模式，Command Pattern，把请求封装为一个对象，多么巧妙的一个说法啊。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.意图&lt;/strong&gt;&lt;br /&gt;将一个请求封装为一个对象，从而使你可用不同的请求对客户进行参数化，对请求排队或记录请求日志，以及支持可撤销的操作。&lt;br /&gt;热门词汇：&lt;em&gt;&lt;strong&gt;动作 事物 请求封装 排队 打包 异步&lt;/strong&gt;&lt;/em&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.结构&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011081300080980.jpg" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;br /&gt;Command接口提供了Execute方法，客户端通过Invoker调用命令操作来调用Recriver，绕了一大圈，但是却把具体对Receiver的操作请求封装在具体的命令中，是客户端对recriver的操作清晰简明。&lt;br /&gt;但是在实际项目中，我们常常忽略Receiver，而把命令对象的目标对象直接设置为子类自己的成员变量或者作为execute()方法的临时变量。&lt;br /&gt;以Android中的Runnable(在java.lang包下)为例，我们画出UML结构图如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011081300184744.jpg" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;br /&gt;想不到我们天天写的代码无意识中就是用到了命令模式，所谓模式，就是无所不在。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.代码&lt;/strong&gt;&lt;br /&gt;命令接口Runnable定义如下：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;public interface Runnable {&#xD;
    public abstract void run();&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;调用者Thread简化版代码：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;//命令模式这里不需要继承Runnable接口，但是这里考虑到实际情况，比如方便性等，继承了Runnable接口，实现了run方法，这个是Thread自身的运行run的方法&#xD;
class Thread implements Runnable {&#xD;
    private Runnable target;&#xD;
    &#xD;
    public Thread(Runnable target) {&#xD;
        this.target = target;&#xD;
    }&#xD;
&#xD;
     public synchronized void start() {&#xD;
&#xD;
        if (threadStatus != 0 || this != me)&#xD;
            throw new IllegalThreadStateException();&#xD;
        group.add(this);&#xD;
        start0();//这个是本地方法，调用run方法&#xD;
        if (stopBeforeStart) {&#xD;
	    stop0(throwableFromStop);&#xD;
	}&#xD;
    }&#xD;
&#xD;
    //可选&#xD;
    public void run() {&#xD;
	if (target != null) {&#xD;
	    target.run();&#xD;
	}&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;客户端只需要new Thread(new Runnable(){}).start()就开始执行相关的一系列的请求，这些请求大部分都是实现Runnable接口的匿名类。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4.效果&lt;/strong&gt;&lt;br /&gt;(1).行为型模式;&lt;br /&gt;(2).将调用对象的操作和知道如何实现该操作的对象解耦;&lt;br /&gt;(3).多个命令可以装配成一个复合命令;&lt;br /&gt;(4).增加新的命令很容易。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/qianxudetianxia/aggbug/2135478.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2011/08/13/2135478.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/qianxudetianxia/archive/2011/08/10/2133659.html</id><title type="text">Android设计模式系列(6)--SDK源码之享元模式</title><summary type="text">享元模式,给我的感觉就是对象池，缓存单例对象。java中的享元模式最经典的例子就是String类了，还有一个最容易理解的就是word文档字符共享的例子，也是享元模式的经典应用。本文对android中的sql编译类SQLiteCompiledSql说明，展开分析，也是很容易理解的一个例子，其实，android SDK中必然有很多地方需要用到享元模式。享元模式，Flyweight Pattern,说的严重点，一些程序如果不使用享元模式的话，根本不能使用面向对象的方法实现，对象会多的撑爆你的内存：&amp;quot;用面向对象思想设计的应用常常会面临对象实例过多的问题&amp;quot;。1.意图运用共享技术有效地</summary><published>2011-08-10T14:00:00Z</published><updated>2011-08-10T14:00:00Z</updated><author><name>谦虚的天下</name><uri>http://www.cnblogs.com/qianxudetianxia/</uri></author><link rel="alternate" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/08/10/2133659.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/qianxudetianxia/archive/2011/08/10/2133659.html"/><content type="html">&lt;p&gt;享元模式,给我的感觉就是对象池，缓存单例对象。&lt;br /&gt;java中的享元模式最经典的例子就是String类了，还有一个最容易理解的就是word文档字符共享的例子，也是享元模式的经典应用。&lt;br /&gt;本文对android中的sql编译类SQLiteCompiledSql说明，展开分析，也是很容易理解的一个例子，其实，android SDK中必然有很多地方需要用到享元模式。&lt;br /&gt;享元模式，Flyweight &amp;nbsp;Pattern,说的严重点，一些程序如果不使用享元模式的话，根本不能使用面向对象的方法实现，对象会多的撑爆你的内存："用面向对象思想设计的应用常常会面临对象实例过多的问题"。&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.意图&lt;/strong&gt;&lt;br /&gt;运用共享技术有效地支持大量细粒度的对象。&lt;br /&gt;热门词汇：&lt;em&gt;&lt;strong&gt;共享 池 缓存 内部状态 外部状态 对象 单例&lt;/strong&gt;&lt;/em&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.结构&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011081020345567.jpg" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;br /&gt;这是一个完整的享元模式结构图。&lt;br /&gt;客户端通过享元工厂获取享元对象，享元对象的创建则根据工厂的享元池来控制，如果有享元池中没有这个对象，则创建这个对象并保存到享元池中，如果享元池中有这个对象，则直接使用这个对象。因为享元对象在共享的同时，说明它重用属性的不变性，不然都是变化的东西，不存在共享，这些不变得属性我们称之为内部状态，独立与外部场景。而另外一些属性，可以根据外部场景变化的，我们称之为外部状态，在上图中我们也看到，我们可以通过Operation改变外部状态。&lt;br /&gt;Android中SQLiteCompiledSql的使用，其实是很多数据库系统典型的实现。从应用启动，通过各种数据库操作，我们不知道进行了多少次的查询操作，而这些操作中又有相当一部分sql语句是相同的，这些编译后的sql编译对象其实是一样的，是可以共用共享的，其实就是缓存。SQLiteCompiledSql就是这样的一个需要共享的享元对象，画出相关的UML图如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/31770/2011081021412432.jpg" alt="" style="display: block; margin-left: auto; margin-right: auto;" /&gt;&lt;br /&gt;其中SqliteDatabase中的mCompiledQuerie就是存放享元对象的容器。&lt;br /&gt;通过这种方式大大减少了sql编译对象的创建，提高了数据库操作的性能。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.代码&lt;/strong&gt;&lt;br /&gt;享元对象类SQLiteCompiledSql，主要是内部状态sql语句：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;class SQLiteCompiledSql {&#xD;
    private String mSqlStmt = null;&#xD;
    native_compile(sql); &#xD;
    native_finalize();&#xD;
}&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;享元工厂类：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;public class SQLiteDatabase{&#xD;
     Map&amp;lt;String, SQLiteCompiledSql&amp;gt; mCompiledQueries = Maps.newHashMap();&#xD;
     SQLiteCompiledSql getCompiledStatementForSql(String sql) {&#xD;
        SQLiteCompiledSql compiledStatement = null;&#xD;
        boolean cacheHit;&#xD;
        synchronized(mCompiledQueries) {&#xD;
            if (mMaxSqlCacheSize == 0) {&#xD;
                return null;&#xD;
            }&#xD;
            cacheHit = (compiledStatement = mCompiledQueries.get(sql)) != null;&#xD;
        }&#xD;
        if (cacheHit) {&#xD;
            mNumCacheHits++;&#xD;
        } else {&#xD;
            mNumCacheMisses++;&#xD;
        }&#xD;
        return compiledStatement;&#xD;
    }&#xD;
&#xD;
    private void deallocCachedSqlStatements() {&#xD;
        synchronized (mCompiledQueries) {&#xD;
            for (SQLiteCompiledSql compiledSql : mCompiledQueries.values()) {&#xD;
                compiledSql.releaseSqlStatement();&#xD;
            }&#xD;
            mCompiledQueries.clear();&#xD;
        }&#xD;
    }&#xD;
&#xD;
    void addToCompiledQueries(String sql, SQLiteCompiledSql compiledStatement) {&#xD;
         //省略具体代码&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;其他类几个相关类是对这个集合的操作相关，和享元模式没有什么实质性的关系，代码省略。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4.效果&lt;br /&gt;&lt;/strong&gt;(1).结构型模式;&lt;br /&gt;(2).节约存储的方法：用共享减少内部状态的消耗，用计算时间换取对外部状态的存储;&lt;br /&gt;(3).缓冲。&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/qianxudetianxia/aggbug/2133659.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/qianxudetianxia/archive/2011/08/10/2133659.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
