ViewStub是android中view的一种优化方案,它的目的是在不需要显示view的时候不去加载view,这样在view的创建时期,减少了加载的资源,优化了view。
下面就用代码来说明如何使用viewstub。
先上图
功能很简单,当点击traggle时,下面的viewstub会加载其中预置的layout,再次点击时,隐藏viewstub。
代码如下
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Traggle" /> <ViewStub android:id="@+id/stub" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout="@layout/<span style="font-family: Arial, Helvetica, sans-serif;">text_layout</span>" /> <Button android:id="@+id/btn1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Traggle2" /> </LinearLayout>
text_layout.xml
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:text="ddddddddddddddddddddddddd \n ddddddddddddddddddddddddddddddddddddddd \n ddddddddddddddddddddddddddddddddddddddd \n ddddddddddddddddddddddddddddddddddddddd \n ddddddddddddddddddddddddddddddddddddddd \n ddddddddddddddddddddddddddddddddddddddd \n ddddddddddddddddddddddddddddddddddddd" > </TextView>
package com.example.listscroll; import android.app.Activity; import android.app.ListActivity; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.view.LayoutInflater; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewStub; import android.view.WindowManager; import android.view.animation.AnimationUtils; import android.widget.AbsListView; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ListView; import android.widget.TextView; public class MainActivity extends Activity { private boolean mShowed; private View mTextPanel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if (mTextPanel == null) { mTextPanel = ((ViewStub) findViewById(R.id.stub)).inflate(); } if (mShowed == false) { mShowed = true; showPanel(mTextPanel, true); } else { mShowed = false; hidePanel(mTextPanel, true); } } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } private void showPanel(View panel, boolean slideUp) { panel.startAnimation(AnimationUtils.loadAnimation(this, slideUp ? R.anim.slide_in : R.anim.slide_out_top)); panel.setVisibility(View.VISIBLE); } private void hidePanel(View panel, boolean slideDown) { panel.startAnimation(AnimationUtils.loadAnimation(this, slideDown ? R.anim.slide_out : R.anim.slide_in_top)); panel.setVisibility(View.GONE); } }
下面是4个简单的动画效果,展示viewstub的加载
slide_in_top.xml<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="200" android:fromYDelta="0%" android:toYDelta="-100%" /> <alpha android:duration="200" android:fromAlpha="1.0" android:toAlpha="0.0" /> </set>slide_in.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="200" android:fromYDelta="100%" android:toYDelta="0%" /> <alpha android:duration="200" android:fromAlpha="0.0" android:toAlpha="1.0" /> </set>slide_out_top.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="200" android:fromYDelta="-100%" android:toYDelta="0%" /> <alpha android:duration="200" android:fromAlpha="0.0" android:toAlpha="1.0" /> </set>slide_out.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="200" android:fromYDelta="0%" android:toYDelta="100%" /> <alpha android:duration="200" android:fromAlpha="1.0" android:toAlpha="0.0" /> </set>
ViewStub中加载layout的代码是
public View inflate() { final ViewParent viewParent = getParent();// 获取当前view的父view,用于获取需要加载的layout的index if (viewParent != null && viewParent instanceof ViewGroup) { if (mLayoutResource != 0) { final ViewGroup parent = (ViewGroup) viewParent; final LayoutInflater factory; if (mInflater != null) { factory = mInflater; } else { factory = LayoutInflater.from(mContext); } final View view = factory.<strong><span style="font-size:14px;color:#ff0000;">inflate</span></strong>(mLayoutResource, parent, false);// 获取需要加载的layout if (mInflatedId != NO_ID) { view.setId(mInflatedId); } final int index = parent.indexOfChild(this); parent.removeViewInLayout(this);// 删除之前加载的view final ViewGroup.LayoutParams layoutParams = getLayoutParams(); if (layoutParams != null) { parent.addView(view, index, layoutParams); } else { parent.<strong><span style="font-size:14px;color:#ff0000;">addView</span></strong>(view, index);// 添加view } mInflatedViewRef = new WeakReference<View>(view); if (mInflateListener != null) { mInflateListener.onInflate(this, view); } return view; } else { throw new IllegalArgumentException("ViewStub must have a valid layoutResource"); } } else { throw new IllegalStateException("ViewStub must have a non-null ViewGroup viewParent"); } }