I would like to know how the child views in my custom RelativeLayout is drawn so that I can use getChildAt() (the childviews are defined in xml).
In particular, my layout contains 5 of these custom layout each containing a number of child views. Most solution I seen seem to be using findViewById() and indexOfChild(), however, since each child view with the same id would appear 5 times I am unsure if this method can be implemented. As a side note I would also like to know if how the index is determined so that when I make modification to the custom layout I would know how to adjust the index. Thanks!
RelativeLayout does not override getChildAt, so the order is the one defined in ViewGroup. The code of getChildAt is
2914 public View getChildAt(int index) {
2915 try {
2916 return mChildren[index];
2917 } catch (IndexOutOfBoundsException ex) {
2918 return null;
2919 }
2920 }
Related
Haven't found something to understand how to use it correctly.
I need to measure 2 views.
For first view i use this:
viewPager.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
//my measure code
viewPager.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
So what should i do for second view: i should use another same block of code, but for second view or can i put second measurement inside viewpager's measurements?
Added: logically it can be different cases:
One view inside another view.
Two views near each other in same parent (viewObserver on first view).
Two views near each other in same parent (viewObserver on parent).
I have the following hierarchy in my layout:
ScrollView
RadioGroup
RelativeLayout
RadioButton
ImageView
RelativeLayout
RadioButton
ImageView
...
Now the point is, that it looks fine in the XML editor where RadioButtons and ImageViews have default values (placeholders) defined, but when I launch an activity and call removeAllViews() on the RadioGroup, all ImageViews disappear. What's interesting, all buttons get new values, only ImageViews are not updated anyhow (setting new source images gives no results).
So, my question is: does removeAllViews() erase the child views completely (like they never existed in a layout XML file) or just removes some values leaving the views' arguments to be defined (like setting new source image or new button description)?
From the official documentation, removeAllViews():
Call this method to remove all child views from the ViewGroup.
Calling this method will set all the childs view to null, so it will remove the child views from itself, and this child becomes not valid (or not considered as child), but not like it never existed in XML file.
This is removeAllViews() code:
public void removeAllViews() {
removeAllViewsInLayout();
requestLayout();
invalidate();
}
As you can see in removeAllViewsInLayout() method, it set the child value to null:
children[i] = null;
For an important reason, i'm required to keep only a single instance of a View in the entire application.
Within the application there will be multiple parent views, (each displayed only once at at time). And I need to move the child view around - to the currently active parent.
I tried doing the following:
if (view_to_move_around != null) {
ViewGroup oldParent = (ViewGroup) view_to_move_around.getParent();
if (oldParent != null) {
oldParent.removeView(view_to_move_around);
}
} else {
// Initialise the View
}
newParent.addView(view_to_move_around)
However, that method didn't seem to work? Completely stuck at this point.
I guess my question will be "What do you mean it's not working?" Are you getting an exception? It is not being displayed properly? Does it execute without issue, but is not displaying? Does it display, but it's always initializing?
Are you manipulating the child view within each parent view, before you pass it on to the next view?
Few things to make sure right off the bat:
Layout Params. Are they all set correctly? For both the parent and the child?
Parent View. The code doesn't appear to be faulty from what I can see. So is the parent view being displayed correctly?
Visibility. Are both the parent and child View.VISIBLE?
EDIT
Sweet. Ok, when I'm debugging these things, I like to keep it simple at first. I would take the child view, set it's background color to purple (or a contrasting color from the parent). Then, for simplicity's sake, set it's layout params to match parent. Assuming the ParentView is a FrameLayout:
mChildView.setBackgroundColor(Color.CYAN);
mNewParentView.addView(mChildView,
new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT, Gravity.CENTER));
Does it fill up and take over the parent?
In the intermediate steps, does it no longer have a parent when it's been removed?
Log.d("LOGTAG", mChildView.getParent().toString());
Does the new parent show that the child has been added?
Log.d("LOGTAG", mNewParentView.getChildCount()): // before and after
Is it being shown 'behind' the other views within the Parent?
mParentView.bringChildToFront(mChildView);
What may be the problem is that you are using getParent() to store oldParent. Compare for example:
if (view_to_move_around != null) {
ViewGroup oldParent = (ViewGroup) findViewById(R.id.old_parent);
if (view_to_move_around.getParent() == oldParent) {
oldParent.removeView(view_to_move_around);
}
} else {
// Initialise the View
}
newParent.addView(view_to_move_around)
Does this sound like what you're looking for? Let me know if this works.
I am adding multiple XML Views programmatically. I'm using a layout inflater to add them and there are no problems with that.
But I'm not able to modify the TextView in each of them.
For example, consider I am adding a LinearLayout three times in my final View. I have a TextView in that linear layout. I extract it using findViewById and if I setText("hello"); it is being reflected in the first layout, but not the second and third.
Will the inflater create new ids dynamically when adding multiple XML elements?
To answer part of your question, no: Ids are not dynamically generated by LayoutInflater.
When you say you are adding the views, where are you adding them? You mention a final View.
You don't include your code, but I assume you are calling Activity.findViewById. If you call this.findViewById from your Activity, you are traversing the entire View hierarchy and finding the first view with such an Id.
What you need to do, is iterate through all of the LinearLayouts that contain your TextViews and call findViewById on each of them.
for (LinearLayout layout : <fill in>) {
((TextView) layout.findViewById(R.id.yourid)).setText("hello");
}
As for the <fill in>. Hard to tell how to fill it in without your code. It seems like you are adding these into a parent view right? Let's assume we have a parent View parent = some view;.
You just have to get all of its children and iterate. There are a few ways you can do it depending on which subclass of View the parent is. Let's keep it simple and assuming the parent is just another LinearLayout.
In that case the for loop changes to something like:
for (int i = 0; i < parent.getChildCount(); i++) {
final LinearLayout layout = (LinearLayout) parent.getChildAt(i);
((TextView) layout.findViewById(R.id.yourid)).setText("hello");
}
Is there a way to create an array containing actual instances of views. For example, if I have one LinearLayout called Container that has within it 3 other LinearLayouts with the same Tag attribute and I wanted to get a list containing all 3 LinearLayouts so I can loop through and handle each.
Tried:
LinearLayout[] layouts = (LinearLayout[]) Container.FindViewWithTag(tag);
and
List<LinearLayout> layouts = (List<LinearLayout>) Container.FindViewWithTag(tag);
and
foreach(LinearLayout layouts in Container.FindViewWithTag(tag))
None of these have been acceptable to Android so far. Another acceptable way to handle my situation would be to just be able to assign each LinearLayout a Parent. But I haven't found a way to programatically set a view's parent, only how to get a view's parent.
What I have understood from your question that you want the child of Linear Layout. Yes, you can get the child of linear layout by container.getChild(index)
for(int i=0;i<container.getChildCount();i++){
View child=container.getChildAt(i);
//your processing....
}