J'ai une mise en page très simple mais quand j'appelle setRefreshing(true)
dans onActivityCreated()
de mon fragment, il ne s'affiche pas initialement.
Il ne montre que lorsque je fais un pull pour actualiser. Des idées pourquoi il ne se présente pas initialement?
Fragment xml:
<Android.support.v4.widget.SwipeRefreshLayout
Android:id="@+id/swipe_container"
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<ScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
</RelativeLayout>
</ScrollView>
</Android.support.v4.widget.SwipeRefreshLayout>
Code de fragment:
public static class LinkDetailsFragment extends BaseFragment implements SwipeRefreshLayout.OnRefreshListener {
@InjectView(R.id.swipe_container)
SwipeRefreshLayout mSwipeContainer;
public static LinkDetailsFragment newInstance(String subreddit, String linkId) {
Bundle args = new Bundle();
args.putString(EXTRA_SUBREDDIT, subreddit);
args.putString(EXTRA_LINK_ID, linkId);
LinkDetailsFragment fragment = new LinkDetailsFragment();
fragment.setArguments(args);
return fragment;
}
public LinkDetailsFragment() {
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mSwipeContainer.setOnRefreshListener(this);
mSwipeContainer.setColorScheme(Android.R.color.holo_blue_bright,
Android.R.color.holo_green_light,
Android.R.color.holo_orange_light,
Android.R.color.holo_red_light);
mSwipeContainer.setRefreshing(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_link_details, container, false);
ButterKnife.inject(this, rootView);
return rootView;
}
@Override
public void onRefresh() {
// refresh
}
}
Face au même problème. Ma solution -
mSwipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
}
});
Voici les anciennes solutions de contournement.
Cela fonctionnait auparavant sur la version précédente du Android.support.v4
, mais à partir de la version 21.0.0 en cours, il ne fonctionne pas et existe toujours avec Android.support.v4:21.0.3
publié le 10-12. Décembre 2014 et c'est la raison.
L'indicateur SwipeRefreshLayout n'apparaît pas lorsque la setRefreshing(true)
est appelée avant la SwipeRefreshLayout.onMeasure()
Solution de contournement:
appelez setProgressViewOffset()
sur SwipeRefreshLayout
qui invalide la vue circulaire de la présentation, ce qui provoque l'appel immédiat de SwipeRefreshLayout.onMeasure()
.
mSwipeRefreshLayout.setProgressViewOffset(false, 0,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources().getDisplayMetrics()));
mSwipeRefreshLayout.setRefreshing(true);
MISE À JOUR Meilleure solution de contournement
Parce que la barre d’action pourrait devenir plus fine lorsque l’orientation change ou que vous avez défini manuellement la taille de la barre d’action. Nous définissons le décalage en pixels à partir du haut de cette vue, auquel la flèche de progression doit revenir après un mouvement de balayage réussi pour atteindre la taille de la barre d’action actuelle.
TypedValue typed_value = new TypedValue();
getActivity().getTheme().resolveAttribute(Android.support.v7.appcompat.R.attr.actionBarSize, typed_value, true);
mSwipeRefreshLayout.setProgressViewOffset(false, 0, getResources().getDimensionPixelSize(typed_value.resourceId));
UPDATE du 20 novembre 2014
S'il n'est pas très important pour votre application d'afficher SwipeRefreshLayout une fois la vue démarrée. Vous pouvez simplement le poster à une heure future en utilisant des gestionnaires ou tout ce que vous voulez.
par exemple.
handler.postDelayed(new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
}
}, 1000);
ou comme mentionné dans la réponse de Volodymyr Baydalka.
Voici le numéro dans le traqueur de problèmes Android. S'il vous plaît, invitez-le pour leur montrer que nous devons le réparer.
Ma solution est de remplacer SwipeRefreshLayout
:
public class MySwipeRefreshLayout extends SwipeRefreshLayout {
private boolean mMeasured = false;
private boolean mPreMeasureRefreshing = false;
public MySwipeRefreshLayout(final Context context) {
super(context);
}
public MySwipeRefreshLayout(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (!mMeasured) {
mMeasured = true;
setRefreshing(mPreMeasureRefreshing);
}
}
@Override
public void setRefreshing(final boolean refreshing) {
if (mMeasured) {
super.setRefreshing(refreshing);
} else {
mPreMeasureRefreshing = refreshing;
}
}
}
mRefreshLayout.getViewTreeObserver()
.addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mRefreshLayout
.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
mRefreshLayout.setRefreshing(true);
}
});
Avec Android bibliothèque de support 24.2.0, le problème aurait dû être résolu! https://developer.Android.com/topic/libraries/support-library/revisions.html#24-2-0-bugfixes
Basé sur réponse de Volodymyr Baydalka , il ne s'agit que d'une petite idée qui vous aidera à garder le code propre. Cela mérite une publication, je crois: vous pourrez facilement inverser le comportement de publication en appel de méthode direct, une fois le bogue corrigé.
Écrivez une classe utilitaire comme:
public class Utils
{
private Utils()
{
}
public static void setRefreshing(final SwipeRefreshLayout swipeRefreshLayout, final boolean isRefreshing)
{
// From Guava, or write your own checking code
checkNonNullArg(swipeRefreshLayout);
swipeRefreshLayout.post(new Runnable()
{
@Override
public void run()
{
swipeRefreshLayout.setRefreshing(isRefreshing);
}
});
}
}
Dans votre code, remplacez mSwipeContainer.setRefreshing(isRefreshing)
par Utils.setRefreshing(mSwipeContainer, isRefreshing)
: un seul point dans le code doit être modifié une fois le bogue corrigé, la classe Utils
. La méthode peut également être alors insérée (et retirée de Utils
).
Il n'y aura généralement aucune différence visuelle notable. Gardez toutefois à l'esprit que l'actualisation en attente peut garder en vie vos anciennes instances Activity
, en conservant les SwipeRefreshLayout
dans leurs hiérarchies de vues. Si cela vous pose problème, modifiez la méthode pour qu'elle utilise WeakReference
s, mais normalement, vous ne bloquez pas le thread d'interface utilisateur et ne retardez donc gc que de quelques millisecondes.
Vous pouvez aussi appeler cette méthode avant setRefreshing.
swipeRefreshLayout.measure(View.MEASURED_SIZE_MASK,View.MEASURED_HEIGHT_STATE_SHIFT);
swipeRefreshLayout.setRefreshing(true);
Ça marche pour moi.
@ niks.stack En réponse à sa réponse, je montrerais la molette de progression après le onLayout()
. Lorsque je l'utilisais directement après onMeasure()
, il ne tenait pas compte de certains décalages, mais son utilisation après onLayout()
le faisait.
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (!mLaidOut) {
mLaidOut = true;
setRefreshing(mPreLayoutRefreshing);
}
}
@Override
public void setRefreshing(boolean refreshing) {
if (mLaidOut) {
super.setRefreshing(refreshing);
} else {
mPreLayoutRefreshing = refreshing;
}
}
En plus de Volodymyr Baydalka, utilisez également le code suivant:
swipeContainer.post(new Runnable() {
@Override
public void run() {
swipeContainer.setRefreshing(false);
}
});
Explication J'ai implémenté la solution donnée par Volodymyr Baydalka (en utilisant des fragments), mais après le début du swipeReferesh, il ne s'est jamais éteint même en appelant swipeContainer.setRefreshing(false);
. toutes les idées pour lesquelles cela se produit sont les bienvenues.
Cordialement,
'com.Android.support:appcompat-v7:22.2.1'
J'ai utilisé AppCompat Library com.Android.support:appcompat-v7:21.0.3
, en utilisant votre même approche et cela a fonctionné. Donc, vous mettez à jour la version de cette bibliothèque.
Conseil: RelativeLayout
ne supporte pas l'orientation, c'est un attribut pour LinearLayout
.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup view = (ViewGroup) inflater.inflate(R.layout.license_fragment,
container, false);ButterKnife.inject(this, view);
// Setting up Pull to Refresh
swipeToRefreshLayout.setOnRefreshListener(this);
// Indicator colors for refresh
swipeToRefreshLayout.setColorSchemeResources(R.color.green,
R.color.light_green);
}
Layout XML:
<Android.support.v4.widget.SwipeRefreshLayout>
<ScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:paddingBottom="@dimen/activity_margin_vertical"
Android:paddingTop="@dimen/activity_margin_vertical">
<!-- Content -->
</ScrollView>
</Android.support.v4.widget.SwipeRefreshLayout>
J'utilise 'com.Android.support:appcompat-v7:23.1.1'
swipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
getData();
}
});
auparavant, j'utilisais la méthode swipeRefreshLayout.setRefreshing(true);
dans la méthode getData()
. Elle ne fonctionnait donc pas. Je ne sais pas pourquoi sa méthode ne fonctionne pas à l'intérieur.
Bien que j’ai utilisé swipeRefreshLayout.setRefreshing(true);
une seule fois dans mon fragment.
Ma solution (sans support v7) -
TypedValue typed_value = new TypedValue();
getTheme().resolveAttribute(Android.R.attr.actionBarSize, typed_value, true);
swipeLayout.setProgressViewOffset(false, 0, getResources().getDimensionPixelSize(typed_value.resourceId));
if(!swipeLayout.isEnabled())
swipeLayout.setEnabled(true);
swipeLayout.setRefreshing(true);
Essaye ça
mSwipeRefreshLayout.setNestedScrollingEnabled (true);