after using setSelection(int, false) like suggested here because i had troubles using the default setSelection(int) for initial setup it turns out that using the two param version messes up the spinner layout till the first manual selection takes place, details see image below.
Is there a way to "update" the spinner layout?
Okay i got it. I extedned the Spinner Class, added a var for saveing that this is the "first" pass and have overrwitten the onDraw method. after super.OnDraw() is called i can be sure that the layout has been drawn the first time and all data is passed to the spinner so to following requestLayout() will fix any layout errors. so i just test if this is the first onDraw with my var, if so i call requestLayout() and set the var to false. it's not the best way and maybe there is another event i could use that is run bevore the draw happens, but it's good enough for my needs.
Related
For some reason (that I can develop if you want/need) I have to redraw all the chart periodically. So, I use removeAllSeries then addSeries, plus removeAllViews then addView. It works but the problem is that addView adds the view not by simply refreshing all pixels of the tablet but with a sort of "animation" that puts firstly the View a little bit (2 or 3 pixels) shifted to the right and then it takes the right place. The consequence is that, everytime I redraw my graph, it looks as if there is a "vibration" (it's not fluid).
Do anyone have some issue? Could this undesired "animation" be related to how the addView method is done?
there are three ways:
redrawAll() method. Maybe it is protected, but you can overwrite and
make it public
change the data in series (appendData or resetData). The Graph will
automatically rerender.
removeAllSeries + add new series. No need to call
removeAllViews/addView. Take a look at the GraphViews-Demos project,
there is an example about that.
Cheers
Thank you for your answer ! I actually just simply overrided the ValueDependentColor() method directly in my main activity. The color depends on a timer. So, when I reset data after x seconds the graph rerenders as you said in your "2."
In an Activity, I am retrieving data from a server. There are a limited number of TableRows containing further Views pre defined in the layout xml file, all set to android:visibility="gone". Further there's an array in the java class with all IDs of these TableRows.
For each entering "data entry", I fill such a TableRow, set it visible and animate it (the animation is a 'push in' from a randomly choosen vertical side). As an further hint, which is important later in this question, every data packet retrieving from the server is related to a month.
Whenever I get data, I do following process
Fill the still invisible TableRows with the information
For every time step 1 is executed, a value in a boolean array is set to true
call showAnimation()
for every entry that is true in the boolean array, get TableRow at index i in the id array, set an Animation and set visibility to visible
This works fine. Even if the visibility is set before starting the Animation, it doesn't matter, since this takes so few time, that the Animation has already begun in our eyes.
Now comes the problem: the reverse way doesn't work. Let me clarify: I want, that the TableRows are pushed out of the window, and THEN set to invisible resp. gone whenever I change the actual month, and the new entries are pushed then in. The problem is, that as soon the Animation starts, the Views are set to invisible / gone. I tried to solve this with an AnimationListener like explained here in the first answer. This leads to two possible ways:
Define such an AnimationListener for each TableRow and set the visibility in the onAnimationEnd(). I find this is very ugly, since it is not dynamical.
Have access to a kind of index in the AnimationListener and set the same Listener to every TableRow's Animation. Here I don't know how possibly solve this. As I discovered earlier, setting Animations on Views set in a loop (a for loop in my case) results in the Animations beeing started when the loop has finished, and not whenever it is set. So even if I would carry a global index variable in that for loop to be used in the onAnimationEnd(), it obviously would came to nothing.
Do someone knows a better way to implement this? Solving it with a Handler.postDelayed() does not do the trick, since it is possible that the new data has already come from the server, and therefor the new entries are already visible (and thus the new ones are set to invisible).
ok I thought a lot about it and honestly I agree with you that it's not the nicest way, but due to the framework limitations the 1st way is still the best one.
It will be nice if we could from the listener call back do:
public void onAnimationEnd (Animation animation){
animation.getView().setVisibility(View.Visible);
}
// but this doesn't exist.
Just make sure every time you're setting an animation to start to do:
Animation anim = row.getAnimation()
if(anim!=null){
anim.setListener(null); // to avoid the listener to be called
anim.cancel(); // to stop it from running
}
// and then go ahead and setup a new animation with new listener
anim = new MyAnimation();
anim.setListener(new SetToInvisibleListener());
row.startAnimation(anim);
My problem is on two fronts.
First issue: Scrolling amnesia
I have a ListView with spinners and edit texts. It acquires it's data from webservice. The problem is when I write up a value on the EditText or select something for the spinners and scroll them out of view. When I come back the fields are empty and the spinners are again in their default selection.
Attempted solution
I have tried resolving the issue by setting ScrollingCacheEnabled programmatic and within the AXML file to both true and false just to see if that is an issue. It seems not to have any kind of an effect.
Second issue: Focus Loss
When I touch the EditText within this same ListView I get the keyboard to appear but I loose the focus on the field and it needs to get touched again to get focus and it allows me to be written.
Attempted solution
I fiddled with setting the fields focusable, Focusavle in toucmode, touchable and whatnot but came out empty handed.
Honestly I am quite new to android and to programming on this level as well but I tried my best on this. I might have just missed something due to lack of knowledge or it's just something somebody with more experience could tackle and solve.
The second issue isn't that bad for now (still after filling out quite a number of fields it does get tiring to set it twice...) but the scrolling issue is a must.
I think you problem relates to that you forget to update the items in the Adapters when you alter the Views containing them. So you need to wire up the events from the Views to update the items.
Why? If you look carefully at your Adapter for you ListView you populate the convertView with the values of GetItem(position). So if that item does not reflect the changes you have made to the View you are bound to get the initial values of that item.
So what you need to do is to hook up SpinnerValue.ItemSelected and all the other Views which can be altered events, so that the items in the Adapter get their values updated. Remember to only add event handlers when you first create the View. So that is when convertView is null.
Also consider changing the lines:
if (SpinnerValue.Adapter.Count.Equals(2))
{
SpinnerValue.SetSelection(1);
}
To be based on the items in the Adapter rather than setting it to 1 every time.
You focus problem is based in that ListView is not really made for having Views inside of it wanting the focus. Try setting the ListView DecendantFocusability when you instantiate it to DescendantFocusability.AfterDescendants like so:
lstPrevzem.DescendantFocusability = DescendantFocusability.AfterDescendants;
I resolved the issue by replacing the listview with LinearLayout and pinning the adapter to it. The "fixed" code is available on pastebin.
Fixed code:
http://pastebin.com/vn3SPrFz
The problem:
I have a class, inherited from LinearLayout.
This class creates some buttons in the constructor and puts them into itself using addChild().
I've overloaded method onSizeCHanged and I want to add some childs in this method.
But changes have no effect until one of the other buttons clicked.
So, I need to press some of existing buttons and after that views which I've added appear.
(by the way, only buttons with ontouchlistener do it. buttons without listener cannot make new views appeared).
How to add views in onSizeChange method to do them appeared immediately?
ADDITION:
Methods forceLayout() and requestLayout() cannot work.
I have not extended LinearLayout myself but I read up on the class a bit and I think you need to override onLayout() and add your child views in it. Check the docs and see if it helps
http://developer.android.com/reference/android/widget/LinearLayout.html#onLayout(boolean,%20int,%20int,%20int,%20int)
The solution was: making a simple boolean flag, setting it "true" im onSizeChanged and calling "invalidate".
In method "onDraw" checking if flag is true and if it is so, calling requestLayout. Then setting flag to false.
I am wanting to display a text field stating that my listview is empty if there is nothing in my list. I know this can be accomplished quite simply using an android:id/empty textview in the xml file, but this also requires that I extend my activity with something other than Activity and I don't want to do that.
I guess my only solution is to create a textview and then set its visibility to gone when my code detects that something has been added to the listview. I can simply check the array that populates the list, but is there some sort of listener so I don't have to run a checkListIsEmpty() constantly throughout the code. I was hoping I could use something that would simply sit quiet and wait for the listview to become populated and when that happened change the visibility to visible and then begin waiting for it to become empty again.
Or you can use setEmptyView(View v) on your ListView in your Activity.