studio recyclerview hacer como android swiperefreshlayout

android - recyclerview - swiperefreshlayout kotlin



SwipeRefreshLayout setRefreshing() no muestra el indicador inicialmente (14)

Ver la respuesta de Volodymyr Baydalka en su lugar.

Estas son las viejas soluciones alternativas.

Eso solía funcionar en una versión anterior de android.support.v4 , pero a partir de la versión 21.0.0 en curso no funciona y todavía existe con android.support.v4:21.0.3 lanzado del 10 al 12 de diciembre de 2014 y esto es la razón.

El indicador SwipeRefreshLayout no aparece cuando se setRefreshing(true) antes de SwipeRefreshLayout.onMeasure()

Solución alternativa:

llamando a setProgressViewOffset() en SwipeRefreshLayout que invalida la vista circular del diseño, lo que SwipeRefreshLayout.onMeasure() que se llame inmediatamente a SwipeRefreshLayout.onMeasure() .

mSwipeRefreshLayout.setProgressViewOffset(false, 0, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources().getDisplayMetrics())); mSwipeRefreshLayout.setRefreshing(true);

ACTUALIZAR Mejor solución

Debido a que la barra de acción podría adelgazarse cuando cambia la orientación o si ha establecido el tamaño de la barra de acción manualmente. Establecemos el desplazamiento en píxeles desde la parte superior de esta vista en la que la flecha de progreso debe restablecerse después de un gesto de deslizamiento exitoso al tamaño actual de la barra de acción.

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));

ACTUALIZACIÓN Nov 20 2014

Si no es muy importante para su aplicación mostrar SwipeRefreshLayout una vez que se inicia la vista. Puede publicarlo en un momento en el futuro mediante el uso de controladores o cualquier cosa que desee.

como ejemplo.

handler.postDelayed(new Runnable() { @Override public void run() { mSwipeRefreshLayout.setRefreshing(true); } }, 1000);

o como mencionó la respuesta de Volodymyr Baydalka.

Aquí está el issue en el rastreador de problemas de Android. Vota a favor para mostrarles que necesitamos que se solucione.

Tengo un diseño muy simple, pero cuando llamo a setRefreshing(true) en onActivityCreated() de mi fragmento, no se muestra inicialmente.

Solo se muestra cuando hago un pull para actualizar. ¿Alguna idea de por qué no aparece inicialmente?

Fragmento 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>

Código de fragmento:

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 } }


@ niks.stack En respuesta a su respuesta, mostraría la rueda de progreso después de que se haya completado onLayout() . Cuando lo usé directamente después de onMeasure() , no onMeasure() algunos de los desplazamientos, pero lo onLayout() después de onLayout() .

@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; } }


Además de Volodymyr Baydalka, use también el siguiente código:

swipeContainer.post(new Runnable() { @Override public void run() { swipeContainer.setRefreshing(false); } });

Explicación Implementé la solución dada por Volodymyr Baydalka (usando fragmentos) pero después de que comenzó swipeReferesh nunca desapareció incluso al llamar a swipeContainer.setRefreshing(false); así que tuve que implementar el código dado anteriormente que resolvió mi problema. cualquier otra idea de por qué sucede esto es muy bienvenida.

Saludos,

''com.android.support:appcompat-v7:22.2.1''


Ante el mismo problema. Mi solución -

mSwipeRefreshLayout.post(new Runnable() { @Override public void run() { mSwipeRefreshLayout.setRefreshing(true); } });



Estoy usando ''com.android.support:appcompat-v7:23.1.1''

swipeRefreshLayout.post(new Runnable() { @Override public void run() { swipeRefreshLayout.setRefreshing(true); getData(); } });

anteriormente estaba usando swipeRefreshLayout.setRefreshing(true); dentro del método getData() , por lo que no estaba funcionando. No sé por qué no funciona dentro del método.

Aunque usé swipeRefreshLayout.setRefreshing(true); solo una vez en mi Fragmento.


Mi solución (sin soporte 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);


Mi solución es anular 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; } } }


Otra solución es crear un nuevo control y derivador de SwipeRefreshLayout. Anule la función OnMeasure y vuelva a alternar la actualización, si la actualización está activada. Utilizo esta solución en un proyecto xamarin y funciona bien. Aquí algunos ejemplos de código C #:

class MySwipeRefreshLayout : SwipeRefreshLayout { /// <summary> /// used to indentify, if measure was called for the first time /// </summary> private bool m_MeasureCalled; public MvxSwipeRefreshLayout(Context context, IAttributeSet attrs) : base(context, attrs) { } public MvxSwipeRefreshLayout(Context context) : base(context) { } public override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) { base.OnMeasure(widthMeasureSpec, heightMeasureSpec); if (!m_MeasureCalled) { //change refreshing only one time m_MeasureCalled = true; if (Refreshing) { Refreshing = false; Refreshing = true; } } } }


Prueba esto

mSwipeRefreshLayout.setNestedScrollingEnabled (true);


Según la respuesta de Volodymyr Baydalka , esta es solo una pequeña idea que lo ayudará a mantener limpio el código. Merece una publicación, creo: podrá revertir fácilmente el comportamiento de la publicación a la llamada al método directo, una vez que se solucione el error.

Escribe una clase de utilidad como:

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); } }); } }

En su código, sustituya mSwipeContainer.setRefreshing(isRefreshing) por Utils.setRefreshing(mSwipeContainer, isRefreshing) : ahora solo es necesario cambiar un punto en el código una vez que se corrige el error, la clase Utils . El método también se puede insertar en línea (y eliminar de Utils ).

Por lo general, no habrá una diferencia visual notable. Sin embargo, tenga en cuenta que la actualización pendiente podría mantener vivas sus instancias de Activity , manteniendo SwipeRefreshLayout en sus jerarquías de vista. Si eso es una preocupación, modifique el método para usar WeakReference s, pero normalmente no bloquea el hilo de la interfaz de usuario de todos modos, y por lo tanto demora gc solo por un par de milisegundos.


También puede llamar a este método antes de setRefreshing ..

swipeRefreshLayout.measure(View.MEASURED_SIZE_MASK,View.MEASURED_HEIGHT_STATE_SHIFT); swipeRefreshLayout.setRefreshing(true);

Me funcionó.


Utilicé AppCompat Library com.android.support:appcompat-v7:21.0.3 , usando su mismo enfoque y funcionó. Entonces, actualizas la versión de esa biblioteca.

Consejo: RelativeLayout no admite orientación, es un atributo para 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); }

Diseño 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>


mRefreshLayout.getViewTreeObserver() .addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { mRefreshLayout .getViewTreeObserver() .removeGlobalOnLayoutListener(this); mRefreshLayout.setRefreshing(true); } });