一、ViewStub概述
ViewStub是Android中一個比較好用的工具類,可以讓我們在布局中預先設置一些不常用的View,當需要使用時才加載進來,可以優化布局加載時間和內存開銷。使用ViewStub可以將布局層次扁平化,以提高布局性能。
ViewStub的優點:
- 方便:可以增加應用程序的負載效率。
- 簡單:加入的布局很簡單,在XML文件使用。
- 高效:由於布局的添加是動態的進行,內存佔用量更小。
- 快速:提高布局加載速度。
二、ViewStub的使用
1.在布局文件中添加ViewStub
可以在布局文件中添加ViewStub標籤,通過設置android:layout布局參數設置ViewStub的位置,code示例如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--其他View省略-->
<ViewStub
android:id="@+id/view_stub"
android:layout="@layout/custom_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
2.在Java文件中進行ViewStub的替換
在Java代碼中可以使用ViewStub的inflate()方法將StubView替換為真正的View,並添加到布局中。在這個例子中,被inflate的布局叫做custom_layout.xml
ViewStub viewStub = findViewById(R.id.view_stub); View inflatedView = viewStub.inflate();
3.使用ViewStub的setVisibility()
也可以使用setVisibility()方法,將ViewStub替換為相應的真正View。
ViewStub viewStub = findViewById(R.id.view_stub); viewStub.setVisibility(View.VISIBLE);
4.使用ViewStub的getInflatedId()
可以使用getInflatedId()方法獲取被inflate的View的ID。
ViewStub viewStub = findViewById(R.id.view_stub); int layoutId = viewStub.getInflatedId();
三、ViewStub原理
ViewStub本質上是一個代理View,當ViewStub替換為真正的View之後,ViewStub就不再存在,成為了普通的View。
可以通過以下方式查看ViewStub的監聽事件:
ViewStub viewStub = findViewById(R.id.view_stub);
viewStub.setOnInflateListener(new ViewStub.OnInflateListener() {
@Override
public void onInflate(ViewStub stub, View inflated) {
Log.d("ViewStubDemo", "inflate()");
}
});
四、ViewStub的擴展
基於ViewStub的原理,可以通過擴展ViewStub做一些有意思的功能。
1.自定義ViewStub
可以擴展ViewStub實現自定義的StubView,提供創建的接口。
public class MyViewStub extends ViewStub {
private View mInflated = null;
private int mLayoutId;
public interface OnInflateListener {
void onInflated(MyViewStub stub, View inflated);
}
private OnInflateListener mListener;
public MyViewStub(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setLayoutResource(int layoutId) {
mLayoutId = layoutId;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mInflated == null) {
setVisibility(View.GONE);
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(mLayoutId, this, true);
if (mListener != null) {
mListener.onInflated(this, view);
}
mInflated = view;
}
else {
setMeasuredDimension(mInflated.getMeasuredWidth(),
mInflated.getMeasuredHeight());
}
}
public void setOnInflateListener(OnInflateListener listener) {
mListener = listener;
}
}
自定義的ViewStub可以在布局文件中使用。
<com.example.myviewstub.MyViewStub
android:id="@+id/my_view_stub"
android:layout="@layout/custom_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
在Java文件中可以使用如下代碼進行ViewStub的替換(和ViewStub使用類似):
MyViewStub myViewStub = findViewById(R.id.my_view_stub); myViewStub.setLayoutResource(R.layout.custom_layout); View inflatedView = myViewStub.inflate();
2.ViewStub的懶加載
可以擴展ViewStub實現懶加載的StubView,可以控制是否需要加載。
public class LazyViewStub extends ViewStub {
private boolean mIsVisibleToUser;
private boolean mHasLoadOnce = false;
public LazyViewStub(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setVisibleToUser(boolean isVisibleToUser) {
mIsVisibleToUser = isVisibleToUser;
if (isVisibleToUser && !mHasLoadOnce) {
inflate();
mHasLoadOnce = true;
}
}
}
使用懶加載的ViewStub時,需要在Java代碼中控制是否需要加載。
LazyViewStub lazyViewStub = findViewById(R.id.lazy_view_stub); lazyViewStub.setLayoutResource(R.layout.custom_layout); lazyViewStub.setVisibleToUser(isVisibleToUser);
五、總結
ViewStub是Android中一個方便、簡單、高效和快速的工具類,可以優化布局加載時間和內存開銷。除此之外,還可以擴展ViewStub實現一些有意思的功能,例如自定義StubView和懶加載。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/249898.html
微信掃一掃
支付寶掃一掃