Android优化布局的几种方式
来源:互联网 发布:淘宝装衣服的袋子 编辑:程序博客网 时间:2024/04/28 12:34
优化布局的几种方式
1. include/merge
布局优化中常常用到include/merge标签,include的含义类似C代码中的include,意思是直接把指定布局片段包含进当前的布局文件。include适用于多个布局文件中存在相同的xml片段,比如说相同的标题栏、相同的广告栏、相同的进度栏等等。
如:
<include layout="@layout/common_title" />
这时必定有个common_title.xml的布局文件,它用于在各页面展示相同的标题区域。
include子布局文件的根节点可以是LinearLayout或RelativeLayout或FrameLayout,可是上级布局文件往往已经有了相同的视图节点,这时子布局的根节点就变成冗余的了,但是布局文件又必须有根节点,着实矛盾。不要急,merge标签便是处理这个问题的,merge要和include配合使用,也就是说,merge只能是include子布局文件的根节点,且merge无需设置额外的属性。merge标签代替了根节点LinearLayout、RelativeLayout和FrameLayout原来的位置,只是告诉编译器:我是个占位的合并标签,不需要对我做布局处理;这样app在渲染UI时,只是简单合并merge标签下的内容,但不做布局计算和调整,从而提高了UI的加载效率。
2. ViewStub
在一个页面上根据不同条件展示不同的控件,我们常常会设置控件的可视属性,比如调用指定控件的setVisibility方法,若需展示则设置View.VISIBLE,若需隐藏则设置View.GONE。不过gone的控件只是看不到罢了,实际UI渲染时还是会被加载。要想事先不加载,在条件符合时才加载,就得用到标签ViewStub。
ViewStub类似一个简单的View,但具体布局由属性layout指定,并且在app加载UI时,ViewStub不显示界面内容,只有在代码中调用该控件的inflate方法,layout指定的布局才会展示。基于以上特性,ViewStub在提高布局性能上有几个特点:
优点:ViewStub在加载时只占用大约一个View控件的内存,不占用layout整个布局需要的内存;
缺点:ViewStub一旦调用inflate方法,页面内容就显示出来,之后就没有对应的方法再缩回去。如果还想再次隐藏或显示布局,只能通过setVisibility来实现。
举个ViewStub实际运用的场景,手机屏幕在竖屏和横屏切换时,有时希望显示不同的布局,比如竖屏显示列表,横屏则显示网格,横竖屏的截图如下:
竖屏的列表方式界面截图
横屏的网格方式界面截图
布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp" > <RelativeLayout android:layout_width="match_parent" android:layout_height="40dp" android:background="#aaaaff" android:paddingLeft="10dp" android:paddingRight="10dp" > <include layout="@layout/common_title" /> </RelativeLayout> <ViewStub android:id="@+id/vs_list" android:layout_width="match_parent" android:layout_height="match_parent" android:layout="@layout/viewstub_list" /> <ViewStub android:id="@+id/vs_grid" android:layout_width="match_parent" android:layout_height="match_parent" android:layout="@layout/viewstub_grid" /> </LinearLayout>
代码
import com.example.exmlayout.adapter.ContentGridAdapter; import com.example.exmlayout.adapter.TitleListAdapter; import android.app.Activity; import android.content.res.Configuration; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewStub; import android.widget.GridView; import android.widget.ImageButton; import android.widget.ListView; import android.widget.TextView; public class PlanetActivity extends Activity implements OnClickListener { private static final String TAG = "PlanetActivity"; private String[] mStrList = {"水星", "金星", "地球", "火星", "木星", "土星" , "天王星", "海王星", "冥王星"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_planet); ImageButton ib_back = (ImageButton) findViewById(R.id.ib_back); ib_back.setOnClickListener(this); TextView tv_title = (TextView) findViewById(R.id.tv_title); tv_title.setText("九大行星介绍"); Bundle bundle = getIntent().getExtras(); int type = bundle.getInt("type"); if (type == 0) { Configuration config = getResources().getConfiguration(); if(config.orientation == Configuration.ORIENTATION_PORTRAIT){ showList(); } else { showGrid(); } } else if (type == 1) { showList(); } else { showGrid(); } } private void showList() { ViewStub vs_list = (ViewStub) findViewById(R.id.vs_list); vs_list.inflate(); ListView lv_hello = (ListView) findViewById(R.id.lv_hello); TitleListAdapter adapter = new TitleListAdapter(this, mStrList); lv_hello.setAdapter(adapter); lv_hello.setOnItemClickListener(adapter); lv_hello.setOnItemLongClickListener(adapter); } private void showGrid() { ViewStub vs_grid = (ViewStub) findViewById(R.id.vs_grid); vs_grid.inflate(); GridView gv_hello = (GridView) findViewById(R.id.gv_hello); ContentGridAdapter adapter = new ContentGridAdapter(this, mStrList); gv_hello.setAdapter(adapter); gv_hello.setOnItemClickListener(adapter); gv_hello.setOnItemLongClickListener(adapter); } @Override public void onClick(View v) { if (v.getId() == R.id.ib_back) { finish(); } } }
3. style样式
样式在res/values/styles.xml中定义,它适用于下面几种情况:
1、布局文件中存在多个具有相同风格的控件,比如说统一的文本框TextView,都是白底黑字、中号字体、居中显示,这时我们便可在styles.xml定义一种文本样式,然后在各文本框处声明它的style属性。好处一个是减少了布局文件的大小,另一个是方便以后统一修改风格。
2、某些控件在代码中声明时需要手工指定style,例如自定义对话框需要在构造函数中指定样式,参见《Android开发笔记(六十六)自定义对话框》;另一个例子是弹窗PopupWindow在设置伸缩动画方法setAnimationStyle时需要指定动画样式,参见《Android开发笔记(六十五)多样的菜单》。
3、定义页面的主题风格,然后应用到Activity页面。代码中设置主题可通过“setTheme(R.style.)”完成,布局中设置可在AndroidManifest.xml的activity节点下添加theme属性,如“android:theme=”@style/“”。
下面是在styles.xml中自定义样式的一个例子
<style name="middle_text"> <item name="android:textColor">#000000</item> <item name="android:textSize">17sp</item> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> </style> <style name="middle_text_center" parent="@style/middle_text"> <item name="android:layout_gravity">center_horizontal</item> <item name="android:gravity">center</item> </style>
布局文件中给控件声明风格属性:
style="@style/middle_text_center"
4. Theme主题
主题是一种特殊的样式,主题专用于页面,而样式一般运用于控件。主题定义一般放在themes.xml,样式定义一般放在styles.xml。
Android定义了一些系统主题,完整定义的参见sdk自带的themes.xml,常用的几种说明如下:
Theme.NoTitleBar : 不显示标题栏,即隐藏ActionBar
Theme.Light : 白色背景
Theme.Holo : 浅灰背景
Theme.Black : 黑色背景
Theme.Wallpaper : 壁纸
Theme.Translucent : 透明背景
Theme.Dialog : 对话框
Theme.Panel : 平板
Theme.InputMethod : 输入法
Theme.SearchBar : 搜索框
在代码中给页面运用主题需要在所有视图初始化之前进行,也就是说,setTheme方法必须在setContentView方法之前执行。下面是个代码中设置主题的例子:
setTheme(android.R.style.Theme_Light_NoTitleBar);
在布局中运用主题,只需在activity界面下添加theme属性即可,下面是个布局中添加主题的例子:
android:theme="@android:style/Theme.Dialog"
除了系统自带的主题样式,我们也可以在themes.xml中自定义主题,具体步骤与自定义样式类似。下面是自定义主题时可能变更的窗口属性:
android:windowFrame : 窗口框架图像
android:windowBackground : 窗口背景
android:windowNoTitle : 窗口是否不要标题,即不带ActionBar
android:windowFullscreen : 窗口是否全屏
android:windowIsTranslucent : 窗口是否半透明
android:windowIsFloating : 窗口是否悬浮
android:windowAnimationStyle : 窗口切换动画的样式
android:windowEnterAnimation : 进入窗口的动画
android:windowExitAnimation : 退出窗口的动画
注意:windowFrame并不只是边框区域,还包括内部窗口,所以如果windowFrame设置为不透明的图像,那么内部窗口也将只显示这幅不透明的图像。
确实这三个属性容易混淆:android:windowFrame、android:windowBackground、android:background,文字描述感觉都说的不清楚,下面针对三个属性分别测试一下,看看究竟都是什么效果:
只有android:windowFrame设置为半透明红色的窗口截图:
从截图可以看到,windowFrame的覆盖区域包括窗口与边框,且窗口对内半透明、对外不透明,而边框对外半透明。
只有android:windowBackground设置为半透明红色的窗口截图:
从截图可以看到,windowBackground的覆盖区域只有窗口,且窗口对内对外都是半透明。
只有android:background设置为半透明红色的窗口截图:
从截图可以看到,background的覆盖区域只有窗口,且窗口对内半透明、对外不透明。
- Android优化布局的几种方式
- 【UI布局优化】Android布局优化的几种方式
- Android布局优化的几种方法
- Android 布局使用的几种方式
- Android开发 第五课 Android的几种布局方式
- Android界面布局的几种常用方式
- Android之view的几种布局方式及实践
- Android 的几种布局方式及实践【转】
- 01 Android 布局使用的几种方式
- Android开发:view的几种布局方式
- Android 加载布局文件的几种方式
- 深入浅出谈Android 几种布局方式
- Android中ListView的几种常见优化方式
- 几种布局方式
- 几种布局方式
- 布局优化的几种方法
- Android 的 几种布局
- android的几种布局
- linux优化相关的系统工具系列-综述
- NGUI内核大剖析(一) UIRect
- 自己动手写简单的eventbus
- 将一个多维的数组展开成一个一维的数组
- App网络管理 → AppNetworkMgr
- Android优化布局的几种方式
- java自定义类加载器的一些个人理解
- kaldi中的深度神经网络
- Android Studio Ctrl Z的相对快捷键
- Ubuntu下如何关闭触摸板
- 注意事项
- 硬件三人行,运放基础第1讲听课笔记,为什么需要运算放大器?
- iOS开发之使用Appearance
- 实时监控软硬件资源,性能监控不在烦恼