一、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/n/249898.html
微信扫一扫
支付宝扫一扫