bluevoid
bluevoid

Reputation: 1359

How to inflate xml as Custom View without a parent

I have a simple xml which I want to inflate as a java view object. I know how to inflate a view:

view = LayoutInflater.from(context).inflate(R.layout.alarm_handling, this);

But then I have a view which is a child of the parent (this). And then the messy problem starts with setting layoutparameters and having an extra layout which I do not need. These are much easier to do in xml.

With an Activity one can just call: setContentView() but with a View that is not possible.

In the end I would like to have a Java class (extends ViewSomething) which I can refer to in an other xml. I have looked at ViewStub, which almost is the answer, except that it is final :(

public class AlarmView extends ViewStub{ //could work if ViewStub wasn't final

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

    //using methods from ViewStub:
    setLayoutResource(R.layout.alarm_handling);
    inflate();
}
}

So how to to this? What to extend to be able to just call setContentView() or setLayoutResource()?

I looked at many SO answers but none of them fit my question.

Upvotes: 3

Views: 4840

Answers (1)

Budius
Budius

Reputation: 39856

as far as I understood the trick that you want to apply it's a bit different than what you trying to.

No ViewStub are not the solution as ViewStub have a very different way of handling everything.

Let's say for the sake of the example your XML layout is something like this (incomplete, just to show the idea):

<FrameLayout match_parent, match_parent>
     <ImageView src="Myimage", wrap_content, Gravity.LEFT/>
     <TextView text="hello world", wrap_content, Gravity.CENTER_HORIZONTAL/>
</FrameLayout>

then you don't want to extend FrameLayout and inflate this XML inside it, because then you'll have two FrameLayouts (one inside the other) and that's just a stupid waste of memory and processing time. I agree, it is.

But then the trick is to use the merge on your XML.

<merge match_parent, match_parent>
     <ImageView src="Myimage", wrap_content, Gravity.LEFT/>
     <TextView text="hello world", wrap_content, Gravity.CENTER_HORIZONTAL/>
</merge>

and inflate as normal on your widget that extends FrameLayout

public class MyWidget extends FrameLayout
   // and then on your initialisation / construction
   LayoutInflater.from(context).inflate(R.layout.alarm_handling, this);

and your final layout on screen will only have 1 FrameLayout.

happy coding!

Upvotes: 6

Related Questions