开发过程中有个地方使用了ViewStub,但是发现ViewStub调用setTranslationX之后并没有任何反应,经过一番实验,发现使用inflate获取了View之后,再对View使用setTranslationX才会有效果
public class ViewStubTestActivity extends Activity {
ViewStub sb1;
ViewStub sb2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_viewstub);
sb1 = (ViewStub) findViewById(R.id.stub_1);
sb2 = (ViewStub) findViewById(R.id.stub_2);
// sb1.setVisibility(View.VISIBLE); // 或者使用sb1.inflate()
// sb1.setTranslationX(100); // 然后这个并没有效果
sb1.inflate().setTranslationX(100); // 这个才有效
}
}
简单读了一下源码,发现ViewStub在实例化具体内容的时候,把自己给移除了,同时将具体内容作为一个引用存了下来。而不是自身转换为目标,也不是自己将目标作为自身的子view。
所以我们应该去用这个mInflatedViewRef所指代的View
而不是用ViewStub本身。
贴一段源码。
/**
* Inflates the layout resource identified by {@link #getLayoutResource()}
* and replaces this StubbedView in its parent by the inflated layout resource.
*
* @return The inflated layout resource.
*
*/
public View inflate() {
final ViewParent viewParent = getParent();
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.inflate(mLayoutResource, parent,
false);
if (mInflatedId != NO_ID) {
view.setId(mInflatedId);
}
final int index = parent.indexOfChild(this);
parent.removeViewInLayout(this);
final ViewGroup.LayoutParams layoutParams = getLayoutParams();
if (layoutParams != null) {
parent.addView(view, index, layoutParams);
} else {
parent.addView(view, index);
}
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");
}
}
以上。