Android ViewStub change layouts programmatically

前端 未结 2 595
长发绾君心
长发绾君心 2021-01-03 08:24

This is my use case:

I want to change my inflated layout at run time, say first I inflate layout a, then after some time I want to show layout B, then layout C etc.<

相关标签:
2条回答
  • 2021-01-03 08:55

    Yes, I think you can easily replace it with another ViewStub and lazily inflate your new layout in this way:

    for Java

     public static ViewStub deflate(View view) {
        ViewParent viewParent = view.getParent();
        if (viewParent != null && viewParent instanceof ViewGroup) {
            int index = ((ViewGroup) viewParent).indexOfChild(view);
            int inflatedId = view.getId();
            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
            ((ViewGroup) viewParent).removeView(view);
            Context context = ((ViewGroup) viewParent).getContext();
            ViewStub viewStub = new ViewStub(context);
            viewStub.setInflatedId(inflatedId);
            viewStub.setLayoutParams(layoutParams);
            ((ViewGroup) viewParent).addView(viewStub, index);
            return viewStub;
        } else {
            throw new IllegalStateException("Inflated View has not a parent");
        }
    }
    

    or Kotlin with an extension

    fun ViewStub.deflate(view: View): ViewStub {
        val viewParent = view.parent
    
        if (viewParent != null && viewParent is ViewGroup) {
            val index = viewParent.indexOfChild(view)
            viewParent.removeView(view)
            val viewStub = ViewStub(context).apply {
                inflatedId = this@deflate.inflatedId
                layoutParams = this@deflate.layoutParams
            }
            viewParent.addView(viewStub, index)
            return viewStub
        } else {
            throw IllegalStateException("Inflated View has not a parent")
        }
    }
    

    Check out the gist

    0 讨论(0)
  • 2021-01-03 09:00

    A ViewStub is a placeholder, which is replaced by an inflated layout as soon as ViewStub.inflate() is called. It doesn't make sense to call inflate a second time, as the ViewStub will no longer be in the hierarchy. Instead, you should obtain a reference to your LinearLayout, remove its views, and add your second layout as a child.

    ViewStub stub = (ViewStub) findViewById(R.id.layout_stub);
    LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
    stub.setLayoutResource(layoutId);
    stub.inflate(); // inflate 1st layout
    
    ll.removeAllViews(); // remove previous view, add 2nd layout
    ll.addView(LayoutInflater.from(context).inflate(secondLayoutId, ll, false));
    
    0 讨论(0)
提交回复
热议问题