关于Include复用layout的文章,2017年写过俩篇;
于2020年综合为一篇 ~
基础
本篇主要讲的是include 标签
,其主要作用体现在layout的复用性方面,也是布局优化中的重要体现之一 ~
include标签
之所以能作为布局优化中的一环,主要是因为其自身的复用性
,当多布局引用一个公用布局时,一般都会使用include标签
,很大程度上节省了开发时间,不用重复造轮子
~
使用方式
关于inlude标签的使用
,我们通常需要一个被引用的layout
,同时在需要引用地方通过include标签
下的layout属性
进行引入我们要复用的布局
通常通过以下类型方式,即可成功引入公用布局
include_layout - 被复用的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/include_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Include—item—1"
/>
</LinearLayout>
activity_main - 引入include标签,复用布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<include
android:id="@+id/include_main"
layout="@layout/include_layout" />
</LinearLayout>
注意要点
引用布局只是其一,大多场景我们需要对inlude布局执行相关操作,关于这里有几点需要注意一下
我们如何操作include内的布局元素?
通常我们首先将include标签加上id,之后在调用时,通过第一次获取的View再次获取include内(被复用视图)控件
//我比较懒,直接链式写完了,一般不建议这么写
TextView mTv1 = findViewById(R.id.include_main).findViewById(R.id.tv_1);
include标签id和include根布局id有什么要注意的?
常规建议俩者共用一个id
,或仅命名include标签的id
,俩者同时命名,且id不同时,include根标签可能被报空,如下 ~
将上方的include布局的根布局加入不同id
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/include_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Include—item—1"
/>
</LinearLayout>
调用示例
View layout_main = findViewById(R.id.include_main);
Log.i(TAG, "layout " + layout_main ); // 此时正常获取Layout
View layout_ll = findViewById(R.id.include_ll);
Log.i(TAG, "layout " + layout_ll); // 此时返回null
尝试解决
//可以用过这种方式解决报空问题,但是不建议这么操作
View layout = findViewById(R.id.include_main).findViewById(R.id.include_ll);
如果在include标签内使用常见的布局属性会不会有问题?
答案是肯定有问题
的,布局会错位
…
简单引用
<include
android:id="@+id/include_main"
layout="@layout/include_layout" />
错误:属性引用(无效)
<include
android:id="@+id/include_main"
android:layout_marginTop="10dp"
layout="@layout/include_layout" />
正确:属性引用(声明layout_width、layout_height)
<include
android:id="@+id/include_main"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="@layout/include_layout" />
篇一
篇一 :Android初级教程 - Include(复用layout)的使用方式(一)
发布时间:2017-01-09 14:01:43
地址:http://blog.csdn.net/qq_20451879/article/details/54288317(4月17被我删除)
项目结构图
包含2个Activity,4个layout
include layout(被复用布局)
include_layout1
<?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="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Include—item—1"
/>
</LinearLayout>
include_layout2
<?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="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="include—item-2"
android:gravity="center"
android:id="@+id/tv_2"
/>
</LinearLayout>
引用include视图
activity_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<include
android:id="@+id/tv_1"
layout="@layout/include_layout1" />
<include
layout="@layout/include_layout2"
/>
</LinearLayout>
activity_secound
<?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="vertical" >
<include
layout="@layout/include_layout2"
/>
</LinearLayout>
Activity中调用include相关操作
MainActivity
package com.example.includedemo;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private TextView include_item2;
private LinearLayout include_item1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//第一种方式-1-在当前布局设置Id,不过返回的都是最外层的布局,所以不对单体View作用,但可以改变其背景,颜色之类
include_item1 = (LinearLayout)findViewById(R.id.tv_1);
include_item1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "第一种方式include_item1", 0).show();
include_item1.setBackgroundColor(Color.BLUE);
}
});
//第一种方式-2-如对其整个空间的背景之类无特殊要求直接一套操作完毕。
// findViewById(R.id.tv_1).setOnClickListener(new OnClickListener() {
//
// @Override
// public void onClick(View v) {
// Toast.makeText(MainActivity.this, "第一种方式include_item1", 0).show();
// }
// });
//第二种方式-在子item布局进行id设置,使用较为方便!而且自由!
include_item2 = (TextView) findViewById(R.id.tv_2);
include_item2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "第二种方式include_item2", 0).show();
//很明显我们可以对此控件进行操作
include_item2.setText("Go to Bed to sleep");
startActivity(new Intent(MainActivity.this,SecoundActivity.class));
}
});
}
}
SecoundActivity
package com.example.includedemo;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
public class SecoundActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_secound);
TextView mSecound = (TextView) findViewById(R.id.tv_2);
mSecound.setText("Secound页面,填充Include");
mSecound.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(SecoundActivity.this, "触发Include", 0).show();
}
});
}
}
总结
包含遇到的问题和需要注意的点
- 三种方式,一种主Xml设置id,一种item的Xml设置id,一种单纯填充布局。
- 主Xml设置id的话,我们大多时候只能获取最外层的View,作用比较小,往往改一个背景,颜色之类的,意义不大(需要注意:如果在运行中layout出现占满整个布局的情况下,需要看一下item的最外层layout是否是match,这是处理方式之一,同时也可以在使用处的Xml进行宽度,高度的限制)。
- 这里的话我们主要使用在item处设置id的方式来在开发中使用,这样使用起来更加的灵活,可以随心所欲的设置item的任何事件,不管是修改text的属性,还是设置onClick,亦或换换颜色,换换背景之类的(需要注意:find之后返回对应的View类即可)。
- 在不同的Activity中获取item的id进行设置处理,并不会造成影响俩者的影响,所以不必在意。
- 一切均自己所想,如有不足,请您指出,如有误导,非常抱歉。
- 希望各位君,2017开开心心
篇二
基于之前不足之处,将不完善之处通过此篇为大家带入更清晰的使用方式,注释已经详细为大家解答,敬请阅读 ~
注意点:此文的双重tag - 及为俩次find id后的控件
- 首先复用的layout注意布局,外部布局一般高度都是wrop的。不然你会发现显示不全
- 如果我们复用的layout只在当前布局复用一次的话,可以直接find到复用 layout的布局的id直接处理逻辑
- 反之如果我们在当前布局,多次复用layout我们就需要通过双重tag获得具体事件操作
include layout(被复用布局)
Inclde Layout(我们要复用的视图)
<?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="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/include_text"
android:text="复用 Layout"
android:layout_gravity="center"
/>
</LinearLayout>
引用include layout
activity_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include
android:id="@+id/main_text"
layout="@layout/include_layout"
/>
<include
android:id="@+id/secound_text"
layout="@layout/include_layout"
/>
</LinearLayout>
基于 include layout 之上Activity的操作
MainActivity code
package com.example.includeall;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private TextView mSecound;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//第一种方式的进阶版使用针对在主layout多次复用layout的处理方式
//第一个复用layout的使用
// 首先获取当前布局的Layout id,这里我们直接返回View!!!因为我们并不确定我们当前复用的layout就是TextView等
View mMain = findViewById(R.id.main_text);
// 之后通过之前获取的id再次获取Include layout的 id
TextView mInculde = (TextView) mMain.findViewById(R.id.include_text);
// 如果我们只是获取当前复用layout的id控件操作,是会报错的
// mMain.setText("xxxxx");
mInculde.setText("在主Layout操作Inclue的Layout,与我们之前的直接查找复用Layout中的id效果是一样的!");
//第二个复用layout的使用
mSecound = (TextView) findViewById(R.id.secound_text).findViewById(R.id.include_text);
mSecound.setText("在同一个布局,复用了俩次相同的子布局页面, 我们需要通过双重tag操作");
mSecound.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplication(), "执行自己的相关逻辑操作", 0)
.show();
}
});
/**此为复用layout的直接id,---目前发现只给复用的第一个layout显示相关的操作!!!*/
TextView mTwo = (TextView) findViewById(R.id.include_text);
mTwo.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplication(), "使用之前的第二种方式操作,效果一样没有区别对待,实现的效果都建立在第一个视图之上", 0)
.show();
}
});
}
}