布局与控件-Toast吐司与布局的抽象标签merge include ViewStub

Posted anddlecn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了布局与控件-Toast吐司与布局的抽象标签merge include ViewStub相关的知识,希望对你有一定的参考价值。

第5节 Toast

5.1 使用效果

Toast用来向用户弹出一个提示框,然后自动消失,就像这样,

技术分享

面包机烤好面包后,就腾的一下把面包从面包机里弹出来。而这个控件显示时也像是从面包机里弹出来的,所以取了这个名字-Toast(吐司)。

使用Toast显示消息的时候,即使启动它的Activity并没有显示在屏幕上,Toast提示的消息也会被显示到最前面,让用户看到。例如,

  1. Activity A正通过网络下载一个文件,
  2. 此时用户点击Home回到主界面,又启动了另一个应用的Activity B;现在Activity A不再显示了;
  3. 下载完成后,隐藏起来的Activity A使用Toast给用户一个提示;
  4. 虽然Activity A现在没有显示出来,但是它使用Toast给出的提示,还是会被显示到整个界面的最上面,被用户看到;

5.2 显示原理

这是因为Toast会显示在一个特别的窗口层次上,这个窗口比任何Activity使用的窗口层次更高,更优先的显示到上层。

关于窗口系统具体的原理,我们会在安卓系统的窗口机制相关章节进行介绍。

5.3 使用方式

调用Toast的makeText函数生成一个Toast对象,再调用它的show函数显示出来。makeText有三个参数,第一个是Context对象,第二个是要显示的字符串,第三个是要显示的时长。

技术分享
  1. 第一个参数Context:是当前Activity运行的上下文环境,也就是它运行时所拥有的各种系统资源。Activity是从Context继承而来的,所以Activity本事就是我们要找的context;
  2. 第二个参数:是要显示的内容;
  3. 第三个参数:显示的时间长短,它只能设置长或短。
    Toast.LENGTH_SHORT,Toast.LENGTH_LONG。
Toast.makeText(context, "需要显示的内容", Toast.LENGTH_SHORT).show()

第6节 布局的抽象标签-merge include ViewStub

include标签、merge标签,以及ViewStub标签是安卓布局使用的抽象标签。它们并不代表某个具体的布局或者控件,而是起布局的辅助作用,提高布局执行的效率和易用性。

例如,对于那些会重复使用到的布局结构,可以它们放到一个单独的layout文件中。当我们在任何要使用这个布局的地方,就通过复用的方法,将它包含到新的布局文件中。

假设下面这个布局结构会被经常的使用,我们就可以将它单独定义到一个独立的布局文件reuse.xml

<FrameLayout
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <TextView
       android:layout_width="match_parent"
       android:layout_height="match_parent">

</FrameLayout>

6.1 include标签

当别的布局文件main_layout.xml,要使用上面被独立出来的布局时,就可以用<include/>标签把这个布局包含进来。在<include/>标签的layout属性中,指定要复用的布局的id就可以了。

例如main_layout.xml使用<include/>标签,

<LinearLayout
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <!--包含复用的布局-->
   <include layout="@layout/reuse"/>

</LinearLayout>

此时main_layout.xml实际上,就变成了,

<LinearLayout
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <!--include的内容开始--> 
   <FrameLayout
   android:layout_width="match_parent"
   android:layout_height="match_parent">

       <TextView
           android:layout_width="match_parent"
           android:layout_height="match_parent"/>

   </FrameLayout>
   <!--include的内容结束-->

</LinearLayout>

6.2 merge标签

再来看看merge标签,将reuse.xml中的FrameLayout修改成merge

<merge>
   <TextView
       android:layout_width="match_parent"
       android:layout_height="match_parent"/>       
</merge>

main_layout.xml继续使用<include/>标签,

<LinearLayout
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <!--包含复用的布局-->
   <include layout="@layout/reuse"/>

</LinearLayout>

此时main_layout.xml实际就变成了,

<LinearLayout
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <!--include的内容开始,少了FrameLayout一层--> 
   <TextView
       android:layout_width="match_parent"
       android:layout_height="match_parent"/>
   <!--include的内容结束-->

</LinearLayout>

与之前相比,少了FrameLayout一层。在布局时少一个层次的包裹,可以增加布局的效率。

6.3 ViewStub标签

这是一个布局的占位符。当一个布局包含了这种标签,它并不会加载这个标签的内容,而是在需要的时候,通过代码来动态加载。

例如,一个布局main_layout.xml里面,有一个ProgressBar,布局被加载时,这个ProgressBar就会被创建出来,

<LinearLayout
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <TextView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="this is a test"/>

   <!--布局被加载时,这个ProgressBar就会被创建出来-->       
   <ProgressBar
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>

</LinearLayout

如果我们将ProgressBar放到一个单独的布局文件progress_layout.xml当中,

<!--单独放到progress_layout.xml当中-->
<ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

然后main_layout.xml中使用ViewStub引用这个布局,

<LinearLayout
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <TextView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="this is a test"/>

   <!--布局被加载时,这个ViewStub不会被创建出来-->       
   <ViewStub
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/viewstub_id" ---ViewStub指定一个ID,方便通过代码找到它
        android:layout="@layout/progress_layout" ---指定这个ViewStub可以被哪个布局文件的内容代替
        android:inflatedId="@+id/progress_bar"/> ---为这个ViewStub被代替之后,给代替者一个ID

</LinearLayout>

布局被加载时,这个ProgressBar并不会被创建出来。使用如下方式,就可以把ViewStub,替换成android:layout指定的布局,

  1. 在代码中使用setVisibility()函数,

    ((ViewStub) findViewById(R.id.viewstub_id)).setVisibility(View.VISIBLE);
  2. 在代码中使用inflate()函数,

    ((ViewStub) findViewById(R.id.viewstub_id)).inflate();

替换之后,ViewStub就被从布局当中移除了,这个布局就变成了,

<LinearLayout
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <TextView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="this is a test"/>

   <!--布局被加载时,这个ProgressBar就会被创建出来-->       
   <ProgressBar
       android:inflatedId="@+id/progress_bar"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>

</LinearLayout>

以上是关于布局与控件-Toast吐司与布局的抽象标签merge include ViewStub的主要内容,如果未能解决你的问题,请参考以下文章

小吃店与吐司

Android 中布局的优化措施都有哪些?

Android学习笔记二十之Toast吐司Notification通知PopupWindow弹出窗

Android的布局复用与优化

Android消息的提示,Toast吐司方式

Android 性能优化 四 布局优化merge标签的使用