I'd like to see all the dynamically created Buttons, TextViews, etc before (or even after) setContentView() shows them on the screen. I have a loose understanding that this relates to the Context and the Activity, but concretely I don't know where these dynamic views exist / how they are put together at runtime.
And if they are shown at runtime is there a way to list all of them?
LinearLayout layout = new LinearLayout(this);
layout.addView(button1);
layout.addView(button2);
layout.addView(button3);
setContentView(layout);
The buttons SHOULD exist somewhere (I am so sure they exist in the Context!!) but there is no way (that I have found) of locating these dynamically created views.
Please and thanks.
In general, if you are going to need to display these kinds of things on the screen, then you should keep a reference to them somewhere. This is a common pattern, if you dynamically create a button, you need to stuff them in a List (for example). You shouldn't need to get all the views if you program like this, and even if you easily could (typically in GUIs, you can, either by reflection, or something equally tacky mechanism) it wouldn't be organized in any kind of logical structure that would relate the things in the layout to the logical layout dictated by the application. So instead, when you dynamically create views, stuff them somewhere like a list so you can iterate through it later.
Related
I am new to android programming am trying to learn it.
So basically there are two ways of creating whatever is going to be visible on the screen :-
We create views and view group objects inside layout.xml files. And then as the need be we access those views that are already existing
in the layout through our java programs by accessing their ids ( as
r.java….). So basically when we start a particular activity, we
set the content to be displayed corresponding to that activity using
setContentView method, to which we pass the layout.xml file, inside
which we have defined the different views and view groups to be
displayed on the screen.
The second way is we create these views dynamically though our java programs and then set them as the content on the screen using
setContentView again.
Now the above is my basic understanding. Please let me know if the above needs correction.
Now what I want to understand here is :-
Is there a way that using the first method itself, we can do the
vice-versa, as in say instead of fetching the the views through their
ids from the layout.xml files, can we already have a predefined
layout.xml file with different views having ids, and now through our
java programs can we just access those views though their ids and set
their values, something like say (in javascript) :-
document.getElementById(“someTextBoxId”).value= “some calculated
value from java code here”
Thanks.
Let's say i have the Android XML file home_page.xml.
on this home_page.xml i have some variations that i want to show at different activities, and i'd like to reuse the same main layout home_page.xml.
For example, imagine variations on the page such as:
there's 2 more buttons if the user is in state A
there's 1 more editText field if the user is in state B (same activity as state A)
there's a different arrangement of layout on the Z-axis in a frame layout if the user is in state C (same activity as state A)
i know it's possible to programmatically say hide views and set views as visible. but is there a better way to do this via xml or something?
Android recommends using 2 Tags for re-using the layouts across different screens.
Include
When to Use ?
If you already know the layout that you want to re-use, create a new XML file and define the layout. Use tag to re-use it.
Merge
When to Use ?
To eliminate redundant view groups in your view hierarchy when including one layout within another, we can use tag.
Refer to this link - http://developer.android.com/training/improving-layouts/reusing-layouts.html for code sample and more details.
You can hide views but using the Visibility flag.
View v = findViewById(R.Id.my_view);
v.setVisiblity(View.GONE); //etc.
I've tried stuff like this before. I had mixed results. This is fine if you are doing things, like asking the user for a name, then showing an address input or something. But if you find yourself with like 3 or 4 conditions for one editText and then different ones for a button in the same class you might want to just use different layouts. A lot easier to manage.
I want to create a XML layout dynamically but I had a question on doing so.
Say I have something like this (Looking at the layout from the "Outline" perspective):
-ScrollView
---Linear Layout(Vertical) (LL1)
-------Linear Layout(Horizontal) (LL2)
-----------Image View (IV1)
-----------Linear Layout(Vertical) (LL3)
---------------TextView
---------------TextView
So my question here is would I start with the most inner Layout (LL3) and add the 2 TextViews and then branch upwards (to LL2 then LL1 then ScrollView) with adding to the other views & layouts?
I believe you can do this several ways. I've not tried creating an entire hierarchy like this dynamically, but I've added buttons, radio-buttons, text-views and other Views this way several times. In those cases, I've just added new ones to the ones that already exist using AddView().
I think the easiest way is to just create it "top down", i.e. create the ScrollView first and add any settings, then add the other views to it downwards. I would typically do something like this:
// Call other methods to create the views first:
ScrollView myScrollView = createMainScrollView();
LinearLayout myHorizontalLayout = createLinearLayoutForAbc();
LinearLayout myOtherLayout = createLinearLayoutForXyz();
TextView myFirstTxt = (...)
(..etc..)
Now populate them in the right way:
myScrollView.addView(myHorizontalLayout);
myHorizontalLayout.addView(myOtherLayout);
(..etc..)
Note:
I do believe this should work, but I can not guarantee it; if the reference to an inner view is no longer correct after having been added to an outer view (Eg. myHorizontalLayout is no longer a valid ref to the actual view under myScrollView), you might not be able to add children to that inner view. Not sure about this, though.
(If so, you might try to fetch a new, correct reference using findViewByName() after adding each view, but I don't think that would be an optimal solution).
I would try the first way first - at least make a proof of concept, to see that you can add view in a hierarchy at least three levels deep. That should give you your answer. If it does not work, I suppose I would try adding them in the opposite order, as you suggest in your question, just to see if that works (maybe just switch the order in my second code block?).
Sorry for the imprecise answer, hope it is of some help anyway.
I assumed that each layout's element id's such as buttons, textviews, edittexts, etc. were unique and private to that layout. This being said, you set the Activity to use a certain layout, you should only be able to find view id's based on the id's set in that specific layout.
However, I am finding now that I can reference whatever view id I want from my Activity regardless of the physical layout I have specified with "setContentView(R.layout.THELAYOUTIWANTTOTARGET)". Is this behavior normal, I figured only id's of those elements on the layout I specified above would be available? Looking at R.java, I believe all the id's I specified on all layouts are made public variables, thus, no id's can have the same name or unexpected behavior may occur!
The implications for this on my project is that I must now change all id's in all layouts to be unique. I figured my supplier layout > title textview would have been different from my customer layout > title textview, is this not the case?
Thank you for clarifying!
Your assumption is correct. IDS are global, and for large projects it's sometimes a pain, leading to very long ID names. But that can also be used as an advantage, as you can reuse layouts on different activities.
For example, you can have a layout for a specific part of your activity (a custom buttons bar for example) that you may want to add to several activities. In this case, you can just inflate it into a specific ViewGroup of the first activity, and also in another ViewGroup in another activity. The methods to access specific buttons based on their ids can then be reused in both activities.
The method findViewById will only work on the activity you call it from. If a button (or any other component) exists on different activities, only the one in your current activity will be returned.
Yes, it is normal. As far as I know, there is no way to change it.
So yes, the implication that you will have to have different names for views in different layouts is correct.
EDIT:
Actually... scratch that. I was under the impression that it was necessary, but according to
http://developer.android.com/reference/android/view/View.html
it isn't even necessary to have id's be unique in a single file. Just make sure you aren't searching in a tree that has multiple ids that are the same or you will always get the first occurrence.
It makes sense too since it doesn't really matter if the views have the same ID in R. I will keep this in mind going forward.
i got the following "problem".
I want to have an activity thats shows me the standings of some teams at a specific gameday.
therefor i would add a spinner and a TableLayout. At the first Start the activity should show the standings of the actual gameday but then you can choose any other gaymeday and the standing should get updated.
Whats the best way to create this activity?
assemble the whole TableLayout with all TableRows and TextViews, give them ids and update those views via id during runtime. Problem: huge unflexible hardcoded layout.xml
assemble the layout during runtime, add ids, update via ids
assemble the layout during runtime. on update remove old views and create new ones
assemble the layout during runtime. on update restart the activity
just whant to know which one is the best. or is there any other way to achieve that
thx Cheetah
If I were you, I'd actually use a GridView with an Adapter. This will abstract away all the handling of layout changes. You just have to worry about mapping your data to appropriate views. This example maps ImageViews to a GridView, but there's no reason you couldn't map to TextViews containing your data in a GridView. Also, because you're using an adapter, you can take advantage of all the Loader classes and they're asynchronous loading capabilities.
In addition, using the approach will allow you program to easily adapt as your dataset changes. You may want to add more data to the table in the future and this approach will allow you to easily do that without having to constantly change your xml layouts.
Does the number of views change? If no. Best way is to use the already existent views and update their values. Try to avoid recreating/reinflating views since that's an expensive task.