Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android custom view group delegate addView

I want to implement custom ViewGroup in my case derived from FrameLayout but I want all child views added from xml to be added not directly into this view but in FrameLayout contained in this custom ViewGroup. Let me show example to make it clear.

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:orientation="vertical">
    <FrameLayout
        android:id="@+id/frame_layout_child_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <FrameLayout
        android:id="@+id/frame_layout_top"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</merge>

And I want to redirect adding all child view to FrameLayout with id frame_layout_child_container.

So of course I overrode methods addView() like this

  @Override
    public void addView(View child) {
        this.mFrameLayoutChildViewsContainer.addView(child);
    }

But for sure this doesn't work because for this time mFrameLayoutChildViewsContainer is not added to the root custom view.

My idea is always keep some view on on the top in this container frame_layout_top and all child views added into custom component should go to frame_layout_child_container

Example of using custom view

   <CustomFrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"/>
    </CustomFrameLayout>

So in this case TextView should be added to the frame_layout_child_container

Is it possible to delegate adding all views into child ViewGroup like I described.

I have other ideas like using bringToFront() method every time view is added to keep them in correct z-axis order or for example when view is added, save it to array and than after inflating custom view add all views to this child FrameLayout

Suggest what to do in this case in order not to hit performance with reinflating all layout every time new view is added, if it is possible to implement in other way.

like image 634
CROSP Avatar asked Apr 29 '16 19:04

CROSP


People also ask

What is Match_parent and Wrap_content in android?

fill_parent and match_parent are the same, used when we want the height or width of a view to be as big as its parent view, fill_parent being deprecated. wrap_content is used when we want the view to occupy only as much space as required by it. You may also read : Android UI Layouts.

What is ViewGroup android?

ViewGroup is a collection of Views(TextView, EditText, ListView, etc..), somewhat like a container. A View object is a component of the user interface (UI) like a button or a text box, and it's also called a widget.

What is view and ViewGroup?

View is the base class for widgets, which are used to create interactive UI components like buttons, text fields, etc. The ViewGroup is a subclass of View and provides invisible container that hold other Views or other ViewGroups and define their layout properties.

What is FrameLayout?

Android Framelayout is a ViewGroup subclass that is used to specify the position of multiple views placed on top of each other to represent a single view screen. Generally, we can say FrameLayout simply blocks a particular area on the screen to display a single view.


1 Answers

Views inflated from a layout - like your example TextView - are not added to their parent ViewGroup with addView(View child), which is why overriding just that method didn't work for you. You want to override addView(View child, int index, ViewGroup.LayoutParams params), which all of the other addView() overloads end up calling.

In that method, check if the child being added is one of your two special FrameLayouts. If it is, let the super class handle the add. Otherwise, add the child to your container FrameLayout.

public class CustomFrameLayout extends FrameLayout {

    private final FrameLayout topLayout;
    private final FrameLayout containerLayout;

    ...

    public CustomFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        LayoutInflater.from(context).inflate(R.layout.custom, this, true);
        topLayout = (FrameLayout) findViewById(R.id.frame_layout_top);
        containerLayout = (FrameLayout) findViewById(R.id.frame_layout_child_container);
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        final int id = child.getId();
        if (id == R.id.frame_layout_top || id == R.id.frame_layout_child_container) {
            super.addView(child, index, params);
        }
        else {
            containerLayout.addView(child, index, params);
        }
    }
}
like image 111
Mike M. Avatar answered Oct 01 '22 07:10

Mike M.