关闭

android 下拉刷新(Swipe-to-Refresh)

标签: android
372人阅读 评论(0) 收藏 举报
分类:

android 下拉刷新(Swipe-to-Refresh)

参考:

ListView 使用(1)http://blog.csdn.net/u012005313/article/details/60468413
SwipeRefreshLayouthttps://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html
Supporting Swipe-to-Refreshhttps://developer.android.com/training/swipe/index.html


android 提供了组件 android.support.v4.widget.SwipeRefreshLayout 以支持下拉刷新操作


主要内容

  1. 添加 SwipeRefreshLayout 组件
  2. 添加菜单项
  3. ListFragment 的结合

添加 SwipeRefreshLayout 组件

SwipeRefreshLayout 组件可以检测下拉刷新手势,从而调用回调方法

其使用方法是将 SwipeRefreshLayout 作为父视图置于布局文件中,且其仅支持一个直接子视图

This layout should be made the parent of the view that will be refreshed as a result of the gesture and can only support one direct child

比如:

<android.support.v4.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">

    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.v4.widget.SwipeRefreshLayout>

工程如下:

新建 MainActivity.java

package com.uniview.swiperefreshlayouttest;

import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();

    private SwipeRefreshLayout srl;
    private ListView lv;

    MyAapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        srl = (SwipeRefreshLayout)findViewById(R.id.am_srl);
        lv = (ListView)findViewById(R.id.am_lv);

        adapter = new MyAapter(this, android.R.layout.simple_list_item_1, getItemList());

        lv.setAdapter(adapter);

        /*
         * Sets up a SwipeRefreshLayout.OnRefreshListener that is invoked when the user
         * performs a swipe-to-refresh gesture.
         */
        srl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                Log.e(TAG, "onRefresh: ");

                // This method performs the actual data-refresh operation.
                // The method calls setRefreshing(false) when it's finished.
                myUpdateOperation();
            }
        });
    }

    private List<Item> getItemList() {
        List<Item> itemList = new ArrayList<>();

        String[] arr = getResources().getStringArray(android.R.array.phoneTypes);
        for (String str : arr) {
            Item item = new Item(str);

            itemList.add(item);
        }

        return itemList;
    }

    private int id = 0;

    private void myUpdateOperation() {
        adapter.add(new Item("add" + String.valueOf(id)));
        id++;

        srl.setRefreshing(false);
    }
}

新建 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/am_srl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.uniview.swiperefreshlayouttest.MainActivity">

    <ListView
        android:id="@+id/am_lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.v4.widget.SwipeRefreshLayout>

新建 MyAdapter.java

package com.uniview.swiperefreshlayouttest;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.List;

/**
 * Created by Lenovo on 2017/3/6.
 */

public class MyAapter extends ArrayAdapter<Item> {
    private static final String TAG = MyAapter.class.getSimpleName();

    private Context context;
    private int resource;

    public MyAapter(Context context, int resource, List<Item> itemList) {
        super(context, resource, itemList);

        this.context = context;
        this.resource = resource;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
//        return super.getView(position, convertView, parent);
        Item item = getItem(position);
        View view;
        ViewHolder viewHolder;

        if (convertView == null) {
            view = LayoutInflater.from(context).inflate(resource, null);
            viewHolder = new ViewHolder();

            viewHolder.tv = (TextView)view.findViewById(android.R.id.text1);
            view.setTag(viewHolder);
        } else {
            view = convertView;
            viewHolder = (ViewHolder)view.getTag();
        }

        viewHolder.tv.setText(item.getText());

        return view;
    }

    class ViewHolder {
        TextView tv;
    }
}

新建 Item.java

package com.uniview.swiperefreshlayouttest;

/**
 * Created by Lenovo on 2017/3/6.
 */

public class Item {

    String text;

    public Item(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

通过应用 OnRefreshListener 接口,当下拉手势被检测到后,调用 onRefresh 方法:

/**
 * Classes that wish to be notified when the swipe gesture correctly
 * triggers a refresh should implement this interface.
 */
public interface OnRefreshListener {
    /**
     * Called when a swipe gesture triggers a refresh.
     */
    void onRefresh();
}

onRefresh 方法中完成更新操作后,需要显示调用 setRefresh(false) 方法来结束进度指示器显示

/**
 * Notify the widget that refresh state has changed. Do not call this when
 * refresh is triggered by a swipe gesture.
 *
 * @param refreshing Whether or not the view should show refresh progress.
 */
public void setRefreshing(boolean refreshing) {
    if (refreshing && mRefreshing != refreshing) {
        // scale and show
        mRefreshing = refreshing;
        int endTarget = 0;
        if (!mUsingCustomStart) {
            endTarget = mSpinnerOffsetEnd + mOriginalOffsetTop;
        } else {
            endTarget = mSpinnerOffsetEnd;
        }
        setTargetOffsetTopAndBottom(endTarget - mCurrentTargetOffsetTop,
                true /* requires update */);
        mNotify = false;
        startScaleUpAnimation(mRefreshListener);
    } else {
        setRefreshing(refreshing, false /* notify */);
    }
}

添加菜单项

通过设置菜单项,也可以手动启动 SwipeRefreshLayout

新建 menu_main.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item android:id="@+id/menu_refresh"
        app:showAsAction="never"
        android:title="refresh" />

</menu>

MainActivity.java 中加入:

...
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_main, menu);

    return true;
}

/*
 * Listen for option item selections so that we receive a notification
 * when the user requests a refresh by selecting the refresh action bar item.
 */
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {

        // Check if user triggered a refresh:
        case R.id.menu_refresh:
            Log.i(TAG, "Refresh menu item selected");

            // Signal SwipeRefreshLayout to start the progress indicator
            srl.setRefreshing(true);

            // Start the refresh background task.
            // This method calls setRefreshing(false) when it's finished.
            myUpdateOperation();

            return true;
    }

    // User didn't trigger a refresh, let the superclass handle this action
    return super.onOptionsItemSelected(item);

}
...

当点击菜单项 refresh 时,显示进度指示器(progress indicator):srl.setRefreshing(true);;同时进行更新操作:myUpdateOperation();

注:在更新完成后同样需要显示调用 setRefreshing(false) 来关闭进度指示器

结果如下:

这里写图片描述


ListFragment 的结合

ListFragment 内置了一个 ListView,如果想要添加下拉刷新功能,需要自定义布局文件,加入 SwipeRefreshLayout,同时需要包含内置的 ListView(其 id@android:id/list

新建 fragment_refresh.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/fr_srl"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ListView
            android:id="@id/android:list"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </android.support.v4.widget.SwipeRefreshLayout>

</LinearLayout>

新建 RefreshFragment.java

package com.uniview.swiperefreshlayouttest;

import android.app.ListFragment;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


/**
 * Created by Lenovo on 2017/3/6.
 */

public class RefreshFragment extends ListFragment {
    private static final String TAG = RefreshFragment.class.getSimpleName();

    private SwipeRefreshLayout srl;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//        return super.onCreateView(inflater, container, savedInstanceState);

        View view = inflater.inflate(R.layout.fragment_refresh, container, false);

        srl = (SwipeRefreshLayout)view.findViewById(R.id.fr_srl);

        srl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                Log.e(TAG, "onRefresh: ");

                // This method performs the actual data-refresh operation.
                // The method calls setRefreshing(false) when it's finished.
                myUpdateOperation();
            }
        });

        return view;
    }

    private void myUpdateOperation() {
        srl.setRefreshing(false);
    }

}

官方也提供了一个 demo:

SwipeRefreshListFragment

0
0
查看评论

Android 众多优秀的下拉刷新

众多优秀的下拉刷新
  • jcy2sls
  • jcy2sls
  • 2016-04-13 15:42
  • 4474

Android下拉刷新效果实现

本文主要包括以下内容 自定义实现pulltorefreshView 使用google官方SwipeRefreshLayout 下拉刷新大致原理 判断当前是否在最上面而且是向下滑的,如果是的话,则加载数据,并更新界面。自定义实现pulltorefreshViewpackage com.jimst...
  • whuhan2013
  • whuhan2013
  • 2016-06-08 16:02
  • 1717

Android 下拉刷新框架实现

一个通用的下拉刷新的框架介绍。 前段时间项目中用到了下拉刷新功能,之前在网上也找到过类似的demo,但这些demo的质量参差不齐,用户体验也不好,接口设计也不行。最张没办法,终于忍不了了,自己就写了一个下拉刷新的框架,这个框架是一个通用的框架,效果和设计感觉都还不错,现在分享给各位看官。
  • leehong2005
  • leehong2005
  • 2013-10-13 23:20
  • 127107

解读Google官方SwipeRefreshLayout控件源码,带你揭秘Android下拉刷新的实现原理

前言想必大家也发现,时下的很多App都应用了这个Google出品的SwipeRefreshLayout下拉刷新控件,它以Material Design风格、适用场景广泛,简单易用等特性而独步江湖。但在我们使用的过程中,不可避免地会发现一些bug,或者需要添加某些特性来满足需求。出现这些问题,最好的方...
  • TellH
  • TellH
  • 2016-03-02 22:42
  • 7372

Android——谷歌官方下拉刷新控件SwipeRefreshLayout

前言: 如今谷歌推出了更官方的下拉刷新控件, 这无疑是对安卓开发人员来说是个好消息,很方便的使用这个SwipeRefreshLayout控件实现下拉刷新功能。Android4.0以下的版本需要用到 android-support-v4.jar包才能用到 android-support-v4.j...
  • zouzhigang96
  • zouzhigang96
  • 2016-01-07 15:00
  • 3483

Android 怎么实现支持所有View的通用的下拉刷新控件

转载请标明出处: 本文出自:【AItsuki的博客】 下拉刷新对于一个app来说是必不可少的一个功能,在早期大多数使用的是chrisbanes的PullToRefresh,或是修改自该框架的其他库。而到现在已经有了更多的选择,github上还是有很多体验不错的下拉刷新。而下拉刷新主要有两种实...
  • u010386612
  • u010386612
  • 2016-06-20 12:25
  • 6713

Android 自定义下拉刷新样式解决方案

随着现在Android设备的越来越多,各种应用层出不穷,下拉刷新这种基本上每个应用都必备的东西也被人玩出了各种花样了。一开始下拉刷新都这这样的(XListView): 不过这样子做,只支持ListView 并且对ListView的侵入太深,所有很快就被摒弃了,演变成了这样 chrisbanes/...
  • u011068996
  • u011068996
  • 2016-02-03 13:39
  • 1623

安卓下拉刷新开源库对比

目前仅比对github上star数>1500的下拉刷新开源库,在比较完成之后可能会加入其它有代表性的库. Repo Repo Owner Star (2015.12.5) version Snap shot Android...
  • nnmmbb
  • nnmmbb
  • 2016-03-31 15:39
  • 1415

android下拉刷新scrollview的用法pullToRefreshScrollview

PullToRefreshScrollView中没有smoothScrollTo方法;也不能直接使用onScrollChange()方法; 不过这个不难解决,我们可以通过scrollView = mPullRefreshScrollView.getRefreshableView(); 获取被包裹的...
  • xvzhengyang
  • xvzhengyang
  • 2017-03-18 13:31
  • 993

<Android>使用ScrollView 实现 ListView 的下拉刷新

下拉刷新 在当下的移动应用中随处可见, 这种交互模式已经逐渐被广大终端用户接受和习惯。 最近就尝试用利用ScrollView + ListView, 写了一个下拉刷新的demo, 这里介绍一下吧。 首先展示一下已经实现了的效果图。
  • u013015161
  • u013015161
  • 2015-05-13 01:24
  • 1594
    个人资料
    • 访问:837120次
    • 积分:10192
    • 等级:
    • 排名:第2018名
    • 原创:311篇
    • 转载:40篇
    • 译文:10篇
    • 评论:92条
    博客专栏
    文章分类
    最新评论