如何实现Android的拉到刷新

在Twitter(官方应用)等Android应用中,当你遇到一个ListView时,你可以下拉它(它会在发布时反弹)来刷新内容。

我想知道,在你看来,最好的实现方式是什么?

我能想到的一些可能性:

  1. 一个在ListView顶部的项目-然而我不认为滚动回项目位置1(基于0)在ListView上的动画是一个简单的任务。
  2. ListView之外的另一个视图-但我需要注意在它被拉时将ListView位置向下移动,我不确定我们是否可以检测到对ListView的拖动触摸是否仍然真正滚动ListView上的项。

你有什么推荐吗?

另外,我想知道官方的Twitter应用程序源代码什么时候发布。有消息说它会发布,但6个月过去了,我们一直没有听到它的消息。

270383 次浏览

如果你不想让你的程序看起来像一个强行安装在Android上的iPhone程序,目标是一个更原生的外观和感觉,并做一些类似于Gingerbread的事情:

alt text

我已经尝试实现一个拉取刷新组件,它是远未完成,但演示了一个可能的实现,https://github.com/johannilsson/android-pulltorefresh

主要逻辑在PullToRefreshListView中实现,它扩展了ListView在内部,它使用smoothScrollBy (API级别8)控制头视图的滚动。小部件现在更新了1.5及以后的支持,请阅读README 1.5支持。

在你的布局中,你只需像这样添加它。

<com.markupartist.android.widget.PullToRefreshListView
android:id="@+id/android:list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
/>

我在这里写了一个刷新组件:https://github.com/guillep/PullToRefresh 它的工作事件,如果列表没有项目,我已经在>=1.6 android手机上测试了它

欢迎任何建议或改进:)

我还为Android实现了一个健壮的、开源的、易于使用的和高度可定制的PullToRefresh库。你可以用PullToRefreshListView替换你的ListView,就像在项目页面的文档中描述的那样。

https://github.com/erikwt/PullToRefresh-ListView

在这个链接中,你可以找到著名的PullToRefresh视图的一个分支,它有新的有趣的实现,如PullTorRefreshWebViewPullToRefreshGridView,或者可以在列表的底部边缘添加PullToRefresh

https://github.com/chrisbanes/Android-PullToRefresh

最好的是,它在Android 4.1中工作完美(正常的PullToRefresh不工作)

注意,在Android和WP上实现时,有一些UX问题需要解决。

“为什么设计师/开发者不应该像iOS应用那样执行拉式刷新,一个很好的指标是谷歌及其团队在Android上从未使用过拉式刷新,而他们却在iOS上使用它。”

https://plus.google.com/109453683460749241197/posts/eqYxXR8L4eb

我有一个很简单的方法来做到这一点,但现在确定这是万无一失的方法 这是我的代码 PullDownListView.java < / p >
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");
}
}

这对我很有用:)

没有人提到新的类型的“拉刷新”,显示在操作栏的顶部,就像谷歌Now或Gmail应用程序。

有一个库ActionBar-PullToRefresh的工作原理完全相同。

最后,谷歌发布了一个官方版本的拉取刷新库!

它被称为SwipeRefreshLayout,在支持库中,文档是这里<强> < / >强:

  1. 添加SwipeRefreshLayout作为视图的父视图,它将被视为刷新布局的pull。(我以ListView为例,它可以是任何View,如LinearLayoutScrollView等)

     <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>
    
  2. 在你的类中添加一个监听器

     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'

你可以去Refactor>>Migrate to AndroidX, Android Studio会为你处理依赖关系。

我认为最好的库是:https://github.com/chrisbanes/Android-PullToRefresh

适用于:

ListView
ExpandableListView
GridView
WebView
ScrollView
HorizontalScrollView
ViewPager

要获得最新的棒棒糖拉刷新:

  1. 下载最新的棒棒糖SDK和Extras/Android支持库
  2. 将项目的构建目标设置为Android 5.0(否则支持包可能会与资源有错误)
  3. 更新libs/android-support-v4.jar到21版
  4. 使用android.support.v4.widget.SwipeRefreshLayout + android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener

详细的指南可以在这里找到:http://antonioleiva.com/swiperefreshlayout/

加上ListView,我建议在评论中阅读canChildScrollUp();)

Pull-to-Refresh by Yalantis。 Gif for 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" />

要实现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);


}

我认为最简单的方法是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>

我假设您使用的是回收视图而不是列表视图。然而,listview仍然可以工作,所以你只需要用listview替换recyclerview并更新java代码中的引用(Fragment)。

在你的活动片段中,你首先实现接口SwipeRefreshLayout.OnRefreshListener: 我,e < / p >
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);


}
}

希望这对大众有所帮助

我们首先应该知道什么是拖动刷新布局在android。我们可以在android中调用滑动刷新来刷新。当你从上到下滑动屏幕时,它会基于setOnRefreshListener做一些动作。

这里是教程,演示了如何实现android拉刷新。我希望这能有所帮助。

那些希望实现RecyclerView的拉取刷新功能的人可以跟随我的简单教程如何实现拉到刷新RecyclerView在Android

要导入的库

implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.gridlayout:gridlayout:1.0.0'

XML代码

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">


<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>


</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

活动JAVA代码

import androidx.appcompat.app.AppCompatActivity;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.os.Bundle;
import android.os.Handler;


public class MainActivity extends AppCompatActivity {


private SwipeRefreshLayout swipeRefreshLayout;


...


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
       

...
swipeRefreshLayout = findViewById(R.id.swipe_layout);
initializeRefreshListener();
}


void initializeRefreshListener() {


swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
// This method gets called when user pull for refresh,
// You can make your API call here,
// We are using adding a delay for the moment
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if(swipeRefreshLayout.isRefreshing()) {
swipeRefreshLayout.setRefreshing(false);
}
}
}, 3000);
}
});
}

将此添加到布局中

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

现在只需在代码中添加以下这些行

 mSwipeRefreshLayout.setOnRefreshListener(() -> {


// your refresh code here


});

都做完了

如果你想在webview或其他地方使用拉动刷新,然后简单地复制粘贴这段代码到你的项目,它可以正常工作。

XML源代码:

   <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/WebView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true">
</WebView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

JAVA代码:

  final SwipeRefreshLayout pullToRefresh = findViewById(R.id.swiperefresh);
pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh()
{
Toast.makeText(WebBrowser.this,"pull to refresh",Toast.LENGTH_LONG).show();
mwebView.loadUrl(mainUrl);
pullToRefresh.setRefreshing(false);//if false then refresh progress dialog will disappear when page loading finish, but if it is true then always the refresh load dialog show even after the page load or not
}
});

构建。Gradle源代码:

 implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'