Android(安卓)进阶 APP优化 布局优化
一.三种标签详解
<1> include标签
include标签常用于将布局中的公共部分提取出来供其他layout使用,以实现布局模块化。
代码
(1) 公共Layout
<?xml version="1.0" encoding="utf-8"?>
(2) 引入使用页面的Layout
<?xml version="1.0" encoding="utf-8"?> ......
即:
(3) 引入使用的Activity
titletextview= (TextView) findViewById(R.id.apptoplayout_onlyback_titletextview);
这样就可以了。
注意:被引入的模块布局父布局要确定宽高(尤其是高)然后直接引入即可。如果不确定宽高都是(match_parent)就要在引入的时候确定宽高
多个布局
(4) layout1
<?xml version="1.0" encoding="utf-8"?>
(5) layout2
<?xml version="1.0" encoding="utf-8"?>
(6) layout3
<?xml version="1.0" encoding="utf-8"?>
(7) 主页面布局
<?xml version="1.0" encoding="utf-8"?>
(8) 主页面效果
(9) 主页面使用
package wjn.com.imwithdemo.activity;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.Toast;import wjn.com.imwithdemo.R;public class IncludeDemoActivity extends AppCompatActivity { private Button button1; private Button button2; private Button button3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_includedemo); button1=findViewById(R.id.includelayout1_button); button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(IncludeDemoActivity.this,"按钮一被点击!",Toast.LENGTH_LONG).show(); } }); button2=findViewById(R.id.includelayout2_button); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(IncludeDemoActivity.this,"按钮二被点击!",Toast.LENGTH_LONG).show(); } }); button3=findViewById(R.id.includelayout3_button); button3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(IncludeDemoActivity.this,"按钮三被点击!",Toast.LENGTH_LONG).show(); } }); }}
附:include官方文档
https://developer.android.google.cn/training/improving-layouts/reusing-layouts
<2> merge标签
merge用于消除视图层次结构中的冗余视图,例如根布局是Linearlayout,那么我们又include一个LinerLayout布局就没意义了,反而会减慢UI加载速度。
又或者根布局是FrameLayout且不需要设置background或padding等属性,可以用merge代替,因为Activity的ContentView父元素就是FrameLayout,所以可以用merge消除只剩一个。
代码
(1) 被引入的布局
<?xml version="1.0" encoding="utf-8"?>
(2) 主页面layout
<?xml version="1.0" encoding="utf-8"?>
(3) 主页面效果
(4) 主页面代码
package wjn.com.imwithdemo.activity;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.Toast;import wjn.com.imwithdemo.R;public class IncludeDemoActivity extends AppCompatActivity { private Button button1; private Button button2; private Button button3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_includedemo); button1=findViewById(R.id.includelayout1_button1); button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(IncludeDemoActivity.this,"按钮一被点击!",Toast.LENGTH_LONG).show(); } }); button2=findViewById(R.id.includelayout1_button2); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(IncludeDemoActivity.this,"按钮二被点击!",Toast.LENGTH_LONG).show(); } }); }}
主页面父布局是LinearLayout且垂直排布,要引入的布局父布局也是LinearLayout且垂直排布。这样的话被引入的布局父布局完全可以修改成merge。这样系统忽略
附:merge官方文档
https://developer.android.google.cn/training/improving-layouts/reusing-layouts
<3> ViewStub标签
ViewStub 标签最大的优点是当你需要时才会加载,使用他并不会影响UI初始化时的性能。各种不常用的布局比如进度条、显示错误消息等可以使用
ViewStub的使用有几个注意事项。
【1】ViewStub对象只可以inflate一次,之后ViewStub对象会被置为空。
【2】 ViewStub不支持merge,不能引入包含merge标签的布局到ViewStub中。否则会报错
can be used only with a valid ViewGroup root and attachToRoot=true
代码
(1) 要引入的textview布局
<?xml version="1.0" encoding="utf-8"?>
(2) 主页面layout
<?xml version="1.0" encoding="utf-8"?>
注意:
【1】 使用id activity_main_viewstub获取ViewStub,ViewStub在加载布局之后,ViewStub本身消失。其中设置的
android:inflatedId="@+id/textview_layout_layout"
指定加载后布局ID,这里加载后是要引入的textview布局,其父布局id
android:id="@+id/textview_layout_layout"
两者一致。
(3) 主页面代码
package com.example.test;import android.os.Bundle;import android.view.View;import android.view.ViewStub;import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity { private ViewStub viewStub; private View view; private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewStub = findViewById(R.id.activity_main_viewstub); if (null == view) { if (viewStub != null) { view = viewStub.inflate(); } } //执行了viewStub.inflate();之后 布局就引入成功,要引入的布局中的View使用和普通ViewfindViewById一样 textView = findViewById(R.id.textview_layout_textview); textView.setText("引入后动态设置TextView字符串"); }}
注意:
【1】由于ViewStub第一次inflate的时候,就已经将需要显示的布局替换掉自己了,所以第二次inflate的时候,getParent()是null,所以就会报异常。解决方法是inflate()的时候将view保存起来,然后下次判断这个View是否为null,如果是null就inflate()。否则就直接使用这个view。
【2】也可通过以下方式获取
findViewById(R.id.activity_viewstubdemo_viewstub2).setVisibility(View.VISIBLE);
附:ViewStub官方文档
https://developer.android.google.cn/training/improving-layouts/loading-ondemand
更多相关文章
- android design library提供的TabLayout的用法
- Android用软键盘将整个界面推上去
- Android实现计算器布局(四种布局方式)之GridLayout网格布局
- Android如何在初始化的时候获取加载的布局的宽高
- Android5.X之百分比布局库(percent-support-lib) 解析与扩展
- 在Ubuntu下搭建Android(安卓)SDK开发环境(图文)
- Android:控件布局(表格布局)TableLayout
- [转]android学习总结----Activity view
- LinearLayout源码分析