【问题标题】:How to use View Stub in android如何在android中使用View Stub
【发布时间】:2012-07-19 15:17:51
【问题描述】:

我想在 android 中使用 ViewStub,所以请帮助我。我已经创建了

ViewStub stub = new ViewStub;
View inflated = stub.inflate(); 

如何以编程方式使用它?

【问题讨论】:

标签: android viewstub


【解决方案1】:

就像documentation 所说的那样,ViewStub 是一个惰性膨胀的View

您可以像这样在 XML 文件中声明ViewStub

 <ViewStub android:id="@+id/stub"
           android:inflatedId="@+id/subTree"
           android:layout="@layout/mySubTree"
           android:layout_width="120dip"
           android:layout_height="40dip" />

android:layout 属性是对View 的引用,它将在调用inflate() 旁边被夸大。所以

ViewStub stub = (ViewStub) findViewById(R.id.stub);
View inflated = stub.inflate();

当调用inflate() 方法时,ViewStub 会从其父级中移除并替换为正确的ViewmySubTree 布局的根视图)。

如果您想以编程方式执行此操作,那么您的代码应该类似于:

ViewStub stub = new ViewStub(this);
stub.setLayoutResource(R.layout.mySubTree);
stub.inflate(); 

【讨论】:

  • ViewStub android:layout_width="120dip" 是什么意思,如果它是不可见的,后来它在膨胀后被替换?
  • 我的猜测是,布局的其余部分要正确对齐
  • 如何在 Android Studio 预览中显示膨胀视图?
  • 我收到The specified child already has a parent. You must call removeView() on the child's parent first. 错误,谁能帮帮我?
  • @DenisNek Android 问题跟踪器中存在问题,但尚未有人回答。 code.google.com/p/android/issues/detail?id=205335
【解决方案2】:

仅使用 ViewStub 来提高渲染布局的效率。 通过使用 ViewStub,可以手动创建视图,但不能将其添加到视图层次结构中。在运行时,可以很方便的进行充气,在对ViewStub进行充气的同时,viewstub的内容会被viewstub中定义的布局替换掉。

activity_main.xml 我们定义了viewstub但没有先创建。

简单的例子可以更好地理解,

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/content"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <Button
        android:id="@+id/btn1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="create the view stub" />
     <Button
        android:id="@+id/btn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hide the stub." />

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >

        <ViewStub
            android:id="@+id/stub_import"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:inflatedId="@+id/content_import"
            android:layout="@layout/splash" />
    </RelativeLayout>
</LinearLayout>

在运行时,当我们膨胀时,内容将被替换为viewstub中定义的布局。

public class MainActivity extends Activity {

    Button b1 = null;
    Button b2 = null;

    ViewStub stub = null;
    TextView tx = null;

    int counter = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        b1 = (Button) findViewById(R.id.btn1);
        b2 = (Button) findViewById(R.id.btn2);
        b1.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (stub == null) {     
                    stub = (ViewStub) findViewById(R.id.stub_import);
                    View inflated = stub.inflate();
                    tx = (TextView) inflated.findViewById(R.id.text1);
                    tx.setText("thanks a lot my friend..");
                } 

            }
        });

        b2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (stub != null) {
                    stub.setVisibility(View.GONE);
                }

            }
        });

    }

那么,让我们再看看视图层次结构,

当我们对viewstub进行膨胀时,它将从视图层次结构中移除。

【讨论】:

  • 注意:inflate() 方法在完成后返回膨胀的视图。因此,如果您需要与布局交互,则无需调用 findViewById()。所以存根 = (ViewStub) findViewById(R.id.stub_import); tx = (TextView) findViewById(R.id.text1); tx.setText("非常感谢我的朋友..");存根.inflate();参考:- developer.android.com/training/improving-layouts/…
  • 鉴于它不支持在它所代表的内容视图中进行合并,出于某种完全愚蠢的原因,我认为这个原因是无效的。它对高效的布局没有帮助;这让他们变得更糟。
  • @huseyin 为您使用 View.GONE 设置可见性的 b2 按钮。 Android 开发者博客使用 View.INVISIBLE。你能说说你为什么用 GONE 而不是 INVISIBLE 吗?
【解决方案3】:

这是一个在运行时显示/隐藏和更改ViewStub 数据的示例

activity_main.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/buttonShow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show View Stub"/>

    <Button
        android:id="@+id/buttonHide"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hide View Stub"/>

    <ViewStub
        android:id="@+id/viewStub"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout="@layout/layout_of_view_stub"
        />

</LinearLayout>

layout_of_view_stub.xml

<TextView
    android:id="@+id/textInViewStub"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="ViewStub Button"
    />

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private ViewStub viewStub;
    private Button buttonShow;
    private Button buttonHide;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        buttonShow = findViewById(R.id.buttonShow);
        buttonHide = findViewById(R.id.buttonHide);
        buttonShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showViewStub();
            }
        });

        buttonHide.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                hideViewStub();
            }
        });
    }

    private void showViewStub() {
        if (viewStub == null) {
            viewStub = findViewById(R.id.viewStub);

            // If you want to change data of ViewStub at runtime, you can do like this
            View inflatedView = viewStub.inflate();
            TextView textViewInViewStub = inflatedView.findViewById(R.id.textInViewStub);
            textViewInViewStub.setText("ABC");
        }
        viewStub.setVisibility(View.VISIBLE);
    }

    private void hideViewStub() {
        if (viewStub == null) {
            return;
        }
        viewStub.setVisibility(View.GONE);
    }
}

【讨论】:

  • 通俗易懂。谢谢
猜你喜欢
  • 2020-10-06
  • 2019-02-21
  • 2014-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多