- 在 ListView 顶部的一个元素——但我认为使用 ListView 上的动画将滚动回项目位置1(基于0)并不容易。
- 在 ListView 外部的另一个视图——但我需要注意当拉动时移动 ListView 的位置,并且我不确定我们是否能够检测到拖动触摸仍然真正滚动 ListView 上的项目。
附言:我想知道官方 Twitter 应用程序源代码何时发布。它已经被提到过,但自那时以来已经过去了6个月,我们没有再听到相关消息。
最后,谷歌发布了一个官方版本的下拉刷新库!
它叫做SwipeRefreshLayout
,在支持库中,文档在这里:
将SwipeRefreshLayout
添加为要处理为下拉刷新布局的视图的父视图。 (我以ListView
为例,可以是任何像LinearLayout
,ScrollView
等的View
)
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pullToRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
向你的类添加一个监听器
protected void onCreate(Bundle savedInstanceState) {
final 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);
。
更新
Android支持库已被弃用,并已被AndroidX取代。新库的链接可以在这里找到。
此外,您需要将以下依赖项添加到项目中:
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
或
您可以前往重构>>迁移到AndroidX,Android Studio将为您处理依赖关系。
我尝试实现了一个下拉刷新组件,但是它远未完成,但展示了一种可能的实现方式,https://github.com/johannilsson/android-pulltorefresh。
主要逻辑通过扩展ListView
实现在PullToRefreshListView
中。 内部使用该小部件已更新为支持1.5及更高版本,请阅读README以获取1.5支持。smoothScrollBy
(API Level 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.support.v4.widget.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>
我假设你正在使用RecyclerView而不是ListView。然而,ListView仍然可以使用,所以你只需要将RecyclerView替换为ListView,并在Java代码(Fragment)中更新引用。
在你的活动片段中,你首先要实现接口SwipeRefreshLayout.OnRefreshListener
:
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);
}
}
希望这能帮助到大众
setRefreshing
:在 http://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html#setRefreshing%28boolean%29 中有说明,“当刷新由滑动手势触发时,请勿调用此函数”。 - gabriel14PullToRefresh
视图的一个分支,它有新的有趣实现,如PullTorRefreshWebView
或PullToRefreshGridView
,或者在列表底部添加PullToRefresh
的可能性。
https://github.com/chrisbanes/Android-PullToRefresh
最好的是它在Android 4.1上运行完美(正常的PullToRefresh
不能工作)。为了实现 Android 的下拉刷新,可以尝试使用以下代码:
<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);
}
我有一种非常简单的方法来做这件事,但不确定它是否是绝对可靠的方法 以下是我的代码 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;
}
}
您只需要在希望使用此ListView的活动上实现ListViewTouchEventListener并设置侦听器。
我已经在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");
}
}
对我来说有效:)
有一种新型的“下拉刷新”方式,类似于Google Now或Gmail应用程序中显示在操作栏顶部的方式,但目前还没有人提到。
现在有一个名为ActionBar-PullToRefresh的库,可以实现完全相同的效果。
https://plus.google.com/109453683460749241197/posts/eqYxXR8L4eb