Android实战技巧:ViewStub的应用

Android实战技巧:ViewStub的应用在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局。那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,然后在代码中动态的更改它的可见性。这样的做法的优点是逻辑简单而且控制起来比较灵活。但是

大家好,又见面了,我是你们的朋友全栈君。

       在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局。那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,然后在代码中动态的更改它的可见性。这样的做法的优点是逻辑简单而且控制起来比较灵活。但是它的缺点就是,耗费资源。虽然把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,也就是说仍然会创建对象,会被实例化,会被设置属性。也就是说,会耗费内存等资源。

      推荐的做法是使用android.view.ViewStub,ViewStub是一个轻量级的View,它一个看不见的,不占布局位置,占用资源非常小的控件。可以为ViewStub指定一个布局,在Inflate布局的时候,只有ViewStub会被初始化,然后当ViewStub被设置为可见的时候,或是调用了ViewStub.inflate()的时候,ViewStub所向的布局就会被Inflate和实例化,然后ViewStub的布局属性都会传给它所指向的布局。这样,就可以使用ViewStub来方便的在运行时,要还是不要显示某个布局。

      但ViewStub也不是万能的,下面总结下ViewStub能做的事儿和什么时候该用ViewStub,什么时候该用可见性的控制。

     首先来说说ViewStub的一些特点:

         1. ViewStub只能Inflate一次,之后ViewStub对象会被置为空。按句话说,某个被ViewStub指定的布局被Inflate后,就不会够再通过ViewStub来控制它了。

         2. ViewStub只能用来Inflate一个布局文件,而不是某个具体的View,当然也可以把View写在某个布局文件中。

     基于以上的特点,那么可以考虑使用ViewStub的情况有:

         1. 在程序的运行期间,某个布局在Inflate后,就不会有变化,除非重新启动。

              因为ViewStub只能Inflate一次,之后会被置空,所以无法指望后面接着使用ViewStub来控制布局。所以当需要在运行时不止一次的显示和隐藏某个布局,那么ViewStub是做不到的。这时就只能使用View的可见性来控制了。

         2. 想要控制显示与隐藏的是一个布局文件,而非某个View。

              因为设置给ViewStub的只能是某个布局文件的Id,所以无法让它来控制某个View。

     所以,如果想要控制某个View(如Button或TextView)的显示与隐藏,或者想要在运行时不断的显示与隐藏某个布局或View,只能使用View的可见性来控制。

下面来看一个实例

在这个例子中,要显示二种不同的布局,一个是用TextView显示一段文字,另一个则是用ImageView显示一个图片。这二个是在onCreate()时决定是显示哪一个,这里就是应用ViewStub的最佳地点。

先来看看布局,一个是主布局,里面只定义二个ViewStub,一个用来控制TextView一个用来控制ImageView,另外就是一个是为显示文字的做的TextView布局,一个是为ImageView而做的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:gravity="center_horizontal">
  <ViewStub 
    android:id="@+id/viewstub_demo_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="5dip"
    android:layout_marginRight="5dip"
    android:layout_marginTop="10dip"
    android:layout="@layout/viewstub_demo_text_layout"/>
  <ViewStub 
    android:id="@+id/viewstub_demo_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="5dip"
    android:layout_marginRight="5dip"
    android:layout="@layout/viewstub_demo_image_layout"/>
</LinearLayout>

为TextView的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content">
    <TextView
        android:id="@+id/viewstub_demo_textview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#aa664411"
        android:textSize="16sp"/>
</LinearLayout>

为ImageView的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/viewstub_demo_imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

下面来看代码,决定来显示哪一个,只需要找到相应的ViewStub然后调用其infalte()就可以获得相应想要的布局:

package com.effective;

import android.app.Activity;
import android.os.Bundle;
import android.view.ViewStub;
import android.widget.ImageView;
import android.widget.TextView;

public class ViewStubDemoActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.viewstub_demo_activity);
        if ((((int) (Math.random() * 100)) & 0x01) == 0) {
            // to show text
            // all you have to do is inflate the ViewStub for textview
            ViewStub stub = (ViewStub) findViewById(R.id.viewstub_demo_text);
            stub.inflate();
            TextView text = (TextView) findViewById(R.id.viewstub_demo_textview);
            text.setText("The tree of liberty must be refreshed from time to time" +
                    " with the blood of patroits and tyrants! Freedom is nothing but " +
                    "a chance to be better!");
        } else {
            // to show image
            // all you have to do is inflate the ViewStub for imageview
            ViewStub stub = (ViewStub) findViewById(R.id.viewstub_demo_image);
            stub.inflate();
            ImageView image = (ImageView) findViewById(R.id.viewstub_demo_imageview);
            image.setImageResource(R.drawable.happy_running_dog);
        }
    }
}

运行结果:

Android实战技巧:ViewStub的应用Android实战技巧:ViewStub的应用

使用的时候的注意事项:

1. 某些布局属性要加在ViewStub而不是实际的布局上面,才会起作用,比如上面用的android:layout_margin*系列属性,如果加在TextView上面,则不会起作用,需要放在它的ViewStub上面才会起作用。而ViewStub的属性在inflate()后会都传给相应的布局。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/153941.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月28日 下午4:16
下一篇 2022年6月28日 下午4:16


相关推荐

  • TPS和事务响应时间的关系、计算公式

    TPS和事务响应时间的关系、计算公式例子 一个高速路有 10 个入口 每个入口每秒钟只能进 1 辆车 1 请问 1 秒钟最多能进几辆车 nbsp nbsp TPS 102 每辆车需要多长时间进行响应 nbsp nbsp reponsetime 13 改成 20 辆车 每秒能进几辆 每辆车的响应时间是多长 nbsp nbsp TPS 10 reponsetime 1 nbsp 10 个为一等份 分成两等份 平均 tps 10 1 10 2 2 7 5 平均响应

    2026年3月26日
    3
  • k8s有哪些资源_k8s资源类型

    k8s有哪些资源_k8s资源类型k8sNamespacePodLabelDeploymentServiceNamespace概述Namespace是kubernetes系统中一种非常重要的资源,它的主要作用是用来实现多套系统的资源隔离或者多租户的资源隔离。默认情况下,kubernetes集群中的所有Pod都是可以相互访问的。但是在实际中,可能不想让两个Pod之间进行互相的访问,那么此时就可以将两个Pod划分到不同的Namespace下。kubernetes通过将集群内部的资源分配到不同的Namespace中,可以形成逻辑上的“组

    2022年8月9日
    10
  • 雪崩效应 (密码学术语)

    雪崩效应 (密码学术语)雪崩效应(密码学术语)雪崩效应就是一种不稳定的平衡状态也是加密算法的一种特征,它指明文或密钥的少量变化会引起密文的很大变化,就像雪崩前,山上看上去很平静,但是只要有一点问题,就会造成一片大崩溃。可以用在很多场合对于Hash码,雪崩效应是指少量消息位的变化会引起信息摘要的许多位变化。这个概念有点类似于蝴蝶效应。蝴蝶效应,说的是,指在一个动力系统中,初始条件下微小的变化能带动整个系统的长期的巨大的连锁反应。说的是极少的变化引发的大变化。雪崩效应在服务器应用系统中,也同样存在,如…

    2022年7月13日
    27
  • 运行代码后出现Process finished with exit code 0是为什么?

    运行代码后出现Process finished with exit code 0是为什么?

    2021年10月21日
    205
  • js的promise用法

    js的promise用法js 的 promise

    2026年3月18日
    1
  • Mysql报Deadlock found when trying to get lock; try restarting transaction问题解决

    Mysql报Deadlock found when trying to get lock; try restarting transaction问题解决Mysql 报 Deadlockfoun tryrestartin 问题解决 问题发生场景今天记录一下最近项目中遇到的一个问题 前几天在部署项目后 在线上运行过程中 突然报了入下这样的错误 从报错信息中我们可以看到 是 mysql 在执行 update 操作的时候报了一个死锁的问题 今天解决了 特此记录一下 Mysql 锁类型分析 MySQL 有三种锁的级别 页级 表级 行级 这个地方我遇到的问题是来自于行级锁 所以重点说一下

    2026年3月18日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号