AddView - Suggestion

andrewmp

Member
Licensed User
Longtime User
It would be nice if AddView returned the index of the object just added

Thanks
 

Roger Garstang

Well-Known Member
Licensed User
Longtime User
In all my classes and libraries I've been making lately I give names to the views and store them in a map. This allows for easy state management either from a Map or From a Database Cursor if the names of the views equal the names of the columns in the Cursor.

An array of numbers may be more efficient, but then all you have is order and you have to have your state management in order too only gaining order/"tab order" to use in Next/Previous (Along with having no clue what a view is other than a number). There is still a call needed to get the actual view too. If all you want is order then an array of Views instead of numbers would be best. The Views exist in memory no matter what, so your array would just point to them and not take up any additional space like an array of numbers would. You also gain not having to call another function to get your view since you already have it.
 

Informatix

Expert
Licensed User
Longtime User
Having AddView return the View would be cool too. I also do this in my libraries so it is easy to grab it right at creation. It also allows for extended dot notation inline like:

Activity.AddView(MyView, 0, 0, Activity.Width, Activity.Height).Color= Colors.Black

AddView places a view in the viewgroup hierarchy (thus it becomes a "child" of the parent view). Why should it return anything else than the view position in the hierarchy? As Vader said, returning a view makes sense only when the view is unknown or not initialized before the function is called.
And even in the case where the function returns the position, I disagree with the idea for the following reasons:
1) the AddView function in Java does not return the index, so you have to call indexOfChild to know it. This method is slow because it goes down the children tree to find the given child. How many people need the result? Is it worth the call to a slow method? Isn't it better to call indexOfChild when you really need it (with the reflector lib)?
2) You add a slow method (AddView) to another slow method (indexOfChild). When you need to create quickly a large number of views, that turns to a snails race. If you ever tried to create a listview based on a scrollview, you probably know what I mean.

To ease the thing for beginners, I think that a good idea would be to add the following functions: getParent and indexOfChild. No?
 

Roger Garstang

Well-Known Member
Licensed User
Longtime User
Ok...I guess I was thinking about my library too much this week. For B4A's AddView you pass a view, so no need to return it. I think it would be possible to have it return the Index in AddView too though without a speed hit.

1. ViewGroup has an AddView that you can specify an Index with. Not much is mentioned on it as to how Index values work though. I'd assume Base 0. For the rest it may require a simple test as to what value is needed to add to the end or the beginning. I'd guess when you insert to 0 it bumps the old 0 to 1. So, with say 2 elements in the list you'd have 0 and 1 and probably have to insert to 2 to add to the end. I'd be curious as to what happens if you try adding to Index 6 with those same 2 elements or maybe what inserting to -1 does.

2. Within B4A #1 above would be fine, but if someone uses a libaray or some other method of adding a view it may through off the index count. Since it is possible to use AddView with an Index it would also mess up the code Erel posted above. With a combination of setOnHierarchyChangeListener and maybe something overriding the AddView methods so they always add in an expected way then you could keep things in order.

One big complaint I've always had though is even when you get this index, what good is it? How is it different than just storing an array of "pointers" to your Views. If all this is added to B4A it would really need some additions to what some would call "Tab Order" for Next and Previous buttons in the keyboard and an easier way to get to the views without a performance hit. Some type of index so it doesn't have to scan the whole tree. If all you have is an array of integers all you did is make a copy of what the ViewGroup already stores.
 

Roger Garstang

Well-Known Member
Licensed User
Longtime User
So, we are still back to "what good is it?" then. Whether it returns it or you get it yourself it can become useless by two additional method calls you mentioned now, so your grabbed index would be invalid. Doesn't matter if B4A keeps track of it or the developer does. It still comes back to needing to track it by another means since the index can change. This is why I prefer keeping track of the actual views. I store names to them that mean something in a map too (And can be used for State Management). I also just posted the source for my Line Layout library yesterday, so anyone can make their own library to keep track of controls any way they want.
 

Informatix

Expert
Licensed User
Longtime User
So, we are still back to "what good is it?" then. Whether it returns it or you get it yourself it can become useless by two additional method calls you mentioned now, so your grabbed index would be invalid. Doesn't matter if B4A keeps track of it or the developer does. It still comes back to needing to track it by another means since the index can change. This is why I prefer keeping track of the actual views. I store names to them that mean something in a map too (And can be used for State Management). I also just posted the source for my Line Layout library yesterday, so anyone can make their own library to keep track of controls any way they want.

I don't understand. When you need to know the Z order of a view (its position in the tree), you call indexOfChild and the returned value is exact. It may change later but who cares? It's now that you are going to use it. Just after the call to the function, not in five minutes. If you want to store this value for a later use, it's a bad idea of course because the Z order can change. But why would you want to store this position if you know the view reference? What use can you have of such an index? If it's just to manage a tab order, a call to indexOfChild will be enough. You don't need something fast.

Example of use:
B4X:
Dim r As Reflector
r.Target = myParentView
Dim Index As Int = r.RunMethod4("indexOfChild", Array As  Object(myChildView), Array As String("android.view.View"))
 
Top