I'm aware that calling myRefreshLayout.setRefreshing(false) will end the refresh animation... BUT, it doesn't just stop, it finishes it's current spin and animates off-screen.
Is there a way to avoid that in certain instances? I'm looking to just have it instantly disappear.
Thanks!
Try this out:
int cnt = swiperefresh.getChildCount();
for(int i=0; i<cnt; i++) {
View ch = swiperefresh.getChildAt(i);
if(ch.getClass().getSimpleName().equals("CircleImageView")) {
ch.clearAnimation();
ch.setVisibility(View.GONE);
swiperefresh.setRefreshing(false);
ch.clearAnimation();
break;
}
}
I found an elegant way. There is a reset() method in SwipeRefreshLayout which cancels the animation and immediately hides the progress drawable without animation. Unfortunately this method is package private. But it is called during setEnabled(false), so you could use it like this:
swipeRefreshLayout.setEnabled(false)
swipeRefreshLayout.setEnabled(true)
Related
I basically have to smooth scroll a listview and update a row at the same time.
I do it with a simple approach for now:
mListViewWeeks.post(new Runnable() {
#Override
public void run() {
// update the row concerned
updateItemAtPosition(rowIndex);
int duration = 200;
mListView.smoothScrollToPositionFromTop(rowIndex, 0, duration);
}
});
with the updateItemAtPosition() function:
private void updateItemAtPosition(int position) {
int visiblePosition = mListView.getFirstVisiblePosition();
View view = mListView.getChildAt(position - visiblePosition);
mListView.getAdapter().getView(position, view, mListView);
}
It's working well at a reasonable scroll speed, but when going faster (calling the first block above at a high rate) it can get a bit laggy. Is there anything that I can do to improve updating a row while scrolling smoothly?
You should'nt acces the iew dirrectly like this. Instead you should update your model object displayed by the list and call notifyDataSetChanged() in your adapter.
Well, I'm really late in the game. It looks like one of the reason why RecyclerView was introduced. I'm gonna try to use this component from now on.
A combination of layoutManager.scrollToPosition(position);
and adapter.notifyItemChanged(position); does the job. Everything runs smoothly!!
I'm having a problem with Robotium where waitForActivity completes when an activity is loaded, but the views on it are not yet accessible. For example:
solo.clickOnButton("Go");
assertTrue(solo.waitForActivity("ActivityTest", 5000));
Activity a = solo.getCurrentActivity(); // This works - a is "ActivityTest"
ArrayList<View> v = solo.getViews(); // This doesn't work - v is empty
The issue seems to be that the activity hasn't completely loaded; a sleep delay works around the problem:
solo.clickOnButton("Go");
assertTrue(solo.waitForActivity("ActivityTest", 5000));
Activity a = solo.getCurrentActivity(); // This works - a is "ActivityTest"
solo.sleep(5000);
ArrayList<View> v = solo.getViews(); // This works - v has lots of views
Is this just a fact of life with Robotium or am I doing this wrong?
edit: This is what I am now using in place of solo.waitForActivity:
public Boolean waitForActivity(String name) {
int timeout = 10 * 1000;
long start = Calendar.getInstance().getTimeInMillis();
assertTrue(solo.waitForActivity(name, timeout));
solo.assertCurrentActivity(name, name);
ArrayList<View> views = solo.getViews();
while (views.isEmpty()) {
solo.sleep(1000);
views = solo.getViews();
if (Calendar.getInstance().getTimeInMillis() > start + timeout)
return false;
}
return true;
}
It's normal. Activity has changed, but views are not fully loaded yet. Workaround with solo.sleep is good, if it doesn't matter for you how long the test lasts.
There are a few another solutions, you can use. That really depends on, what you are trying to achieve. If you are going to do something on specified view, you can easily use solo.waitForView. If you are going to do something on collection of views I can suggest you to use solo.waitForCondition, however you have to make some implementation of that condition.
I have been working on a ListViewidea where it keeps scrolling automatically with no user interaction and that is absolutely doable using the android APIs for instance smoothScrollToPositionFromTop.
I have implemented ListView BaseAdapter where it load items forever (almost) to get a non stopping self repeated ListView.
What I want to achieve here is to keep myListViewscrolling forever with certain speed (slow) to make items clear and readable while scrolling down, I not sure yet if ListView is my best choice here.
below is a snippet of what I am trying to do. the result is good somehow but it's not smooth enough, I can feel the ListView flickers.
I need to improve smoothness, efficiency and control the speed
new Thread(new Runnable() {
#Override
public void run() {
int listViewSize = mListView.getAdapter().getCount();
for (int index = 0; index < listViewSize ; index++) {
mListView.smoothScrollToPositionFromTop(mListViewA.getLastVisiblePosition() + 100, 0, 6000);
try {
// it helps scrolling to stay smooth as possible (by experiment)
Thread.sleep(60);
} catch (InterruptedException e) {
}
}
}
}).start();
I suggest, thath your adapter implemented in effective way.
so this code is just scrolls listview
you need to try another values of variables
final long totalScrollTime = Long.MAX_VALUE; //total scroll time. I think that 300 000 000 years is close enouth to infinity. if not enought you can restart timer in onFinish()
final int scrollPeriod = 20; // every 20 ms scoll will happened. smaller values for smoother
final int heightToScroll = 20; // will be scrolled to 20 px every time. smaller values for smoother scrolling
listView.post(new Runnable() {
#Override
public void run() {
new CountDownTimer(totalScrollTime, scrollPeriod ) {
public void onTick(long millisUntilFinished) {
listView.scrollBy(0, heightToScroll);
}
public void onFinish() {
//you can add code for restarting timer here
}
}.start();
}
});
Here a few pointers : Simulate onFling() programmatically instead of detecting it (Android)
and Programmatically Fling ListView Android
It's hard to figure out what you call smooth enough in your case. Usually smoothness problems are related to a non optimal usage of listviews and troubles in either cell layouts or view creation / recycling inside the getView method of adapters.
Do you use a placeholder ?
An important thing to consider is also Drawables usage.
I never achieved what you are looking for, but a simple idea that comes to mind is :
find a way to scroll the view of 1 position or 2.
use a ring buffer inside your adapter. For instance let's say you got 100 items in your list of items. Then at the beginning, item 0 of the listview is item 0 of your list. When listview is scrolled up of 1 item, then item 0 of listview should become item 1 in your list. Thus the problem would not be scrolling but more syncing with scrolling and displaying an endless list of items.
ImageView something = (ImageView)findViewById(R.id.my_animated_image_view);
something.setVisibility(View.INVISIBLE);
((AnimationDrawable)something.getDrawable()).stop(); // <-- Is this line redundant?
In my case, i have a bunch of animations of which only one runs/is visible, and right now I'm calling setVisibility() and stop() on all of them. Might get faster if i don't need to call stop() on my own?
From AnimationDrawable source:
#Override
public boolean setVisible(boolean visible, boolean restart) {
boolean changed = super.setVisible(visible, restart);
if (visible) {
if (changed || restart) {
setFrame(0, true, true);
}
} else {
unscheduleSelf(this);
}
return changed;
}
So if you apply setVisible(false,false) to the AnimationDrawable then the animation will stop. But not when you apply it to the View. If you want the animation to go smooth then try AnimationDrawable.setVisible(false,false) and if you want your view Invisible don't make it invisible cause a lot of UI stuff happens then. Try setting an Alpha animation ,make it transparent and setFillAfter(true). When the animations end call view to setVisibility(View.Invisible) where is needed. This probably with give you some FPS. But generally consider overall what UI stuff happen when you animate. Avoid GC calls and view invalidations
I have a Gallery widget set up to auto advance every 10000ms. However the transition between views is instantaneous and I would prefer to have a transition.
My advancing method is like so:
private void tickerAdvance() {
int selectedItemPosition = mTickerGallery.getSelectedItemPosition();
if (selectedItemPosition + 1 == mTickerGallery.getCount()) {
mTickerGallery.setSelection(0, true);
} else {
mTickerGallery.setSelection(selectedItemPosition + 1, true);
}
}
I was under the impression that setting the animation to true would cause it to animate between states. In my XML I've also added animationDuration="500", however the transition still pops between states instantly.
The problem is because you have used the setSelection() which obviously won't give you the feel of an Gallery being scrolled. SO instead of using setSelection() you have to override the onScroll() of gallery.
Here is how you do it.
Assuming that you have made the necessary steps for auto advancing periodically, now do this code.
MotionEvent e1, e2;
gallery.onScroll(e1, e2, scroll_limit , 0); //scroll limit is your integer variable for scroll limit.
The answer I came up with is that the Gallery API is terribly non-extensible. There are multiple package private or private methods that would unlock this functionality without a kludge including moveNext, FlingRunnable.startwithdistance, and scrollToChild. Alas, they are all unavailable.
Instead the best answer I was able to come up with was to override setSelection to get all the behaviors I needed. In the setSelection method I reverse the deceleration algorithm to calculate a velocity for a calculated distance and then call onFling. This is a nasty kludge could be made a ton better by making any of the above methods protected or public (I can't fathom a reason why at least moveNext and scrollToChild shouldn't be).
i had a similar task to make item to item animation and i decided to choose gallery, so i tried a lot of things, but the best way is to subclass gallery and add this:
boolean avoidSound = false;
public void showNext() {
avoidSound = true;
this.onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, null);
}
public void playSoundEffect(int soundConstant) {
if (avoidSound) {
avoidSound = false;
} else {
super.playSoundEffect(soundConstant);
}
}
just call showNext() and it will do an animation