Cómo implementar Android Pull-to-Refresh
En aplicaciones Android como Twitter (aplicación oficial), cuando se encuentra con una vista de lista, se puede tirar hacia abajo (y se recuperará cuando se lance) para actualizar el contenido.
Me pregunto cuál es la mejor manera, en su opinión, de implementar eso.
Algunas posibilidades que se me ocurren:
- Un elemento en la parte superior de la ListView - sin embargo, no creo que desplazarse hacia atrás a la posición del elemento 1 (basado en 0) con animación en la ListView sea una tarea fácil.
- Otra vista fuera de la ListView-pero tengo que cuidar de mover la posición de la ListView hacia abajo cuando se tira, y no estoy seguro de si podemos detectar si los toques de arrastre a la ListView todavía realmente desplazan los elementos en la ListView.
Alguna recomendación?
P.d. Me pregunto cuándo se lanzará el código fuente oficial de la aplicación de Twitter. Se ha mencionado que se lanzará, pero han pasado 6 meses y no hemos oído hablar de él desde entonces.
14 answers
Finalmente, Google lanzó una versión oficial de la biblioteca pull-to-refresh!
Se llama SwipeRefreshLayout
, dentro de la biblioteca de soporte, y la documentación es aquí:
1) Agregue SwipeRefreshLayout
como un padre de la vista que se tratará como pull para actualizar el diseño. (Tomé ListView
como ejemplo, puede ser cualquier View
como LinearLayout
, ScrollView
etc.)
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/pullToRefresh"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
2) Agregar un oyente a su clase
protected void onCreate(Bundle savedInstanceState) {
SwipeRefreshLayout pullToRefresh = findViewById(R.id.pullToRefresh);
pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refreshData(); // your code
pullToRefresh.setRefreshing(false);
}
});
}
También puede llamar a pullToRefresh.setRefreshing(true/false);
según su requisito.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-10 15:57:20
He hecho un intento de implementar un componente pull to refresh, está lejos de completarse pero demuestra una posible implementación, https://github.com/johannilsson/android-pulltorefresh .
La lógica principal se implementa en PullToRefreshListView
que se extiende ListView
. Internamente controla el desplazamiento de una vista de encabezado usando El widget ahora se actualiza con soporte para 1.5 y posteriores, por favor lea el README para soporte 1.5 sin embargo.smoothScrollBy
(Nivel de API 8).
En su diseños que simplemente añadir como este.
<com.markupartist.android.widget.PullToRefreshListView
android:id="@+id/android:list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
/>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-24 16:00:03
También he implementado una biblioteca PullToRefresh robusta, de código abierto, fácil de usar y altamente personalizable para Android. Puede reemplazar su ListView con el PullToRefreshListView como se describe en la documentación en la página del proyecto.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-07 02:03:24
La forma más fácil creo que es la proporcionada por la biblioteca de soporte de Android:
Android.apoyo.v4.widget.SwipeRefreshLayout;
Una vez que se importa, puede tener su diseño definido de la siguiente manera:
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/refresh"
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.v7.widget.RecyclerView
xmlns:recycler_view="http://schemas.android.com/apk/res-auto"
android:id="@android:id/list"
android:theme="@style/Theme.AppCompat.Light"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/button_material_light"
>
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
Asumo que utilizas la vista recycler en lugar de listview. Sin embargo, listview todavía funciona, por lo que solo necesita reemplazar recyclerview con listview y actualizar las referencias en el código java (Fragmento).
En su fragmento de actividad, primero implementa interfaz, SwipeRefreshLayout.OnRefreshListener
:
i, e
public class MySwipeFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener{
private SwipeRefreshLayout swipeRefreshLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_item, container, false);
swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.refresh);
swipeRefreshLayout.setOnRefreshListener(this);
}
@Override
public void onRefresh(){
swipeRefreshLayout.setRefreshing(true);
refreshList();
}
refreshList(){
//do processing to get new data and set your listview's adapter, maybe reinitialise the loaders you may be using or so
//when your data has finished loading, cset the refresh state of the view to false
swipeRefreshLayout.setRefreshing(false);
}
}
Espero que esto ayude a las masas
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-15 18:28:08
En este enlace, puedes encontrar una bifurcación de la famosa vista PullToRefresh
que tiene nuevas implementaciones interesantes como PullTorRefreshWebView
o PullToRefreshGridView
o la posibilidad de agregar un PullToRefresh
en el borde inferior de una lista.
Https://github.com/chrisbanes/Android-PullToRefresh
Y lo mejor de todo es que funciona perfectamente en Android 4.1 (lo normal PullToRefresh
no funciona)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-10 14:48:33
Tengo una manera muy fácil de hacer esto, pero ahora seguro que es la manera infalible Ahí está mi código PullDownListView.java
package com.myproject.widgets;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
/**
* @author Pushpan
* @date Nov 27, 2012
**/
public class PullDownListView extends ListView implements OnScrollListener {
private ListViewTouchEventListener mTouchListener;
private boolean pulledDown;
public PullDownListView(Context context) {
super(context);
init();
}
public PullDownListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public PullDownListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
setOnScrollListener(this);
}
private float lastY;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
lastY = ev.getRawY();
} else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
float newY = ev.getRawY();
setPulledDown((newY - lastY) > 0);
postDelayed(new Runnable() {
@Override
public void run() {
if (isPulledDown()) {
if (mTouchListener != null) {
mTouchListener.onListViewPulledDown();
setPulledDown(false);
}
}
}
}, 400);
lastY = newY;
} else if (ev.getAction() == MotionEvent.ACTION_UP) {
lastY = 0;
}
return super.dispatchTouchEvent(ev);
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
setPulledDown(false);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
public interface ListViewTouchEventListener {
public void onListViewPulledDown();
}
public void setListViewTouchListener(
ListViewTouchEventListener touchListener) {
this.mTouchListener = touchListener;
}
public ListViewTouchEventListener getListViewTouchListener() {
return mTouchListener;
}
public boolean isPulledDown() {
return pulledDown;
}
public void setPulledDown(boolean pulledDown) {
this.pulledDown = pulledDown;
}
}
Solo necesita implementar ListViewTouchEventListener en su actividad donde desea usar este ListView y establecer el listener
Lo tengo implementado en PullDownListViewActivity
package com.myproject.activities;
import android.app.Activity;
import android.os.Bundle;
/**
* @author Pushpan
*
*/
public class PullDownListViewActivity extends Activity implements ListViewTouchEventListener {
private PullDownListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
listView = new PullDownListView(this);
setContentView(listView);
listView.setListViewTouchListener(this);
//setItems in listview
}
public void onListViewPulledDown(){
Log.("PullDownListViewActivity", "ListView pulled down");
}
}
Funciona para mí:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-27 11:45:02
Para implementar android Pull-to-Refresh pruebe esta pieza de código,
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/pullToRefresh"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</android.support.v4.widget.SwipeRefreshLayout>
Clase de actividad:
ListView lv = (ListView) findViewById(R.id.lv);
SwipeRefreshLayout pullToRefresh = (SwipeRefreshLayout) findViewById(R.id.pullToRefresh);
lv.setAdapter(mAdapter);
pullToRefresh.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh() {
// TODO Auto-generated method stub
refreshContent();
}
});
private void refreshContent(){
new Handler().postDelayed(new Runnable() {
@Override public void run() {
pullToRefresh.setRefreshing(false);
}
}, 5000);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-20 08:51:10
Nadie ha mencionado el nuevo tipo de "Pull to refresh" que se muestra en la parte superior de la barra de acciones como en la aplicación Google Now o Gmail.
Existe una biblioteca ActionBar-PullToRefresh que funciona exactamente igual.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-21 11:10:31
Tenga en cuenta que hay problemas de UX con los que lidiar al implementar en Android y WP.
"Un gran indicador de por qué los diseñadores/desarrolladores no deben implementar pull-to-refresh en el estilo que hacen las aplicaciones de iOS es cómo Google y sus equipos nunca usan pull-to-refresh en Android mientras lo usan en iOS. "
Https://plus.google.com/109453683460749241197/posts/eqYxXR8L4eb
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-23 20:09:02
Si no quieres que tu programa se vea como un programa de iPhone que se ajusta a la fuerza en Android, busca un aspecto más nativo y haz algo similar a Gingerbread:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-05 14:34:28
He escrito un pull para actualizar el componente aquí: https://github.com/guillep/PullToRefresh Funciona evento si la lista no tiene elementos, y lo he probado en >=1.6 teléfonos android.
Cualquier sugerencia o mejora es apreciada:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-30 20:05:21
Creo que la mejor biblioteca es : https://github.com/chrisbanes/Android-PullToRefresh.
Funciona con:
ListView
ExpandableListView
GridView
WebView
ScrollView
HorizontalScrollView
ViewPager
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-25 05:13:24
Para obtener el último Pull de piruleta-Para Actualizar:
- Descargue la última Lollipop SDK y Extras / Biblioteca de soporte de Android
- Establezca el objetivo de compilación del proyecto en Android 5.0 (de lo contrario, el paquete de soporte puede tener errores con los recursos)
- Actualiza tu libs/android-support-v4.jar to 21st version
- Use
android.support.v4.widget.SwipeRefreshLayout
másandroid.support.v4.widget.SwipeRefreshLayout.OnRefreshListener
Se puede encontrar una guía detallada aquí: http://antonioleiva.com/swiperefreshlayout /
Más para ListView Recomiendo lea acerca de canChildScrollUp()
en los comentarios;)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-19 20:34:45
Muy interesante Pull-to-Refresh por Yalantis. Gif para iOS, pero puedes comprobarlo:)
<com.yalantis.pulltorefresh.library.PullToRefreshView
android:id="@+id/pull_to_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/list_view"
android:divider="@null"
android:dividerHeight="0dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-19 13:42:39