关闭

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

标签: android
281人阅读 评论(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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:648503次
    • 积分:8946
    • 等级:
    • 排名:第2338名
    • 原创:307篇
    • 转载:40篇
    • 译文:10篇
    • 评论:79条
    博客专栏
    文章分类
    最新评论