I have a view which I get from the parent ViewGroup:
mActiveCard = getChildAt(LAST_OBJECT_IN_STACK);
I later what to check if mActiveCard equals to another view:
anotherCard = getChildAt(x);
A naive approach would have been to check if x== LAST_OBJECT_IN_STACK however there might be many changes in the ViewGroup e.g. removed objects. So the positions are relative.
Also I can save the object for later but that will consume some more memory, like:
mActiveCard.equals( getChildAt(LAST_OBJECT_IN_STACK) )
One idea is to setId() of the view or setTag(). So if I have a unique String/int then I could later get the id or the tag. So saving just the id/tag would require less memory, right?
First of all is my theory correct? Also, does Android SDK offer a way to identify tags and what can be an good id/tag to generate and set on that view?
If you are truly holding onto a reference to a View (mActiveCard) that you know is also in the child list, you can simply compare their references.
if (mActiveCard == getChildAt(x))
{
// ...
}
Related
private fun turnOnAllItems() {
items.forEachIndexed { index, item ->
val viewHolder = recyclerView.findViewHolderForAdapterPosition(index)
as SwitchableItemViewHolder
viewHolder.switchButton.isChecked = false
}
}
What this does, is it also changes list items object values isEnabled to false. Looks weird to me, as I actually change viewHolder attribute. Why is this happening? How to avoid this?
I strongly believe that you are doing it the wrong way. RecyclerView is meant to display already modified data, meaning that you have a set of it.
Let's say, 10 tables in restaurant, and at some point table #4 becomes available for new customer and you want to indicate that.
A good approach would be to modify your list of tables somewhere outside RCV, even fragment or activity will do, and then just graphically update (all or just one) item by means of RCV.
Here's a little article I made to illustrate how to properly use RecyclerView, hope it will help you
I want to bind some information by attaching tags to a view. So when the view is clicked I can retrieve this information with its tag. However, I meet problem when using an int array as the tag.
I save two integers by following samples:
int arr=[x,y];
view.setTag(arr);
parentView.addView(view);//parentView is a list/LinearLayout of such views
Later, when I want to find the view using
int tmp=[i, j];//i=x, j=y in values
View target=parentView.findViewWithTag(tmp);
The returned target is null. Why does it not return the correct view?
Edit:
I'm not sure if it's because of object reference and comparison issue. I tried to combine integers x and y into a string like "x,y", and search the view like parentView.findViewWithTag("x,y") and it can find the view.
Although didn't do verification experiments, a guess is mentioned by #CommonsWare. And real objects should solve the problem.
i would like to ask a lot of questions about how this whole id system works in android. I looked up the View documentation, but the description was too shallow for my taste.
Is there a pattern, how the IDE (Eclipse/Netbeans) generates the ids
when i use android:id="#+id/..."? Or is it completely random?
If i set ids programmatically, then will it be found by the Context
classes findViewById() function?
If the answer for the previous question is yes, then if i want to
create a large amount of Views, but i want them to have distinct ids
for later identification, then wich one is better to use? (To answer
this question, it would be really useful to know the answer for the
first two)
For example generating random ids in the largest possible range:
Random random = new Random();
for(int i=0; i<100; i++)
{
View view = new View(someContext);
view.setId(random.nextInt(Integer.MAX_VALUE));
}
Or setting the ids in some sort of order, for example:
final int addToId = 5670;
for(int i=0; i<100; i++)
{
View view = new View(someContext);
view.setId(i+addToId);
}
Also i would like to know, what happens, when you use a
LayoutInflater for example to populate a ListView using a
pre-defined xml layout for every item in the list. Then you get your
sub-views in the getView() function by the findViewById(). So i
assume, that all the identical Views across your listitems have the
same id. If so, then is it a good practice to use the tag
attribute to distinguish the items in an inflated layout?
Any clear explanation for these question would be highly appreciated!
#+id/.... creates an id value that lives within the applications namespace. Contrast this with #android:id/.... which lives in the android namespace.
When you set the id in code and add the view element to the layout it will then become available to access through the code. You won't be able to reference it from the xml
Not sure you want to be using random to generate your ids? think sequential would be better but even then what is the point of a random id? How do you know which view you are referring to?
Definitely use the tag option and look to use the ViewHolder pattern for smoother list scrolling. You could add the id to the view holder class if you need access to it but it would be available anyway through the data set being used to populate the list. A quick search will give you plenty of examples for this.
I have a custom activitygroup that adds and removes views to the stack.
I override the dispatchKeyEvent to check for certain keys pressed.
the problem is that I need to check the type of the current focused view like this:
View v=getCurrentFocus();
when I check for the type of the view,
it returns a type like this
com.android.internal.policy.impl.PhoneWindow$DecorView
what is this type and can I cast any class object to this type ?
thanks
No you can't just cast any class object to this type! Best practice is that you should only ever cast up the class hierarchy, or if you really must cast down make sure you check the type first using the instanceof operator.
Also, judging by the package name it's an internal android class, so you do not want any references to that in your code - if it's internal, it's non api. They could change it at any point and your app would immediately be broken.
Why are you checking the type of the view?
Are you looking for a particular type?
If so, it's be safer to do (for example):
View v = getCurrentFocus();
if(v instanceof SomeView){
//do stuff
}
Or if it is the decor view you are interested in use getDecorView instead of getCurrentFocus .
How to get the dirty(changed) properties(any controls subclasses of view) amongst a number of properties on a layout. Does android has a dirty flag to mark if the layout has any field that has a changed content??
Actually, i have a layout that has a few edittexts,spinners,datewidgets.Now doing a save should make request to the server only if the user has modified anything .I wanted to know that how can i check if the user has changed anything in that layout or not.Does android has any flag or something that sets itself when the user modifies any input control?
Hmm..Blckberry Does have isDirty(){boolean net.rim.device.api.ui.Manager.isDirty()}method.
The activity is not tightly coupled to the elements in your layout, so you'll have to do this yourself. You could maintain a Map where the key is the id of the layout element, and the value is a boolean that signals if the element has been modified by the user. You would probably need to set up listeners on each element (such as OnKeyListener for your EditTexts) and additionally capture their initial values.
Does android has a dirty flag to mark
if the layout has any field that has a
changed content??
No, sorry.
Bit late with my answer, but the way I do it is to store the form (activity) fields in a container object (for validation, etc). This container object implements the
java.lang.Comparable interface, where T is the same class as the container.
The compareTo(T) method then returns
0 if both objects are equal (thereby form contents haven't changed).
-1 indicates that something has changed and therefore the data is dirty
You can always return other numeric values to indicate what exactly has changed if required.