50 Android Hacks(hack 2)

接触到一本涉及android编程技巧的书,叫做《50 Android Hacks》,作者:Carlos Sessa。然后从网上找了一下这本书的译本,居然发现没有免费中文版的,所以和技术群里的小伙伴们商量翻译一下,以飨程序猿。后来发现初衷虽好,但是路漫漫,每天下班的一点时间充斥着乱七八糟的事,所以就先以博客的形式,以单个技巧为单位发到博客上,最后再整理成完整的pdf。希望大家用的上。

在翻译中,我尽量的保持了原来语句的语义,但是受“chinese english”的影响,也难免有偏差,希望大家批评指正。凡是android涉及到的词汇,我一般就不译成中文了,以免出现偏差,比如View,一般情况下我没有翻译成“视图”,以免中文丰富的近义词影响阅读。另外,我只翻译了文章的主体,即技巧,其他部分(目录,前沿,序...)都没有翻译,如果有小伙伴想看这部分,可以自行翻译。


技巧2 使用快捷导入来避免重复


       当你在创建一个复杂的布局时,你会发现你增加了很多的ViewGroups和Views。但是你的视图树越高,软件将越慢。创建优化的层级结构是创建运行速度快、与用户良好交互的程序基础。

      在本技巧中,你将学到在XML中如何使用<include/>标签来避免重复,还有如何使用ViewStub类来快捷导入视图。   

2.1 使用<include />标签避免重复

让我们想一下,如果我们要在每一个视图下加一个脚标--简单的一个例子,比如要在应用程序中一个用TextView显示应用程序的名字。如果我们有很多个Activity,可能有几个XML文件,我们要把这个TextView复制到每一个xml中吗?如果我们将来需要编辑这个内容会怎么样?复制并黏贴可能解决问题,但是这看起来不高效。最简单的办法是用<include/>在程序中增加一个脚标。让我们看看这会怎么帮助我们。

       在一个的XML文件中使用<include />来加入一个另外的layout。在我们的例子中,我们将创建完整的视图,在底部,我们增加了<include/>标签指向脚标层。其中一个Activity的xml文件如下描述:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center_horizontal"
        android:text="@string/hello" />
    
    <include layout="@layout/footer_with_layout_properties"/>
    
</RelativeLayout>

Footer_with_layout_properties如下描述:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="30dp"
    android:gravity="center_horizontal"
    android:text="@string/footer_text" />

        在第一个例子中,我们使用标签<include />引入唯一需要的layout。你可能会想,“好吧,之所以会起作用,因为主XML使用了RelativeLayout布局。如果其中一个XML是LinearLayout会怎么样?android:layout_alignParentBottom=”true”将不会起作用,因为它是相对布局的一个属性。”是的,是这样。让我们看看第二种使用includes的方法,这里我们将在<include />中放置android:layout_*属性。

        以下是修改了的main.xml,在<include />中使用了android:layout_*属性。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    
	<TextView
	  android:layout_width="fill_parent"
	  android:layout_height="wrap_content"
	  android:layout_centerInParent="true"
	  android:gravity="center_horizontal"
	  android:text="@string/hello" />
	
	<include 
	    layout="@layout/footer"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:layout_alignParentBottom="true"
	    android:layout_marginTop="30dp"/>

</RelativeLayout>
以下是修改了的footer.xml
xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"
    android:text="@string/footer_text" />

        在第二个例子中,我们将让包含footer的容器决定在什么地方放置它。安卓的事件跟踪器报告了一件事情,它说<include />标签奔溃了(引用的层参数没有其作用)。有时是这样的。问题在于,如果我们想引用任何android:layout_*属性,<include />标签必须同时指定android:layout_width和android:layout_height。

       注意在该技巧里一个我们做过了的细节。正如在第二个例子中看到的,我们把每一个android:layout_*挪到了<include />里。看看footer.xml里我们设定的宽度和高度—都是0dp。我们这样做是确保当使用<include />时指定了一个宽度和高度。如果使用者不加这些,他们将看不到footer,因为都是0.

       

2.2 使用ViewStub类快捷导入视图

       当设计布局时,你可能考虑过依赖内容或用户的交互来显示一个视图。如果你曾经让一个视图不可见,然后让它可见,你应该读下去-----你将会喜欢上ViewStub类。

       让我们看看Android文档(2.4节),里面对ViewStub类做了介绍。

              ViewStub是一个不可见的、0尺寸的视图,它能在运行时导入布局资源。当设置ViewStub可见时,或当inflate()被激发时,布局资源被显示。ViewStub然后用显示了布局资源的View或Views替换自己。

       你已经知道了ViewStub是什么了,所以我们看看能用它做些什么。接下来的例子,你会使用ViewStub快捷导入一个MapView。想想创建位置视图的细节。看看下面两个可能的情形:

    ●一些地方没有GPS信号。

    ●使用者可能不需要地图。

       如果该地没有GPS信号,你不可能在地图上放置标记,如果使用者不需要地图,为什么要加载?我们把MapView放入ViewStub里,让用户决定是否加载地图。

       用以下布局实现来实现:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:onClick="onShowMap"
        android:text="@string/show_map" />

    <ViewStub
        android:id="@+id/map_stub"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:inflatedId="@+id/map_view"
        android:layout="@layout/map" />
</RelativeLayout>

很明显,我们使用map_stubID从Activity获取ViewStub,layout属性告诉了ViewStub加载哪个布局。在该示例中,我们使用以下的地图布局:

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.maps.MapView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clickable="true"
android:apiKey="my_api_key"/>

我们需要讨论最后一个属性inflatedID。inflatedId是加载了布局的视图的ID,该加载过程发生在ViewStub类里的infalte()或setVisibility()方法调用之后。在该示例中,我们使用了setVisibility(View.VISIBLE),因为我们除了MapView不做其他任何事情。如果我们想获取视图的引用,inflate()方法会返回视图,并避免二次调用findViewById()。

       Activity的代码比较简单:

publicclass MainActivity extends MapActivity {

  private View mViewStub;

  @Override

  publicvoid onCreate(BundlesavedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    mViewStub = findViewById(R.id.map_stub);

  }

 

  publicvoid onShowMap(View v) {

    mViewStub.setVisibility(View.VISIBLE);

  }

  ...

}

正如你看到的,当我们需要显示地图时,只要改变ViewStub的可视性就行了。

2.3 概述

       <include/>是规范布局的一个有用工具。如果你用Fragment类创建了一些东西,你会发现使用包含可以做同样的事情。和用Fragment需要做的一样,你的完整的视图应该是一些列的包含(includes)。

       <include/>标签提供了很好的方法来组织XML文件的内容。如果你正在制作一个复杂的布局,XML将会很大,试试用包含(include)创建不同的部分。XML会变得简单易读,组织性更强。

       ViewStub是用来导入视图的极好的类。无论何时你要根据内容隐藏一个视图、还是使它变得可见、试试用ViewStub。或许当只有一个视图时,你注意不到性能上的表现,但是如果你有很多视图时会发现。









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值