Как реализовать Android Pull-To-Refresh
В Android-приложениях, таких как Twitter (официальное приложение), когда вы сталкиваетесь с ListView, вы можете вытащить его (и он будет отскакивать при выпуске), чтобы обновить содержимое.
интересно, как лучше всего, на ваш взгляд, реализовать это?
некоторые возможности, которые я мог бы придумать:
- элемент поверх ListView-однако я не думаю, что прокрутка назад к позиции элемента 1( на основе 0) с анимацией на ListView-это легко задача.
- другой вид за пределами ListView-но мне нужно позаботиться о перемещении позиции ListView вниз, когда она вытягивается, и я не уверен, что мы можем обнаружить, если перетаскивание касается ListView все еще действительно прокручивает элементы в ListView.
какие рекомендации?
P. S. Интересно, когда выйдет официальный твиттер исходный код приложения. Было упомянуто, что он будет выпущен, но прошло 6 месяцев, и мы не слышали об этом с тех пор затем.
14 ответов:
наконец, Google выпустила официальную версию библиотеки pull-To-refresh!
это называется
SwipeRefreshLayout, внутри библиотеки поддержки, и документация здесь:1) добавить
SwipeRefreshLayoutкак родитель вида, который будет рассматриваться как pull для обновления макета. (Я взялListViewв качестве примера, это может быть любойViewкакLinearLayout,ScrollViewetc.)<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) добавить слушателя к вашему класс
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); } }); }вы также можете позвонить
pullToRefresh.setRefreshing(true/false);согласно вашему требованию.
Я сделал попытку реализовать pull для обновления компонента, это далеко не полный но демонстрирует возможную реализацию,https://github.com/johannilsson/android-pulltorefresh.
основная логика реализована в
PullToRefreshListViewчто расширяетListView.внутренне он управляет прокруткой представления заголовка с помощьювиджет теперь обновляется с поддержкой 1.5 и более поздних версий, пожалуйста, прочитайте README для 1.5 однако поддержка.smoothScrollBy(уровень API 8).в ваших макетах вы просто добавляете его так.
<com.markupartist.android.widget.PullToRefreshListView android:id="@+id/android:list" android:layout_height="fill_parent" android:layout_width="fill_parent" />
Я также реализовал надежный, с открытым исходным кодом, простой в использовании и настраиваемый PullToRefresh библиотека для Android. Вы можете заменить ListView на PullToRefreshListView, как описано в документации на странице проекта.
самый простой способ, я думаю, как это предусмотрено в библиотеку поддержки Android:
android.поддержка.v4.штучка.SwipeRefreshLayout;
после того, как это импортируется, то вы можете иметь свой макет определяется следующим образом:
<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>Я предполагаю, что вы используете recycler view вместо listview. Однако listview все еще работает, поэтому вам просто нужно заменить recyclerview на listview и обновить ссылки в коде java (фрагмент).
В вашей деятельности фрагмент, вы сначала реализуете интерфейс,
SwipeRefreshLayout.OnRefreshListener: i, epublic 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); } }надеюсь, это поможет массам
в этой ссылке, вы можете найти вилка знаменитого
PullToRefreshпросмотр, который имеет новые интересные реализации, такие какPullTorRefreshWebViewилиPullToRefreshGridViewили возможность добавитьPullToRefreshв нижней части списка.https://github.com/chrisbanes/Android-PullToRefresh
и самое лучшее, что отлично работает в Android 4.1 (нормальный
PullToRefreshне работает )
у меня есть очень простой способ сделать это, но теперь уверен, что его надежный способ Вот мой код 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; } }вам просто нужно реализовать ListViewTouchEventListener на вашей деятельности, где вы хотите использовать этот ListView и установить прослушиватель
я реализовал его в 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"); } }это работает для меня :)
для реализации android Pull-To-Refresh попробуйте этот кусок кода,
<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>занятие:
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); }
никто не упоминает новый тип "Pull To refresh", который отображается поверх панели действий, как в приложении Google Now или Gmail.
библиотека ActionBar-PullToRefresh, который работает точно так же.
Примечание есть проблемы UX, чтобы бороться с при реализации на Android и WP.
"отличный индикатор того, почему дизайнеры/разработчики не должны реализовывать pull-To-refresh в стиле iOS-приложений,-это то, как Google и их команды никогда не используют pull-To-refresh на Android, пока они используют его в iOS. "
https://plus.google.com/109453683460749241197/posts/eqYxXR8L4eb
Если вы не хотите, чтобы ваша программа выглядела как программа для iPhone, которая принудительно встроена в Android, стремитесь к более родному внешнему виду и делайте что-то похожее на Gingerbread:
Я написал тянуть, чтобы обновить компонент здесь:https://github.com/guillep/PullToRefresh Он работает событие, если в списке нет элементов, и я проверил его на >=1.6 android телефонов.
любое предложение или улучшение приветствуется :)
Я думаю, что лучшая библиотека:https://github.com/chrisbanes/Android-PullToRefresh.
работает:
ListView ExpandableListView GridView WebView ScrollView HorizontalScrollView ViewPager
чтобы получить последний леденец тянуть-обновить:
- загрузите последнюю версию Lollipop SDK и Extras / библиотеку поддержки Android
- установите цель сборки проекта на Android 5.0 (в противном случае пакет поддержки может иметь ошибки с ресурсами)
- обновление libs / android-поддержка-v4.jar до 21-й версии
- использовать
android.support.v4.widget.SwipeRefreshLayoutплюсandroid.support.v4.widget.SwipeRefreshLayout.OnRefreshListenerподробное руководство можно найти здесь: http://antonioleiva.com/swiperefreshlayout/
плюс для ListView я рекомендую прочитать о
canChildScrollUp()в комментариях ;)
очень интересно Pull-To-Refresh by Yalantis. Gif для iOS, но вы можете проверить это:)
<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" />

Comments