需求:正常情况下展示原有的文章详情页,当特殊情况--文章被删除时,展示一个"文章不存在"的兜底页。
1⃣️正常页面 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="30dp"
android:text="Hello World!" />
</RelativeLayout>
2⃣️引入一个删除页的展示,实际业务中布局会比较复杂,建议新建一个布局文件 view_delete.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="文章已删除"
android:textColor="@color/colorAccent"
android:textSize="30sp" />
</RelativeLayout>
3⃣️在把view_delete引入到activity_main中时,我们可以使用include方式,或者时ViewStub方式。
(1)如果使用include方式,通过指定layout引入布局,先置为gone
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="30dp"
android:text="Hello World!" />
<include
android:id="@+id/layout_delete"
layout="@layout/view_delete"
android:visibility="gone"/>
</RelativeLayout>
当控制两个样式的显隐时,在Activity或Fragment或者什么地方⬇️
class MainActivity : AppCompatActivity() {
private lateinit var mMainText: TextView
private lateinit var mEmptyLayout: RelativeLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mMainText = findViewById(R.id.tv_main)
mEmptyLayout = findViewById(R.id.layout_delete)
hideMainActivity()
}
private fun hideMainActivity() {
mMainText.visibility = GONE
mEmptyLayout.visibility = VISIBLE
}
}
(2)使用ViewStub方式
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Hello World!"
android:textSize="30dp" />
<ViewStub
android:id="@+id/layout_delete"
android:layout="@layout/view_delete"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
在逻辑控制的部分⬇️,用inflate()方式或VISIBLE方式都可以
class MainActivity : AppCompatActivity() {
private lateinit var mMainText: TextView
private lateinit var mViewStub: ViewStub
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mMainText = findViewById(R.id.tv_main)
mViewStub = findViewById(R.id.layout_delete)
hideMainActivity()
}
private fun hideMainActivity() {
mMainText.visibility = GONE
mViewStub.inflate()
//mViewStub.visibility = VISIBLE
}
}
总结一下include与ViewStub的区别
1⃣️引入布局的方式不同
include采用layout="@layout/xxx"的方式
ViewStub采用android:layout="@layout/xxx"的方式(如果写错了,编译不会报错,运行时会发生崩溃)
2⃣️在布局中的实际情况不同
include方式与直接把布局内容写在主文件一样,只是为了把布局分开写 或者 布局复用,在一开始就会把include的内容引用进来;
而ViewStub的内容一开始在布局中是不存在的,只有调用inflate()才会开始加载,⚠️inflate()只能调用一次。
3⃣️布局中必要属性不同
include不用必须指定android:layout_width和android:layout_height,ViewStub必须指定
⚠️在include和ViewStub节点中加入id,而不是在被引入文件的跟布局中加id。在该例中,不要在view_delete的跟布局加入id。
ViewStub很适用于引入这种,很少有机会被加载出来的页面。这样在大多数正常的主流程中,完全不用考虑ViewStub,性能不会收到影响。
附:发完文,给我推荐了很多merge的使用,就顺便学习了一下,记录一下merge的使用。merge的目的在于减少多余的布局层级,如主布局是RelativeLayout(LinearLayout),引入的文件跟布局也是RelativeLayout(LinearLayout),就很浪费。这时候,可以使用merge来进行处理,merge的布局,取决于引入它的布局的布局方式。
view_delete如下⬇️
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="文章已删除"
android:textColor="@color/colorAccent"
android:textSize="30sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_delete"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="看看别的文章吧"
android:textColor="@color/colorPrimaryDark"
android:textSize="20dp" />
</merge>
1⃣️当主布局使用RelativeLayout时
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<include layout="@layout/view_delete" />
</RelativeLayout>
界面如下图所示
当主布局采用LinearLayout布局时。
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".MainActivity">
<include layout="@layout/view_delete" />
</LinearLayout>
界面如下图所示