Inflate multiple layouts

﹥>﹥吖頭↗ 提交于 2019-12-05 05:41:24

问题


Inside a fragment I try to inflate two layouts besides the root layout:

View a, b;

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

     View root = inflater.inflate(R.layout.list_fragment, container, false);

    //..
    a = inflater.inflate(R.layout.empty_list_view, container);
    b = inflater.inflate(R.layout.progress_list_view, container);
    //..

    return root;
}

public void showB() {
    a.setVisibility(GONE);
    b.setVisibility(VISIBLE);
}

So I just return a single layout from the onCreateView method. However I inflate two more, a and b.

However when I display b actually a will be displayed. So progress_list_view never shows up. Can someone explain this strange behavior?

I suspect that a and b are both added to the container (ViewGroup). And since a is added first, it will be displayed first.


回答1:


edit:

The point is, you're doing a huge mess and there is no good reason why you're doing it.

What happens there is that you inflate root, but not attach it to the container with this line View root = inflater.inflate(R.layout.list_fragment, container, false);

Then you inflate two views and add them directly to the container with those lines a = inflater.inflate(R.layout.empty_list_view, container);, which is a wrong thing to do as per Fragment documentation:

The fragment should not add the view itself, but this can be used to generate the LayoutParams of the view

also both a and b are the same object, which is the container object as per documentation for the LayoutInflater

If root was supplied, this is the root

and root was supplied by you and it's the container, so what you have is basically the same asa=container; b=container;

and then you return root, at which point I really don't know what is happening anymore due to this mess. I decribed.

Lucky to fix is easy:

create another XML layout like this (shortened):

<FrameLayout>
    <include layout="@layout/empty_list_view"/>
    <include layout="@layout/progress_list_view"/>
</FrameLayout>

then you inflate this new XML:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
     View root = inflater.inflate(R.layout.new_xml, container, false);
    a = root.findViewById( .. ID of the root of empty_list_view.. )
    b = root.findViewById( .. ID of the root of progress_list_view.. )
    return root;
}

then the code will work.

original answer:

There's no strange behavior. You inflated those layouts and you have 2 View objects that are representative of them. But nothing attached those Views to the UI.

Only the view that you return from the onCreateView method that will be attached to the device UI.

For example:

the following code will show a:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    //..
    View a = inflater.inflate(R.layout.empty_list_view, container);
    View b = inflater.inflate(R.layout.progress_list_view, container);
    //..
    return a;
}

the following code will show b:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    //..
    View a = inflater.inflate(R.layout.empty_list_view, container);
    View b = inflater.inflate(R.layout.progress_list_view, container);
    //..
    return b;
}

if you want to have them both togeher you should put them together in the XML layout file. Maybe using an include tag if you need it re-usable.




回答2:


You can only return one view from the onCreateView. The view that is returned is the view that is displayed. Looks like you always return view a.




回答3:


/** Called when the activity is first created. */

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    LinearLayout layoutMain = new LinearLayout(this);
    layoutMain.setOrientation(LinearLayout.HORIZONTAL);
    setContentView(layoutMain);
    LayoutInflater inflate = (LayoutInflater)       getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    // 1st Layout
    RelativeLayout layoutLeft = (RelativeLayout) inflate.inflate(
        R.layout.main, null);

    // 2nd Layout
    RelativeLayout layoutRight = (RelativeLayout) inflate.inflate(
       R.layout.row, null);

    RelativeLayout.LayoutParams relParam = new RelativeLayout.LayoutParams(
    RelativeLayout.LayoutParams.WRAP_CONTENT,
    RelativeLayout.LayoutParams.WRAP_CONTENT);
    layoutMain.addView(layoutLeft, 100, 100);
    layoutMain.addView(layoutRight, relParam);
 }



回答4:


R.layout.list_fragment should look something like this:

<FrameLayout>
    <include 
        android:id="@+id/a"
        layout="@layout/empty_list_view"/>
    <include 
        android:id="@+id/b"
        layout="@layout/progress_list_view"/>
</FrameLayout>

Your code will look something like this:

View a, b;

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View root = inflater.inflate(R.layout.list_fragment, container, false);
    a = root.findViewById(R.id.a);
    b = root.findViewById(R.id.b);

    return root;
}

public void showB() {
    a.setVisibility(GONE);
    b.setVisibility(VISIBLE);
}



回答5:


Why don't you inflate new view in the container.

Try this

LayoutInflater mInflater  = null;  
ViewGroup mContainer = null;

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    mInflater = inflater;
    mContainer = container;
    View root = inflater.inflate(R.layout.list_fragment, container, false);
    return root;
}

public void showB() {
    mInflater.inflate(R.layout.progress_list_view, mContainer, false);
}


public void showA() {
    mInflater.inflate(R.layout.empty_list_view, mContainer, false);
}


来源:https://stackoverflow.com/questions/32247542/inflate-multiple-layouts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!