I am using a FlowLayout which is like a horizontal linear layout , but when it reaches the end of the line elements within the layout continue on the next line .
https://github.com/ApmeM/android-flowlayout
I need to programmatically delete the views on the right of a particular view within the FlowLayout , the views ( textviews ) are created programmatically :
For example (if each letter were a view )
AAAAXBBB
I want to delete the views to the right of the view X.
How I can remove programmatically the siblings to the right of the X view ?
If I keep them all in an array of views , I can do it , but it can be done without having to store the views in an array of views ?
Thanks.
Have you tried using
int children= layout.getChildCount();
for(int i=children-1; i>=0; i--) {
View child = layout.getChildAt(i);
if(child == viewX) {
break;
}
layout.removeViewAt(i);
}
This will loop over the children of the layout from the end to the beginning, removing each one until it finds the view X
Related
I use a for statement to create and add linearlayouts to a pre-existing vertical linearlayout. When creating them I use the for statement variable to assign an id to each one so the first layout has an id of 0 and the last has an id of 4.
for(int i = 0; i < 5; i++){
create layout
layout.setID(i);
}
I know how to change a view that's created like
Linearlayout linearLayout = new LinearLayout();
linearLayout.makeSomeChanges;
But how do I reference the layouts created in my for statement to make changes to them?
You can do it with findViewById() function. Suppose we have vertical linear layout called container. Now we can inflate there 4 items (in my case this items are linear layout with TextView inside). See the code below:
LinearLayout container = findViewById(R.id.container);
for (int i = 0; i < 5; i++) {
View child = getLayoutInflater().inflate(R.layout.item, null);
child.setId(i);
container.addView(child);
}
After adding child layouts we can access their views by ids and change any view inside them like I did with TextView:
for (int i = 0; i < 5; i++) {
View view = container.findViewById(i); // here we get child linear layout
// now we can access any view inside child linear layout and change it,
// or change some parameters of the child layout itself.
TextView textView = view.findViewById(R.id.text);
textView.setText(String.format("Changed Text %d", i));
}
Id should be ideally in resource file to avoid any coflict with existing IDs. In your case if the views are dynamic, it's not a good idea either to put those IDs in resource files.
I would recommend to use setTag() method instead of setId(). Later you can do getViewWithTag() to get the view associated with that tag.
If you are creating View (or layout) objects yourself and adding them to the screen you will have to keep track of them yourself, perhaps by a ArrayList or HashMap or any other way. note that: using setID() you may run into conflicts (two Views with same id), to avoid this you can use View.generateViewId() and keep track of all IDs you get and map them to the View.
Can I somehow extract the number out of a Layout?
I have code similar to this:
linearLayout.addView(randomView, 3);
This means, the element randomView is inserted at position 3 (so it is the 4. element).
I removed another element inside the linearLayout and because of the hardcoded number 3 I ran into an Exception. I want to add my randomView to the end of the layout, so it would be nice if I could do something like this:
linearLayout.addView(randomView, linearLayout.size());
Even if I'm changing the elements of a specific layout, the randomView would then always be at the end of all other elements.
If you don't specify the position view will be added at the end of the ViewGroup.
linearLayout.addView(randomView);
But if you need to specify the position you can get the child count and do this
int childCount = ((ViewGroup)linearLayout).getChildCount();
linearLayout.addView(randomView, childCount);
If you need to access the view inside your linear layout then you can do this
View childView = ((ViewGroup)linearLayout).getChildAt(position);
Why just not do:
linearLayout.addView(randomView);
I remember it adds the view to end of the viewgroup.
I am developing an app in which I am receiving json objects in json array. Each json object contains one image and two string. Now I want to show each json object's data in HorizontalScrollView i.e. if there are 10 json objects then I have to show 10 layout(with one image and two textview) in HorizontalScrollView.
What I tried is that I created a layout with one ImageView and two TextView and inflated that layout in a view object. Now at runtime I added that view object in a LinearLayout (horizontal) which is in HorizontalScrollView to the length of json array but it's giving me an error
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Can anybody tell me solution for this.
Here is my code
Linear layout ll_hori_scroll = (ViewGroup)findViewById(R.id.ll_hori_scroll);//layout in horizontal scroll view
View v = View.inflate(_activity, R.layout.list_item_recentlyadd_home, null);//custom layout
for (int i = 0; i < 2; i++) {
ll_hori_scroll.addView(v);
}
and its give error in ll_hori_scroll.addView(v);
Scrollview will allow only one child, so you have to add child layouts to child of of ScrollView.
Like this
<ScrollView
<LinearLayout
/// you can add layout's here at dynamic
</LinearLayout>
</ScrollView>
addView must add "indepent object", you just add the same "list_item_recentlyadd_home" into ll_hori_scroll twice...
The code should be below:
Linear layout ll_hori_scroll = (ViewGroup)findViewById(R.id.ll_hori_scroll);//layout in horizontal scroll view
for (int i = 0; i < 2; i++) {
//move below line from outside into for loop
View v = View.inflate(_activity, R.layout.list_item_recentlyadd_home, null);
ll_hori_scroll.addView(v);
//if you wants to use this view later, you can add the tag for your view
v.setTag(i); // v.getTag() can get their position
}
Hope it helps you... ^^
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");
}
I'm trying to set the z order of a UI element (i.e. a View) so that it will overlap another element, but calling ViewGroup.bringChildToFront() has a weird side effect....it moves the element to be the last item in the parent (the ViewGroup). Is this a bug, expected behavior, or what? More importantly, how can I set the z order or a View without this unfortunate side effect?
This is the expected behavior. bringChildToFront() just changes the index of the View inside its parent.
To send a view all the way back, do this:
private void moveToBack(View currentView) {
ViewGroup viewGroup = ((ViewGroup) currentView.getParent());
int index = viewGroup.indexOfChild(currentView);
for(int i = 0; i<index; i++) {
viewGroup.bringChildToFront(viewGroup.getChildAt(i));
}
}
bringChildToFront(child) does nothing but changes the index value of the child.
In order to bring a child to the front without using showNext() or showprevious(),
use
setDisplayedChild() and indexOfChild() together.
example
vf.setDisplayedChild(vf.indexOfChild(child));
where child is the view that needs to be brought front.
Thanks