Android用户界面设计
2012-11-07 22:01
253 查看
Android用户界面设计
Android用户界面设计:使用片段Android 3.0引入的新的片断(Fragment)API,让我们更容易地创建动态用户界面。在这个教程中,我们学习如何将一个两屏的ListView转换成WebView流,以适应大屏幕的单屏流设计,比如在平板设备中。
这篇文章的节奏将比我们的入门教程更快一些。如果你对基本的Android控件或概念不熟悉你可能需要复习这个网站上我们其它的一些教程,甚至是Android API参考。最终的开源代码可以在Google code上下载到。
片段简介
在我们开始之间,让我们在更高的层次上定义一下什么是片段。通常来说,片段是一大块用户界面,它具有自己的生存周期。如果它听起来像一个Activity,那是因为它确实很像一个Activity。然而,片段与Activity不同,片段必须存在于Activity之内。片段不须要在它每次初始化的时候与同一个Activity配对,这使它具有一些灵活性。与Activity一样,片段也无需包含任何用户界面。
步骤0:开始
这个教程假设你读过我们的列表视图教程,你可以下载那个教程的代码,并完成一些任务,然后开始,也可以直接下载这个教程的代码直接开始。
步骤1:重新设计界面
下图示意了我上在列表视图教程中所提到的文章阅读应用,我们还没有考虑并使用片段:
这个流程在相对小屏幕上运行得很不错。然而,在大屏幕上,比如Motorola Xoom平板的10寸屏幕上,在列表视图上却浪费了很多空间。WebView看起来正常,但是有点枯燥。
这就是要引入片段的地方:在大屏幕上,我们可以提供更有效的用户界面,如果我们可以在同一屏上显示ListView和WebView。当用户点击左边“面板”的列表视图中的某一项时,右边的WebView更新显示相应的内容。这种工作流程经常用于email或文档或RSS阅读器。下图就是重新设计之后的界面示意图:
步骤2:转换为基于片段的设计
现在我们知道了新的流程应该如何设计,我们也知道当前的两个活动必须转换成片段。我们将分几步来完成这个转换。第一步保持界面样子不变,只是使用片段修改每个界面内容。一个片段将包含当前的ListView,另一个包含WebView。然后我们再转到单个屏幕的实现,修改ListView和WebView之间的消息传递。
首先,将你的程序的项目构建目标改变Android 3.0。在Eclipse中,右键点击项目并选择“属性”。点击Android部分并选中Android 3.0。我们不使用任何Google API,所以Android开源项目版本足够了。然后点击“确定”按钮。
现在你就可以访问新的API了,包括片段API。
注意:在将来的教程中,我们将讨论如何使用新的兼容层来使得像片段API这样的技术在更早版本的Android设备上也能工作。但是现在它只能运行在Android 3.0设备上。
步骤3:创建片段类
创建两个Java类来代表两个片段:ListView界面和WebView界面。将它们命名为TutListFragment和TutViewerFragment。TutListFragment将继承ListFragment类,TutViewerFragment只是继承Fragment类。
在TutListFragment类中,我们需要重写两个方法: onListItemClick()和onCreate()。这些方法的内容看起来应该很熟悉,它与之前我们讲过的TutListActivity类的代码一致。这个代码很快就要修改,但是现在暂时不需要,下面是当前TutListFragment类的代码:
@Override public void onListItemClick(ListView l, View v, int position, long id) { String[] links = getResources().getStringArray(R.array.tut_links); String content = links[position]; Intent showContent = new Intent(getActivity().getApplicationContext(), TutViewerActivity.class); showContent.setData(Uri.parse(content)); startActivity(showContent); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setListAdapter(ArrayAdapter.createFromResource(getActivity() .getApplicationContext(), R.array.tut_titles, R.layout.list_item)); } |
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Intent launchingIntent = getActivity().getIntent(); String content = launchingIntent.getData().toString(); WebView viewer = (WebView) inflater.inflate(R.layout.tut_view, container, false); viewer.loadUrl(content); return viewer; } |
步骤4:添加片段布局资源
现在创建一个新的名为“tutlist_fragment.xml”的布局文件来表示包含文章列表的片段。片段布局资源使用你创建的Fragment类的标签和引用。
<?xml version="1.0" encoding="utf-8"?> <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:name="com.mamlambo.tutorial.tutlist.TutListFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/tutlist_fragment"> </fragment> |
<?xml version="1.0" encoding="utf-8"?> <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:name="com.mamlambo.tutorial.tutlist.TutViewerFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/tutview_fragment"> </fragment> |
TutListActivity和TutViewerActivity类必须修改。TutListActivity类只有一个方法,onCreate(),现在需要修改它来加载你在前一步创建的合适的片段布局资源,如下:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.tutlist_fragment); } |
TutViewerActivity类也需要类似的修改,它的onCreate()方法现在看起来像这样:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.tutview_fragment); } |
尝试现在运行程序。你会发现它和以前一样。没什么值得兴奋的,不是么?然而,整个用户界面现在使用片段来运行了。这使你需要做的下一步修改更加平滑,我们添加一个新的布局来组合两个片段以在一个界面上显示。然而可能你也注意到了,片段之间的通信的处理和我们文章之间的通信一样。事实上,我们每个片段对应的活动保持不变。当一个活动包含并管理两个片段时,这将不符合需求。首先让我们来修复它。
步骤7:改变TutListFragment通信
像你在步骤3中学到的一样,从TutListFragment对象直接启动一个活动不再有效了。WebView UI可能与列表是同一个活动的一部分——总之那就是我们对于大屏幕的计划。在那种情况下,我们只想在第二个片段中更新WebView的URL。
做这些修改,我们需要做几件事情。首先,我们让片段不依赖于它们所在的活动。要做到这一点,在TutListFragment类中添加一个侦听器,如下:
public interface OnTutSelectedListener { public void onTutSelected(Uri tutUri); } |
@Override public void onListItemClick(ListView l, View v, int position, long id) { String[] links = getResources().getStringArray(R.array.tut_links); String content = links[position]; tutSelectedListener.onTutSelected(Uri.parse(content)); } |
public class TutListActivity extends Activity implements TutListFragment.OnTutSelectedListener { ... @Override public void onTutSelected(Uri tutUri) { Intent showContent = new Intent(getApplicationContext(), TutViewerActivity.class); showContent.setData(tutUri); startActivity(showContent); } } |
步骤8:改变TutViewerFragment通信
现在让我们把注意力转到TutViewerFragment类上,它的代码也需要修改。片段不再查询启动目标来找出加载哪个URL,而是等待被通知要加载哪个URL。在样,我们可以直接修改WebView而不需要每次加载都重新创建片段。
首先,修改TutViewerFragment类,让它包含一个叫做updateUrl()的方法:
public void updateUrl(String newUrl) { if (viewer != null) { viewer.loadUrl(newUrl); } } |
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.tutview_fragment); Intent launchingIntent = getIntent(); String content = launchingIntent.getData().toString(); TutViewerFragment viewer = (TutViewerFragment) getFragmentManager() .findFragmentById(R.id.tutview_fragment); viewer.updateUrl(content); } |
步骤9:添加双片段布局
现在让我们来创建带有两个片段的布局,以供特定情况使用。在layout-land目录(你可能需要自己创建),粘贴一份tutlist_fragment.xml。它将对横屏和竖屏提供不同的布局。竖屏模式将保持不变。编辑这个文件如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <fragment android:name="com.mamlambo.tutorial.tutlist.TutListFragment" android:layout_width="0dp" android:layout_height="match_parent" android:id="@+id/tutlist_fragment" android:layout_weight="45"> </fragment> <fragment android:name="com.mamlambo.tutorial.tutlist.TutViewerFragment" android:layout_width="0dp" android:layout_height="match_parent" android:id="@+id/tutview_fragment" android:layout_weight="55"> </fragment> </LinearLayout> |
步骤10:添加动态选项
现在我们可以为程序添加一些简单的逻辑,可以在启动一个新的活动(双屏模式)和更新存在的片段(单屏模式)之间切换。
为了达到这个目的,更新TutListActivity类的onTutSelected()方法如下:
@Override public void onTutSelected(String tutUrl) { TutViewerFragment viewer = (TutViewerFragment) getFragmentManager() .findFragmentById(R.id.tutview_fragment); if (viewer == null || !viewer.isInLayout()) { Intent showContent = new Intent(getApplicationContext(), TutViewerActivity.class); showContent.setData(Uri.parse(tutUrl)); startActivity(showContent); } else { viewer.updateUrl(tutUrl); } } |
步骤11:运行最新的使用片段的程序
到此,程序将有两种模式:竖屏保持不变,横屏显示列表位于WebView的左侧。现在可以做几个改进,但是只是做微调,优化。比如,如果你在竖屏WebView模式下并旋转屏幕,结果还是只有WebView界面。你必须点击返回以获得双面视图。程序修正不在这个教程讲述的范围,但是你可以发现,如果使用适当的布局并且加上一些活动逻辑,你可以对于不同的屏幕和设备做到非常强大和灵活。
总结
片段API帮助组织用户界面组件,以使它们可以实现跨活动重用。这样,程序可以在相对少的代码量下,动态地适应它的流程和用户界面。你也能看到基于片段构建的代码更容易重新组织。更值得高兴的是,通过Google提供的兼容库,现在任何程序都可以使用片段了,它甚至兼容到Android 1.6。现在就使用片段来为每一个屏幕大小和形状创建你的程序用户界面吧!
Android用户界面设计:布局基础
理解布局对于好的Android应用设计来说是非常重要的。在这个教程里,我们提供一个关于布局如何适应Android应用程序架构的概述。我们还探讨了一些特定的可用布局控件,用它们来以各种各样的方式组织应用程序屏幕内容。
什么是布局?
Android开发者使用术语“布局”,指的是两种含意中的一种。两种定义在这篇教程中都会用到,而且很不幸的是在Android开发社区它们被混着使用。布局的两种定义如下:
一种资源,它定义了在屏幕上画什么。布局资源存储在应用程序的/res/layout资源目录下的XML文件中。布局资源简单的说就是一个用于用户界面屏幕,或屏幕的一部分,以及内容的模板。
一种视图类,它的主要是组织其它控件。这些布局类(LinearLayout,,RelativeLayout,TableLayout等)用于在屏幕上显示子控件,如文本控件或按钮或图片。
Android用户界面可以定义为XML中的布局资源或程序动态创建。
使用Eclipse设计布局资源
Eclipse的Android开发插件包含了一个很方便的用于设计和预览布局资源的布局资源设计器。这个工具包括两个标签视图:布局视图允许你预览在不同的屏幕下以及对于每一个方向控件会如何展现;XML视图告诉你资源的XML定义。布局资源设计器如下图:
这里有一些关于在Eclipse中使用布局资源编辑器的技巧:
使用概要(Outline)窗格来在你的布局资源中添加和删除控件。
选择特定的控件(在预览或概要窗口)并使用属性窗格来调整特定控件的属性。
使用XML标签来直接编辑XML定义。
很重要的是要记住一点,Eclipse布局资源编辑器不能完全精确的模拟出布局在最终用户那的展现。对此,你必须在适当配置的模拟器中测试,更重要的是在目标设备上测试。而且一些“复杂”控件,包括标签或视频查看器,也不能在Eclipse中预览。
定义XML布局资源
设计程序用户界面最方便且可维护的方式是创建XML布局资源。这个访法极大地简化了UI设计过程,将许多用户界面控件的静态产物和布局,以及控件属性定义移动XML中,代替了写代码。它适应了UI设计师(更关心布局)和开发者(了解Java和实现应用程序功能)潜在的区别。开发者依然可以在必要的时候动态的改变屏幕内容。复杂控件,像ListView或GridView,通常用程序动态地处理数据。
XML布局资源必须存放在项目目录的/res/layout下。对于每一屏(与某个活动紧密关联)都创建一个XML布局资源是一个通用的做法,但这并不是必须的。理论上来说,你可以创建一个XML布局资源并在不同的活动中使用它,为屏幕提供不同的数据。如果需要的话,你也可以分散你的布局资源并用另外一个文件包含它们。
下面是一个简单的XML布局资源,一个LinearLayout模板包含一个TextView和一个ImageView,定义在XML中:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center"> <TextView android:layout_width="fill_parent" android:id="@+id/PhotoLabel" android:layout_height="wrap_content" android:text="@string/my_text_label" android:gravity="center_horizontal" android:textSize="20dp" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/matterhorn" android:adjustViewBounds="true" android:scaleType="fitXY" android:maxHeight="250dp" android:maxWidth="250dp" android:id="@+id/Photo" /> </LinearLayout> |
在屏幕上显示一个布局资源只需要有包括onCreate()的一行代码就可以搞定。如果布局资源存放在/res/layout/main.xml文件,代码可能是:
setContentView(R.layout.main);用程序动态定义布局
你也可以用程序创建用户界面组件。为了易组织和可维护性,仅在特殊时候这样做,而不是在一般情况下。不是直接使用setContentView()方法来加载布局资源,你必须创建屏幕内容然后向setContentView()方法提供包含所有要显示的子控件内容的父布局对象。
例如,下面的代码展示了如何用程序实例化一个LinearLayout视图并向里面放置两个TextView。没有使用任何资源。
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.main); TextView label = new TextView(this); label.setText(R.string.my_text_label); label.setTextSize(20); label.setGravity(Gravity.CENTER_HORIZONTAL); ImageView pic = new ImageView(this); pic.setImageResource(R.drawable.matterhorn); pic.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); pic.setAdjustViewBounds(true); pic.setScaleType(ScaleType.FIT_XY); pic.setMaxHeight(250); pic.setMaxWidth(250); LinearLayout ll = new LinearLayout(this); ll.setOrientation(LinearLayout.VERTICAL); ll.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); ll.setGravity(Gravity.CENTER); ll.addView(label); ll.addView(pic); setContentView(ll); } |
探索不同的布局类型
现在让我们把注意力转向对组织其它控件很有用的布局控件。最常用的布局类是:
FrameLayout – 用于显示一堆子视图控件。多视图控件可以添加到这个布局中。它可以用来在相同的屏幕空间展示多个控件。
LinearLayout – 用于在单行或单列中显示子视图控件。这对于创建表单来说是非常方便的布局方法。
RelativeLayout – 用于相对彼此地显示子视图控件。比如,你可以设置一个控件相对另一个控件“在上方”或“在下方”或“在左边”或“在右边”。你也可以相对于父级元素的边界来放置子视图控件。
TableLayout – 用于将子视图控件组织到行或列。对于表格的每一行,单个视图控件使用TableRow布局视图被添加到表格的每一行。
用复合布局来组织控件
布局(LinearLayout,TableLayout,RelativeLayout等)像其它控件一样也是一个控件。这意味着布局控件可以被嵌套。比如,为了组织屏幕上的控件你可以在一个LinearLayout中使用一个RelativeLayout,反过来也行。下面的图展示了一个屏幕,它有一个LinearLayout(父级),一个TableLayout(顶部子节点)以及一个FrameLayout(底部子节点)。
但是小心!保证你的屏幕相对简单,复杂布局加载很慢并且可能引起性能问题。
提供可选布局资源
在你设计你的程序布局资源时考虑设备的差异性。通常情况下是可能设计出在各种不同设备上看着都不错的灵活布局的,不管是竖屏还是模屏模式。必要的时候,你可以引入可选布局资源来处理特殊情况。例如,你可以根据设备的方向或设备是不是有超大屏幕(如网络平板)来提供不同的布局供加载。
想了解更多的关于如何使用可选资源的信息,查看Android SDK的Android资源方面的文档.
布局工具和优化
Android SDK包括几个可以帮助我们设计,调试和优化布局资源的工具。除了Eclipse的Android插件中内置的布局资源设计器,你可以使用Android SDK提供的Hierarchy Viewer(层次结构查看器)和layoutopt。这些工具在你的Android SDK的/tools目录下可以找到。
你可以使用Hierarchy Viewer来查看布局运行时的详细情况。可以在Android开发者网站的Hierarchy Viewer部分了解更多信息。
你可以使用layoutopt(布局优化)命令行工具来优化你的布局文件。优化布局非常重要,因为复杂的布局文件加载很慢。layoutopt工具简单地扫描XML布局文件并找出不必要的控件。在Android开发者网站的layoutopt部分查看更多信息。
总结
Android应用程序用户界面使用布局来定义。有许多不同类型的布局类型可以用来组织屏幕上的控件。布局可以使用XML资源定义,也可以通过Java程序在运行时来定义。可选布局可以在特殊情况下被加载,比如在横屏和竖屏模式下提供一个可选用户界面。最后,设计良好的布局对于应用程序性能很重要;使用像Hierarchy Viewer和layoutopt之类的Android SDK工具来调试和优化你的应用程序布局。
Android用户界面设计:框架布局
框架布局是将控件组织在Android程序的用户界面中最简单的布局类型之一。
理解布局对于良好的Android程序设计来说是非常重要的。在这个教程里,你将学到所以关于框架布局的知识,它们主要用来在屏幕上组织特别的或重叠的视图控件。使用得当的话,很多有趣的Android程序用户界面都可以基于框架布局来设计。
什么是框架布局
框架布局是Android开发者组织视图控件最简单和最有效的布局之一。它们使用得比其它一些布局要少一些,只是因为它们一般只用于显示单个视图,或重叠的视图。框架布局常用作容器布局,因为它一般只有一个子视图(通常是另一个布局,用于组织多个视图)
技巧:事实上,你会看到框架布局是作为你设计的任何布局资源的父布局来使用的。如果你在层级视图工具(Hierarchy Viewer tool,一个很有用的调试你的程序布局的工具)创建你的程序,你会发现你设计的任何布局资源都被显示在一个父布局中——一个框架布局。
框架布局非常简单,这使得它们非常高效。它们可以在XML布局资源文件中定义,也可以通过Java代码在程序中定义。框架布局中的一个子视图总是被绘制到相对于屏幕的左上角上。如果存在多个子视图,那么他们被按顺序一个堆叠在另一个上面的方式绘制。这意味着第一个添加到框架布局的视图将显示在栈的底部,最后添加的视图会显示在最顶部。
让我们来看一个简单的例子。我们假设有一个框架布局大小调整到控制整个屏幕(换句话说,layout_width and layout_height属性都设置为match_parent)。我们要添加三个子控件到这个框架布局:
一个有湖面图片的ImageView。
一个在屏幕顶部显示的TextView。
一个在屏幕底部显示的(使用layout_gravity属性将TextView下沉到父布局的底部)TextView。
下图展示这种类型的布局在屏幕上会是什么样:
在XML资源文件中定义框架布局
设计程序用户界面最方便和可维护的方法是创建XML布局资源。这个方法极大地简化了UI设计过程,将很多静态创建和用户界面控件的布局以及控件属性的定义移到XML中去,取代了写代码。
XML布局资源必须存储在/res/layout项目目录下。让我们看看前一节介绍的框架布局。同样地,这个屏幕基本上就是一个有三个子视图的框架布局:一个充满整个屏幕的图片,两个文本控件绘制在它上面,每一个文本控件都是默认透明背景。这个布局资源文件命名为/res/layout/framed.xml,在XML中如下定义:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:id="@+id/ImageView01" android:layout_height="fill_parent" android:layout_width="fill_parent" android:src="@drawable/lake" android:scaleType="matrix"></ImageView> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="#000" android:textSize="40dp" android:text="@string/top_text" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/bottom_text" android:layout_gravity="bottom" android:gravity="right" android:textColor="#fff" android:textSize="50dp" /> </FrameLayout> |
setContentView(R.layout.framed);用程序定义框架布局
你也可以用程序创建和配置框架布局。这通过使用FrameLayout类(android.widget.FrameLayout)来实现。你会在 RelativeLayout.LayoutParams类中找到具体的参数。同样地,典型的布局参数 (android.view.ViewGroup.LayoutParams),比如layout_height和layout_width,以及边距参数(ViewGroup.MarginLayoutParams),也能用在FrameLayout对象上。
你必须用Java创建屏幕内容,然后向setContentView()方法提供一个包含所有要作为子视图显示的控件内容的父布局对象,而不是像前面所示直接使用setContentView()方法来加载布局资源。在这里,你的父布局就是框架布局。例如,下面的代码示例了如何用程序重新创建前面描述的相同的布局。特别地,我们在活动中实例化一个FrameLayout,并在它的onCreate()方法中先添加一个ImageView控件然后再添加两个TextView控件:
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv1 = new TextView(this); tv1.setText(R.string.top_text); tv1.setTextSize(40); tv1.setTextColor(Color.BLACK); TextView tv2 = new TextView(this); tv2.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, Gravity.BOTTOM)); tv2.setTextSize(50); tv2.setGravity(Gravity.RIGHT); tv2.setText(R.string.bottom_text); tv2.setTextColor(Color.WHITE); ImageView iv1 = new ImageView(this); iv1.setImageResource(R.drawable.lake); iv1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); iv1.setScaleType(ScaleType.MATRIX); FrameLayout fl = new FrameLayout(this); fl.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); fl.addView(iv1); fl.addView(tv1); fl.addView(tv2); setContentView(fl); } |
何时使用框架布局
当你可以自由使用其它强大布局类型,如线性布局,相对布局和表格布局时,很容易会忘了框架布局。框架布局的效率使得它是包含很少视图控件的屏幕的很好的选择(主屏幕,只有一个画布的游戏界面等)。有些时候其它低效的布局设计可以简化为一个更有效率的框架布局设计,而其它时候使用更专业的布局类型会更合适。当你想要堆叠视图时框架布局是一般的选择。
看看类似的控件
FrameLayout相对比较简单。因为这一点,很多其它布局类型和视图控件都是基于它的。例如,ScrollView就是一个在子内容太大而不能在布局界限内完全展示时出现滚动条的框架布局。所有主屏幕(Home屏幕)应用小工具都位于一个框架布局中。
对于所有框架布局需要注意的是它们除了通常的背景以外还可以设置前景色。这通过android:foreground XML属性来实现。这也可以用于框架下面的视图。
总结
Android程序Android程序用户界面使用布局来定义,框架布局是最简单和最高效的布局类型之一。框架布局的子控件被相对于布局的左上角来绘制。如果框架布局中存在多个子视图,它们将按顺序绘制,最后一个子控件绘制在最上面。
相关文章推荐
- Android用户界面设计学习之旅-第五站
- Android用户界面设计:使用片段
- Android用户界面设计:线性布局
- 【Android开发】用户界面设计-使用XML和Java代码混合控制UI界面
- Android 4.0用户界面设计和元素-ICS简介
- Android用户界面设计:基本按钮
- Android用户界面设计学习之旅-第六站
- Android用户界面设计:框架布局
- 【Android开发】用户界面设计-开发自定义的View
- 【Android应用开发技术:用户界面】界面导航设计
- Android 图像用户界面免费的PSD设计文件
- Android用户界面设计:线性布局
- Android用户界面设计学习之旅-第一站
- Android用户界面设计:相对布局
- Android简明开发教程六:用户界面设计
- Android用户界面设计:框架布局(转)
- Android用户界面设计:“.NET研究”创建列表视图程序
- Android用户界面设计:相对布局
- 【Android笔记】入门篇01:快速设计用户界面
- Android用户界面设计:布局基础