Fixed
Status Update
Comments
op...@gmail.com <op...@gmail.com> #2
Another workaround, getting the ActionBar size at run-time:
TypedValue typed_value = new TypedValue();
getTheme().resolveAttribute(android.support.v7.appcompat.R.attr.actionBarSize, typed_value, true);
swipe_refresh_layout.setProgressViewOffset(false, 0, getResources().getDimensionPixelSize(typed_value.resourceId));
TypedValue typed_value = new TypedValue();
getTheme().resolveAttribute(android.support.v7.appcompat.R.attr.actionBarSize, typed_value, true);
swipe_refresh_layout.setProgressViewOffset(false, 0, getResources().getDimensionPixelSize(typed_value.resourceId));
jo...@gmail.com <jo...@gmail.com> #3
I am experiencing this too...
[Deleted User] <[Deleted User]> #4
Another workaround might help
handler.postDelayed(new Runnable() {
@Override
public void run() {
initiateRefresh();
}
}, 1000);
handler.postDelayed(new Runnable() {
@Override
public void run() {
initiateRefresh();
}
}, 1000);
[Deleted User] <[Deleted User]> #5
same problem here.
th...@gmail.com <th...@gmail.com> #6
Same issue here. I am calling an AsyncTask (that calls setRefreshing) from onResume.
pa...@gmail.com <pa...@gmail.com> #7
Same here. android.support.v4 v 21.0.0
[Deleted User] <[Deleted User]> #8
Problem still exists with android.support.v4:21.0.3.
ma...@mobconverge.com <ma...@mobconverge.com> #9
[Comment deleted]
ma...@mobconverge.com <ma...@mobconverge.com> #10
[Comment deleted]
ma...@mobconverge.com <ma...@mobconverge.com> #11
FWIW: a workaround that seems to work (even without the delay):
final boolean refreshing = true;
swipeToRefreshLayout.post(new Runnable() {
@Override public void run() {
swipeToRefreshLayout.setRefreshing(refreshing);
}
});
final boolean refreshing = true;
swipeToRefreshLayout.post(new Runnable() {
@Override public void run() {
swipeToRefreshLayout.setRefreshing(refreshing);
}
});
jc...@gmail.com <jc...@gmail.com> #12
[Comment deleted]
jc...@gmail.com <jc...@gmail.com> #13
[Comment deleted]
jc...@gmail.com <jc...@gmail.com> #14
The same problem.
as...@dismoiou.fr <as...@dismoiou.fr> #15
The post() workaround works when loading programmatically, but the gesture down is still broken.
jc...@gmail.com <jc...@gmail.com> #16
It seems the gesture doesn't work if the view doesn't have a ScrollView widget in its hierarchy.
ni...@gmail.com <ni...@gmail.com> #17
My solution is to override SwipeRefreshLayout
private boolean mMeasured = false;
private boolean mPreMeasureRefreshing = false;
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (!mMeasured) {
mMeasured = true;
setRefreshing(mPreMeasureRefreshing);
}
}
@Override
public void setRefreshing(boolean refreshing) {
if (mMeasured) {
super.setRefreshing(refreshing);
} else {
mPreMeasureRefreshing = refreshing;
}
}
private boolean mMeasured = false;
private boolean mPreMeasureRefreshing = false;
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (!mMeasured) {
mMeasured = true;
setRefreshing(mPreMeasureRefreshing);
}
}
@Override
public void setRefreshing(boolean refreshing) {
if (mMeasured) {
super.setRefreshing(refreshing);
} else {
mPreMeasureRefreshing = refreshing;
}
}
[Deleted User] <[Deleted User]> #18
Still broken, v22.2.0
ne...@gmail.com <ne...@gmail.com> #19
Fix this already!
te...@gmail.com <te...@gmail.com> #20
Please, fix this issue.
mw...@gmail.com <mw...@gmail.com> #21
Still exists with 22.2.1
[Deleted User] <[Deleted User]> #22
Still an issue with 23.0.0
ed...@gmail.com <ed...@gmail.com> #23
Still broken in 23.0.1
iv...@gmail.com <iv...@gmail.com> #24
I don't think this is broken in Google's eyes.
"The refresh indicator appears only in conjunction with a refresh gesture or action. Syncing does not display a refresh indicator."
http://www.google.com/design/spec/patterns/swipe-to-refresh.html#swipe-to-refresh-swipe-to-refresh
"The refresh indicator appears only in conjunction with a refresh gesture or action. Syncing does not display a refresh indicator."
pa...@gmail.com <pa...@gmail.com> #25
Note that this almost year old bug has not been triaged yet, meaning they didn't see it, or choose to ignore.
I couldn't find any recommended way to display initial loading. Empty view is for empty list, having a separate loading indicator and a swipe-to-refresh indicator is problematic to code and may confuse the user. In Google's world everything shows up immediately.
Note that even the GMail app shows two indicators sometimes. In the morning when I turn WiFi on, it starts syncing, but it takes a while, and if in the middle of that I swipe to refresh it shows me two spinners, going in opposite directions.
I couldn't find any recommended way to display initial loading. Empty view is for empty list, having a separate loading indicator and a swipe-to-refresh indicator is problematic to code and may confuse the user. In Google's world everything shows up immediately.
Note that even the GMail app shows two indicators sometimes. In the morning when I turn WiFi on, it starts syncing, but it takes a while, and if in the middle of that I swipe to refresh it shows me two spinners, going in opposite directions.
al...@gmail.com <al...@gmail.com> #26
Why hasn't this been fixed already??
am...@google.com <am...@google.com> #27
[Comment deleted]
az...@gmail.com <az...@gmail.com> #28
What google is doing ??????
Still not fixed
Still not fixed
[Deleted User] <[Deleted User]> #29
Still broken in 23.0.1
jh...@gmail.com <jh...@gmail.com> #30
Still not fixed in 23.1.0 !!!!!
[Deleted User] <[Deleted User]> #31
I agree with papp.robert.s. Although this is a bug, it's probably bad UX to set it programmatically anyways. Might as well not set it. So there's not really much to gain by fixing this bug, except for correctness.
I propose removing setRefreshing(boolean) entirely, or deprecating it.
I propose removing setRefreshing(boolean) entirely, or deprecating it.
[Deleted User] <[Deleted User]> #32
At least Google's "News and Weather" app uses the setRefreshing() function. However, it's after pressing "YES" on the "Stay in the know?" banner that appears on first launch, so it's unaffected by this bug.
Anyways, it probably shouldn't be deprecated, because apps are already using it.
Anyways, it probably shouldn't be deprecated, because apps are already using it.
pa...@gmail.com <pa...@gmail.com> #33
bhender..., don't get me wrong: I support the swipe to refresh indicator, and I think it's good to use it for loading indicator is well. That way there's only one spinner, it's nice and it prevents refreshing mid-update, because it already showing the indicator which disables the down-swipe. The problem is that this indicator is hard to use because we have to post() it for no apparent reason.
ra...@gmail.com <ra...@gmail.com> #34
Workaround posted by #16 (niks.m...@gmail.com) is on the right track. The caveat there is that the vertical offset will be incorrect.
A more robust workaround would be to use a Global Layout Listener to ensure that the view is properly placed in the hierarchy and sized appropriately, something like this:
private class OnLayoutReadyListener implements OnGlobalLayoutListener {
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
if (!mLayoutReady) {
mLayoutReady = true;
setRefreshing(mPreLayoutReadyRefreshing);
}
}
}
Hope this helps.
A more robust workaround would be to use a Global Layout Listener to ensure that the view is properly placed in the hierarchy and sized appropriately, something like this:
private class OnLayoutReadyListener implements OnGlobalLayoutListener {
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
if (!mLayoutReady) {
mLayoutReady = true;
setRefreshing(mPreLayoutReadyRefreshing);
}
}
}
Hope this helps.
ad...@gmail.com <ad...@gmail.com> #35
[Comment deleted]
ad...@gmail.com <ad...@gmail.com> #36
[Comment deleted]
ad...@gmail.com <ad...@gmail.com> #37
This is a bug, not a feature for preventing bad UX.
I want to keep the spinner on after activity recreation or programatically start it on the first startup.
It is bad UX to have two different loading spinners, one for the gesture and one for initial load/activity recreation.
I want to keep the spinner on after activity recreation or programatically start it on the first startup.
It is bad UX to have two different loading spinners, one for the gesture and one for initial load/activity recreation.
lb...@gmail.com <lb...@gmail.com> #38
@33 I think your first condition is not needed: both do the same. :)
ca...@gmail.com <ca...@gmail.com> #39
Still not working....
pa...@gmail.com <pa...@gmail.com> #40
Stop saying it's not working, no-one from Google or AOSP looked at this. Notice the status: New; somehow we need to make them notice this and triage it. I thought near 200 stars would be enough...
am...@google.com <am...@google.com> #41
Hi,
We have passed this defect on to the development team and will update this issue with more information as it becomes available.
Thanks
We have passed this defect on to the development team and will update this issue with more information as it becomes available.
Thanks
ro...@gmail.com <ro...@gmail.com> #42
Is this fixed @ version 22.3 ?
pa...@gmail.com <pa...@gmail.com> #43
I don't think so, see #29 and the fact that this issue is not in Fixed/Released state.
nk...@gmail.com <nk...@gmail.com> #44
Still not fixed in 23.2.1 :(
to...@gmail.com <to...@gmail.com> #45
For me it works properly only if it has only one child view and it's a scrollable view, for example a ScrollView. I guess it's because SwipeRefreshLayout needs to listen the childview's onScroll event, and the other views don't call it.
Here's my fragment's layout xml, how it works for me.
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android "
xmlns:app="http://schemas.android.com/apk/res-auto "
xmlns:tools="http://schemas.android.com/tools "
android:id="@+id/pull_to_refresh"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#567123">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textColor="@android:color/black"/>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
I hope I could help.
Here's my fragment's layout xml, how it works for me.
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="
xmlns:app="
xmlns:tools="
android:id="@+id/pull_to_refresh"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#567123">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textColor="@android:color/black"/>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
I hope I could help.
lb...@gmail.com <lb...@gmail.com> #46
@45 Sure it works well with ScrollView? Have you tried it on old Android versions too (2.3, 4.0,... for example) ?
au...@google.com <au...@google.com> #47
As a workaround for now use OnLayoutChangeListener and call setRefreshing there. The fix will come in the release after 24.0 release.
al...@android.com <al...@android.com> #48
Released in v24.0.0.
ch...@gmail.com <ch...@gmail.com> #49
this is not fixed in v24.0.0
lb...@gmail.com <lb...@gmail.com> #50
@52 can you please post sample project to test it out?
ch...@gmail.com <ch...@gmail.com> #51
@53 Just created this simple project. This bug still exists on every device that I've tested on (my Nexus 6P on API 23, a Galaxy Nexus emulator on API 17, and a Nexus 4 emulator on API 21) https://github.com/charlesmadere/RefreshApplication
[Deleted User] <[Deleted User]> #52
for me it's not working too in v24.0.0
[Deleted User] <[Deleted User]> #53
I also confirm, it is not working in v24.0.0
au...@google.com <au...@google.com> #54
You guys are right. Turns out I could not merge it to 24.0.0. The fix will come in 24.1.0. Sorry about getting everyone excited :(
ja...@gmail.com <ja...@gmail.com> #55
When is 24.1.0 coming? Please asap!
au...@google.com <au...@google.com> #56
As I mentioned in #47 you can OnLayoutChangeListener as a workaround until 24.1.0 ships.
lb...@gmail.com <lb...@gmail.com> #57
@59 can you please show code for this?
ch...@gmail.com <ch...@gmail.com> #58
I cant figure out how to implement it using OnLayoutChangeListener. Can you please show sample code for this?
au...@google.com <au...@google.com> #59
Let me know if this works:
final SwipeRefreshLayout srl = (SwipeRefreshLayout) findViewById(R.id.srl);
srl.addOnLayoutChangeListener(
new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
srl.removeOnLayoutChangeListener(this);
srl.setRefreshing(true);
}
});
final SwipeRefreshLayout srl = (SwipeRefreshLayout) findViewById(R.id.srl);
srl.addOnLayoutChangeListener(
new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
srl.removeOnLayoutChangeListener(this);
srl.setRefreshing(true);
}
});
ch...@gmail.com <ch...@gmail.com> #60
It does the job to starting refresh animation but setrefreshing to false when my task is complete doesnt disable it. I guess using it inside runnable is only workaround as of now
do...@gmail.com <do...@gmail.com> #61
The #16 did the thing for me. It is easier to do and it won't add additional logic to your code.
Just create a new class which inherit from SwipeRefreshLayout and add the following code. Use it in your layout files (com.example.view.CustomSwipeRefreshLayout for example) but reference it in your code like the classic SwipeRefreshLayout.
When the new lib version is out, just replace all occurrences of your custom class in your project by the original one.
private boolean mMeasured = false;
private boolean mPreMeasureRefreshing = false;
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (!mMeasured) {
mMeasured = true;
setRefreshing(mPreMeasureRefreshing);
}
}
@Override
public void setRefreshing(boolean refreshing) {
if (mMeasured) {
super.setRefreshing(refreshing);
} else {
mPreMeasureRefreshing = refreshing;
}
}
Just create a new class which inherit from SwipeRefreshLayout and add the following code. Use it in your layout files (com.example.view.CustomSwipeRefreshLayout for example) but reference it in your code like the classic SwipeRefreshLayout.
When the new lib version is out, just replace all occurrences of your custom class in your project by the original one.
private boolean mMeasured = false;
private boolean mPreMeasureRefreshing = false;
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (!mMeasured) {
mMeasured = true;
setRefreshing(mPreMeasureRefreshing);
}
}
@Override
public void setRefreshing(boolean refreshing) {
if (mMeasured) {
super.setRefreshing(refreshing);
} else {
mPreMeasureRefreshing = refreshing;
}
}
au...@google.com <au...@google.com> #62
Due to internal changes this will actually ship in 24.2.0. Sorry about the continuous delay :(
tu...@gmail.com <tu...@gmail.com> #64
Does "Released in 24.2.0" mean "fixed in 24.2.0"?
al...@gmail.com <al...@gmail.com> #65
It's fixed in 24.2.0, many thanks
tu...@gmail.com <tu...@gmail.com> #66
Yes, it's fixed. Thanks.
vl...@trimexa.de <vl...@trimexa.de> #67
[Comment deleted]
vl...@gmail.com <vl...@gmail.com> #68
It seems to be only partly fixed. I call setRefreshing(true) in fragment onResume() and the indicator's white circle background does show, but not the indicator itself.
au...@google.com <au...@google.com> #69
Re #72: Can you share an example project with this issue? In my testing I did not see this issue.
[Deleted User] <[Deleted User]> #70
Not fixed for me. If i setting refreshing `true` on fragment creation. Use it with data bindings
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
bind:refreshing="@{showLoader}">...<...>
where showLoader is observableBoolean, setted in binding class in onViewCreated method.
Fragment appears with animation if it is important.
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
bind:refreshing="@{showLoader}">...<...>
where showLoader is observableBoolean, setted in binding class in onViewCreated method.
Fragment appears with animation if it is important.
ni...@gmail.com <ni...@gmail.com> #71
Same problem as #72 described
ni...@gmail.com <ni...@gmail.com> #72
Re #73 It happens if SwipeRefreshLayout is a root of a fragment layout; So if i put it inside FrameLayout, everything is ok.
he...@gmail.com <he...@gmail.com> #73
Hi, i face this issue when i pull it slowly and then push it back up so that it doesnt perform a pull to refresh. So, it shows the white circle but not the arrow inside it, however if i drag it along to some distance it shows the arrow. Is there a workaround to this to make it to show the arrow even when i pull it just some short distance? Again, after it is pulled the first time, it manages to show the arrow when i pull it a shorter distance the second time, so the issue is just in the first pull.
su...@gmail.com <su...@gmail.com> #74
@ comment#77
If you can make a video of what you're doing, it will help other (and dev team) to reproduce this bug easily.
Android Studio allows you to capture video from the connected device/AVD.
If you can make a video of what you're doing, it will help other (and dev team) to reproduce this bug easily.
Android Studio allows you to capture video from the connected device/AVD.
pa...@gmail.com <pa...@gmail.com> #75
#77/#78 see also https://developer.android.com/studio/command-line/adb.html#screenrecord , it works on production devices too, if you have USB debugging enabled.
I think a fully working/easy to compile demo project would also be helpful to gather attention from the dev team.
I think a fully working/easy to compile demo project would also be helpful to gather attention from the dev team.
he...@gmail.com <he...@gmail.com> #76
i tried capturing screenshots to get the same effect, so the idea is to drag for the pull to refresh and you see just a white progress bar with no indicator, if you drag further down you see the indicator. I tried video capturing but studio records a blank video.
Description
SwipeRefreshLayout indicator does not appear when the `setRefreshing(true)` is called before the `SwipeRefreshLayout#onMeasure()`.
Sample:
{{{
public class MainActivity extends Activity implements SwipeRefreshLayout.OnRefreshListener {
private SwipeRefreshLayout mSwipeRefreshLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiperefresh);
mSwipeRefreshLayout.setOnRefreshListener(this);
// Indicator will not appear
mSwipeRefreshLayout.setRefreshing(true);
stopRefreshingDelayed();
}
@Override
public void onRefresh() {
stopRefreshingDelayed();
}
void stopRefreshingDelayed() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(false);
}
}, 10000);
}
}
}}}
Workaround:
{{{
mSwipeRefreshLayout.setProgressViewOffset(false, 0,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources().getDisplayMetrics()));
}}}