Custom LinearLayout with inflate xml and child node - android

I have a custom navigation class where there are common views therefore i was thinking to put them into one layout which is to be inflated by the custom class and on the main layout ill put some navigation item on it.
Currently when i extends linearlayout, the views in the xml replaces all the views in the inflated view (i put this code on constructor)
((Activity) context).getLayoutInflater().inflate(R.layout.navigation_group, this ,true);
Is there a way where i could inflate a layout and get the child of the xml implementation and put it on one view? like
layout to be inflated
<com.mycompany.NavigationGroup>
<Text android:text="title" ... />
<Button android:text="collapse" ... />
<LinearLayout android:id="#+id/navigationItemHolder ... />
<Text android:text="descriptions" ... />
</com.mycompany.NavigationGroup>
used in main layout
<com.mycompany.NavigationGroup>
<Button android:text="menu 1" />
<Button android:text="menu 2" />
</com.mycompany.NavigationGroup>
My question is how could i put menu 1 & menu 2 inside navigationItemHolder? Thanks

You can do this programmatically after you inflate your layout. I believe you can do something like this:
YourLayout layout = (YourLayout)((Activity) context).getLayoutInflater().inflate(R.layout.navigation_group, this ,true);
layout.((LinearLayout)getChildAt (3)).addView (yourNavigationGroup);

Related

Inflate ViewStub with a native widget

Is it possible to inflate a ViewStub with a native android widget?
For example:
<LinearLayout...>
<TextView...>
<TextView...>
<ViewStub...>
</LinearLayout>
I want to replace/inflate the ViewStub with a Switch or a Checkbox. Is that possible?
To set the layout to inflate into the ViewStub either:
Set the layout via XML:
<ViewStub
android:id="#+id/stub"
android:inflatedId="#+id/myLayout"
android:layout="#layout/myLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Or, set the layout at runtime:
viewStub.setLayoutResource(R.layout.myLayout);
Then, you can inflate the ViewStub.
View inflatedView = viewStub.inflate();
You could call this inflate() method from where you want, such as a Switch or Checkbox being clicked (as you asked).
Currently there is no way to replace the StubView with a View object. You must create a layout representing the view you want to replace. So for example, if you want to switch it with a single CheckBox, you need to create a layout like this
<?xml version="1.0" encoding="utf-8"?>
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_checkbox"
android:text="Click me"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Then calling
viewStub.setLayoutResource(R.layout.my_checkbox);
viewStub.inflate();
If you need a reference to the inflated view you can use this instead
CheckBox checkInflated = (CheckBox)viewStub.inflate();

ViewGroup - Add XML content into different container within inflated ViewGroup

Is it possible to inflate a LinearLayout from XML that contains some static objects and another LinearLayout and later when "XML" code is used inside the LinearLayout it's content is being added inside the inner LinearLayout.
Explanation with some code removed:
<LinearLayout id="main">
<LinearLayout id="top">
<TextView text="This is always here" />
<ImageView src="#drawable/image_alwayshere" />
</LinearLayout>
<LinearLayout id="bottom">
</LinearLayout>
</LinearLayout>
This is then inflated by my View "CustomLinearLayout" or whatever we call it
and when using the View in another Layout:
<com.my.views.CustomLinearLayout>
<ImageButton id="button1" src="#drawable/button1" />
</com.my.views.CustomLinearLayout>
In this case, the ImageButton should not be added below "bottom" it should be added into it. SO whatever I have in top, stays static and whatever I want to change is added to the Bottom LinearLayout.
Is this possible and if it is how could it be done?
Not sure if it's good or bad practice, if it would work. But if I have a constant layout (top container, middle container and bottom container) and I have 10 different activities and the only one changing content is the middle one, I can easily make one change to the top and bottom container at one place instead of 10 places and have whatever "View" I want to show in my activity be added inside.
Maybe I need to create a whole new ViewGroup for this? But currently working on LinearLayout since it's functionality is pretty much what I need.
If not, then what I'm looking for is where and when a LinearLayout reads the content of the XML and then override that to be added to my inner LinearLayout instead.
It is possible, you can either use include tag to add the other xml layout into the "bottom" layout and make its visibility as "gone" and change it to "visible" when you need it.
Or you can do that dynamically and inflate the xml whenever you want then add it to "bottom" using ViewGroup.addView(View) method.

android double layout objects in compound view

When you create a compound view and inflate an xml layout file for it like this:
public class CompundLayout extends LinearLayout{...}
this inflates an xml with root like this:
<LinearLayout ... />
you end up with a layout hierarchy with a LinearLayout inside a LinearLayout (or so I concluded when defining a tag string to the layout object in the xml cased my app to crash).
Am I wrong? is there a better way to do this and prevent this double layout?
There is a better way to avoid the double layout, alter your xml layout to replace the LinearLayout container with a "merge" container. Your xml layout will look something like this afterwards:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView ... />
<EditText ... />
...
</merge>

Android Layout Templating [duplicate]

This question already has an answer here:
Custom Layout in android
(1 answer)
Closed 2 years ago.
I'm looking to a simple way to do layout templating in android.
I already check include and merge techniques without success.
(I think that it's possible creating custom Layouts and defining by code this behavior, but i wondered if that could be done by xml)
I want to define something like this:
[globalLayout]
<linearLayout params=xxx>
<linearLayout params=yyy>
<?yied ?>
</linearLayout>
</linearLayout>
[customView1]
<Linearlayout>
<ImageView />
<Button/>
</LinearLayout>
[customView2]
<Linearlayout>
<Button/>
<Button/>
<Button/>
</LinearLayout>
(these 3 xml should be reusable)
[HomeLayout]
<?include globalLayout >
<?include customView1 />
</include>
[ParamsLayout]
<?include globalLayout >
<?include customView2 />
</include>
The thing is that i want to have a reusable layout, if a perform a small change, it will affect all dependent views. somethink linked to "partial views or templating" in other languages.
Could anyone help me?
I have done something like this before by using view stub.
You can inflate any view you like inside that view.
<GlobalLayout>
<ViewStub>
<GlobalLayout>
Use LayoutInflater to do something like this:
On the Activity's onCreate:
super.onCreate(savedInstanceState);
setContentView(new TemplateInflater(this).apply(R.layout.products)
.onViewGroup(R.id.replace_here).ofTemplate(R.layout.template));
An implementation snippet:
public View ofTemplate(int templateId) {
LayoutInflater inflater = LayoutInflater.from(context);
View root = inflater.inflate(templateId, null);
View content = inflater.inflate(contentId, null);
((ViewGroup)root.findViewById(viewGroupId)).addView(content);
return root;
}
An example of a working code is in my git: https://github.com/erichegt/AndroidTemplating
I think this code will solve your problem, but you should use Fragments instead. You can have one Activity associated with a template and a Fragment to inflate it.
ViewStub is pretty straightforward and can cover basic layout templating needs.
It serves as a placeholder for some other layout which you can specify and inflate at runtime and then:
The inflated View is added to the ViewStub's parent with the ViewStub's layout parameters.
Here is example from one of my projects. In my layout template I have:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout ... >
...
<ViewStub
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/button_1_stub"
app:layout_constraintDimensionRatio="H,1:1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/split_guideline"
app:layout_constraintLeft_toRightOf="#+id/primary_left_guideline"
app:layout_constraintRight_toLeftOf="#+id/primary_right_guideline">
</ViewStub>
....
</android.support.constraint.ConstraintLayout>
... then, when I inflate it I am setting actual button layout that I need and inflate stub:
View contentView = inflater.inflate(R.layout.activity_main_template, null);
ViewStub button1Stub = contentView.findViewById(R.id.button_1_stub);
button1Stub.setLayoutResource(R.layout.work_button);
button1Stub.inflate();
... which inserts layout from R.layout.work_button instead of stub, imposing layout constraints I defined on the R.id.button_1_stub.

Not able to access ViewStub'child

I am trying to use VIEWSTUB inside the merge tag.and its working well.I'm able to catch onclicklistenr of ViewStub's parent button.But i want to access the button that is inside the viewstub.
1.Main xml:
<merge>
<LinearLayout>
<Button></Button>
<ViewStub></ViewStub>
</LinearLayout>
</merge>
2.view stub layout
<Button android:id="#+id/button_cancel" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:minWidth="100dip"
android:text="Next" />
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/imageView"
android:background="#drawable/golden_gate"
/>
</LinearLayout>
I am inflating view stub in an activity...here i want to fire click event on button cancel.How it will be possible
Let's suppose your ViewStub ID is view_stub. You need to do the following in the activity:
ViewStub viewStub = (ViewStub) findViewById(R.id.view_stub);
View inflatedView = viewStub.inflate();
Button button = (Button) inflatedView.findViewById(R.id.button_cancel);
Now you can do whatever you want with the button :) That is, the inflate method returns the stub layout which contains the actual elements from the XML file.
Of course, you can always have the onClick XML attribute...
As for removing the ViewStub - the question is two-fold (check http://developer.android.com/resources/articles/layout-tricks-stubs.html):
before inflation of the ViewStub - you cannot actually remove it. There's no need, though, since ViewStub "has no dimension, it does not draw anything and does not participate in the layout in any way".
after inflation - you just take the View returned by the ViewStub.inflate() method and do whatever you want with it - for example, hide it.

Categories

Resources