I am building parts of my layout programmatically.
My process looks like this:
I inflate a layout: View view = inflater.inflate(R.layout.view_layout, viewGroup, false);
I add this view to the ViewGroup: viewGroup.addView(view);
Before adding views in this way, I first add a fragment to the root view of viewGroup:
getChildFragmentManager().beginTransaction().add(R.id.viewgroup_root, fragment, "fragment_tag").commit();
My ViewGroup is a LinearLayout and I am adding the Fragment before I add the other views. However, the Fragment is appearing last - after all the views I add using ViewGroup.addView().
How can I get the added Fragment to be displayed first in the LinearLayout, and why is the LinearLayout displaying it last if it was added first?
commit() is asynchronous - it does not run immediately. Therefore you definitely are running your addView methods before your fragment is actually added.
As Fragments automatically are re-added to their respective layout based on ID and you do not control the ordering of when the fragment is added to the layout in those cases, you can't rely on any initial ordering.
Instead, you should always add a Fragment to its own container - if using Fragment 1.2.0 or higher (the latest right now is 1.2.5), you should add a FragmentContainerView to your LinearLayout. If you're using an earlier version of Fragments, you'd want to add a FrameLayout to your LinearLayout. In either case, you'd need to make sure you use setId() with that layout and use the same ID when you use add.
You will have to leave placeholder under your LinearLayout and use placeholder's ID to do beginTransaction/add stuff. Any viewgroup would do. You are not just adding another view to your viewgroup, you are adding a fragment. It has its own lifecycle, bound to entities hosting it (activity, fragment).
Related
I have a scrollview in an activity that I want to populate. Each item I want to add to the list is made up of several views (text view, image view, etc). Instead of programmatically creating each view, and adding it to a linear layout, and then adding that to the containing layout, is it possible to instead create a predefined layout resource with these items and instead add it to the view and programmatically change the item contents?
Essentially, is it possible to do something like:
container.addView(R.layout.listItem);
And if so, how could I access views within the list item to change them?
It's just what inflate(int, ViewGroup, boolean) does with the third parameter attachToRoot set to true
getLayoutInflater().inflate(R.layout.listItem, container, true);
After that everything is straightforward
container.findViewById(R.id.text_view)
You have to "inflate" your view by LayoutInflater. For example like this:
View view = LayoutInflater.from(context).inflate(R.layout.listItem, container, true);
or
View view = LayoutInflater.from(context).inflate(R.layout.listItem, container, false);
container.addView(view);
I have a problem figuring out how to create a custom android view that contains other views in it like a table. How can I create a method in that android custom view class for adding a view inside it, I would like to know how the parent view will resize and position the child view.
How can I create a table like view that I can use to add other views in ?
Should I extend View(since I actually want to create a view not a layout) or ViewGroup(since I want to add other views in it) ?
This is what I hope to obtain:
I'am trying to use a custom listView in my application and i have some questions about its working principles.When i implemented a custom adapter,how its methods(especially the getView method)work without calling them from any other class ?
When you set the adapter to a view (e.g. ListView or GridView), that view at some point wants to have some items to show. So it calls getView in the adapter:
getView(int position, View convertView, ViewGroup parent).
The position is the position of the item in the list/grid/etc. The convertView is a recycled view that can be already inflated by a previous getView() call, or null when it's not inflated yet (see this answer about convertView and view recycling.
The parent is used to inflated the view, so the correct layout parameters can be computed in relation to the parent view.
Note that inflation is slow. That is why the convertView mechanism exists, to recycle views so the number of inflations is minimized. Next to that, finding views (findViewById()) is also relatively slow. To improve on that, check out the ViewHolder pattern, which keeps references to views in memory so they don't have to be searched for each time.
I think this link can help you. getview is a callback function which will be called automatically when you will display your listview on Activity. When you display your listview then you overrides getview and inflates your row from XML or dynamically creates your row. That row you return as a view which displays in your listview.
How does the getView() method work when creating your own custom adapter?
For each row getview will be called once. You create your layouts and return them as view. Those respective views displays in your lisview rows.
You are calling the custom adapter class from you activity class.Your customised adapter class extends a BaseAdapter which is an abstract class.The methods of an abstract will be used by the extended class(the methods like getView(), getItemId(), getItem(), and getCount()).These methods should not need a seperate call from your Class since you are calling the customised adapter classs .
I have a fragment that has a layout with non-unique IDs (the layout repeats itself multiple times). For example:
LinearLayout (vertical)
FrameLayout (id = R.id.always_the_same)
FrameLayout (id = R.id.always_the_same)
FrameLayout (id = R.id.always_the_same)
I can't make the IDs unique because they are loaded from an XML file individually.
For each of the FrameLayouts, I would like to add a child fragment inside. I tried to call the following multiple times from the outer fragment's onCreateView method, but it added all of the child fragments to the first FrameLayout.
this.getChildFragmentManager().beginTransaction()
.add(R.id.always_the_same, MyChildFragment.newInstance(), "tag")
.commit();
How can I specify which FrameLayout to add the fragment to? Or am I going about this all wrong and should be using something other than nested Fragments?
OK, found a workaround:
In the outer fragment's onCreateView method, instead of adding the fragments directly, I added placeholder layouts with unique IDs to the FrameLayouts. Then in the outer fragment's onStart method, I used those unique IDs to add the fragments.
I have read the android documentation about getLayoutInflator and I am still not understanding what it does. Can someone give me a use case for this method or may be during what time would you want to call getLayoutInflator?
XML Layouts in Android need to be Inflated (parsed into View objects) before they are used. getLayoutInflator() gets you an instance of the LayoutInflator that will allow you to manually inflate layouts for specific uses.
One example being in a Custom ArrayAdapter to populate a ListView with a Custom Layout.
You need to manually inflate and populate your desired Layout for each individual list item in the ArrayAdapter's overridden getView() method.
Use setContentView() when you're in an Activity. That method inflates the layout and displays the selected layout as the view for that Activity. But when you're NOT in an Activity and you need to work with a layout file, you have to inflate it to get access to the view objects in the XML.