zoukankan      html  css  js  c++  java
  • 开源项目PullToRefresh详解(一)——PullToRefreshListView

      

    开源项地址:https://github.com/chrisbanes/Android-PullToRefresh

    下拉刷新这个功能我们都比较常见了,今天介绍的就是这个功能的实现。我将按照这个开源库的范例来一点一点介绍,今天是介绍比较常见的PullToRefreshListView,是让listView有下拉刷新功能。

    1.下载项目包,将library包导入即可,其他的包暂时不用

    2.分析源码,看我们可以设置的有哪些

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <declare-styleable name="PullToRefresh">
    
            <!-- A drawable to use as the background of the Refreshable View -->
            <!-- 设置刷新view的背景 -->
            <attr name="ptrRefreshableViewBackground" format="reference|color" />
    
            <!-- A drawable to use as the background of the Header and Footer Loading Views -->
            <!-- 设置头部view的背景 -->
            <attr name="ptrHeaderBackground" format="reference|color" />
    
            <!-- Text Color of the Header and Footer Loading Views -->
            <!-- 设置头部/底部文字的颜色 -->
            <attr name="ptrHeaderTextColor" format="reference|color" />
    
            <!-- Text Color of the Header and Footer Loading Views Sub Header -->
            <!-- 设置头部/底部副标题的文字颜色 -->
            <attr name="ptrHeaderSubTextColor" format="reference|color" />
    
            <!-- Mode of Pull-to-Refresh that should be used -->
            <!-- 设置下拉刷新的模式,有多重方式可选。无刷新功能,从顶部刷新,从底部刷新,二者都有,只允许手动刷新 -->
            <attr name="ptrMode">
                <flag name="disabled" value="0x0" />
                <flag name="pullFromStart" value="0x1" />
                <flag name="pullFromEnd" value="0x2" />
                <flag name="both" value="0x3" />
                <flag name="manualOnly" value="0x4" />
    
                <!-- These last two are depreacted -->
                <!-- 这两个属性不推荐了,用上面的代替即可 -->
                <flag name="pullDownFromTop" value="0x1" />
                <flag name="pullUpFromBottom" value="0x2" />
            </attr>
    
            <!-- Whether the Indicator overlay(s) should be used -->
            <!-- 是否显示指示箭头 -->
            <attr name="ptrShowIndicator" format="reference|boolean" />
    
            <!-- Drawable to use as Loading Indicator. Changes both Header and Footer. -->
            <!-- 指示箭头的图片 -->
            <attr name="ptrDrawable" format="reference" />
    
            <!-- Drawable to use as Loading Indicator in the Header View. Overrides value set in ptrDrawable. -->
            <!-- 顶部指示箭头的图片,设置后会覆盖ptrDrawable中顶部的设置 -->
            <attr name="ptrDrawableStart" format="reference" />
    
            <!-- Drawable to use as Loading Indicator in the Fooer View. Overrides value set in ptrDrawable. -->
            <!-- 底部指示箭头的图片,设置后会覆盖ptrDrawable中底部的设置 -->
            <attr name="ptrDrawableEnd" format="reference" />
    
            <!-- Whether Android's built-in Over Scroll should be utilised for Pull-to-Refresh. -->
            <attr name="ptrOverScroll" format="reference|boolean" />
    
            <!-- Base text color, typeface, size, and style for Header and Footer Loading Views -->
            <!-- 设置文字的基本字体 -->
            <attr name="ptrHeaderTextAppearance" format="reference" />
    
            <!-- Base text color, typeface, size, and style for Header and Footer Loading Views Sub Header -->
            <!-- 设置副标题的基本字体 -->
            <attr name="ptrSubHeaderTextAppearance" format="reference" />
    
            <!-- Style of Animation should be used displayed when pulling. -->
            <!-- 设置下拉时标识图的动画,默认为rotate -->
            <attr name="ptrAnimationStyle">
                <flag name="rotate" value="0x0" />
                <flag name="flip" value="0x1" />
            </attr>
    
            <!-- Whether the user can scroll while the View is Refreshing -->
            <!-- 设置刷新时是否允许滚动,一般为true -->
            <attr name="ptrScrollingWhileRefreshingEnabled" format="reference|boolean" />
    
            <!--
                Whether PullToRefreshListView has it's extras enabled. This allows the user to be 
                able to scroll while refreshing, and behaves better. It acheives this by adding
                Header and/or Footer Views to the ListView.
            -->
            <!-- 允许在listview中添加头/尾视图 -->
            <attr name="ptrListViewExtrasEnabled" format="reference|boolean" />
    
            <!--
                Whether the Drawable should be continually rotated as you pull. This only
                takes effect when using the 'Rotate' Animation Style.
            -->
            <!-- 当设置rotate时,可以用这个来设置刷新时旋转的图片 -->
            <attr name="ptrRotateDrawableWhilePulling" format="reference|boolean" />
    
            <!-- BELOW HERE ARE DEPRECEATED. DO NOT USE. -->
            <attr name="ptrAdapterViewBackground" format="reference|color" />
            <attr name="ptrDrawableTop" format="reference" />
            <attr name="ptrDrawableBottom" format="reference" />
        </declare-styleable>
    
    </resources>

    看到有这么多可以设置的属性,别以为真的就可以定制了。真正要定制还得到layout中改变刷新布局

    3.开始用它建立自己的工程

    设置布局文件

    就是插入PullToRefreshListView
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="${relativePackage}.${activityClass}" 
        android:background="#000000">
    
    <!--     The PullToRefreshListView replaces a standard ListView widget. -->
    
        <com.handmark.pulltorefresh.library.PullToRefreshListView
            xmlns:ptr="http://schemas.android.com/apk/res-auto"
            android:id="@+id/pull_refresh_list"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:cacheColorHint="#000000"
            android:divider="#19000000"
            android:dividerHeight="4dp"
            android:fadingEdge="none"
            android:fastScrollEnabled="false"
            android:footerDividersEnabled="false"
            android:headerDividersEnabled="false"
            android:smoothScrollbar="true" 
            ptr:ptrAnimationStyle="rotate"
            ptr:ptrHeaderTextColor="#ffffff"
            ptr:ptrHeaderSubTextColor="#00ffff"
            ptr:ptrHeaderBackground="@null"
            ptr:ptrDrawable="@drawable/ic_launcher"/>
        
    </RelativeLayout>

    开始编写代码

    1.找到这个控件,并且设置监听器

    这里面用到了一个日期的工具类,其实就是设置上次下拉的时间的。此外在下拉后会触发一个异步任务

        /**
         * 设置下拉刷新的listview的动作
         */
        private void initPTRListView() {
            mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);
            //设置拉动监听器
            mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {
    
                @Override
                public void onRefresh(PullToRefreshBase<ListView> refreshView) {
                    //设置下拉时显示的日期和时间
                    String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),
                            DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);
    
                    // 更新显示的label
                    refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);
                    // 开始执行异步任务,传入适配器来进行数据改变
                    new GetDataTask(mPullRefreshListView, mAdapter,mListItems).execute();
                }
            });
    
            // 添加滑动到底部的监听器
            mPullRefreshListView.setOnLastItemVisibleListener(new OnLastItemVisibleListener() {
                
                @Override
                public void onLastItemVisible() {
                    Toast.makeText(getApplication(), "已经到底了", Toast.LENGTH_SHORT).show();
                }
            });
            
            //mPullRefreshListView.isScrollingWhileRefreshingEnabled();//看刷新时是否允许滑动
            //在刷新时允许继续滑动
            mPullRefreshListView.setScrollingWhileRefreshingEnabled(true);
            //mPullRefreshListView.getMode();//得到模式
            //上下都可以刷新的模式。这里有两个选择:Mode.PULL_FROM_START,Mode.BOTH,PULL_FROM_END
            mPullRefreshListView.setMode(Mode.BOTH);
            
            /**
             * 设置反馈音效
             */
            SoundPullEventListener<ListView> soundListener = new SoundPullEventListener<ListView>(this);
            soundListener.addSoundEvent(State.PULL_TO_REFRESH, R.raw.pull_event);
            soundListener.addSoundEvent(State.RESET, R.raw.reset_sound);
            soundListener.addSoundEvent(State.REFRESHING, R.raw.refreshing_sound);
            mPullRefreshListView.setOnPullEventListener(soundListener);
        }

    2.从上面的那个控件中,得到它包含的listView,并且设置适配器

        //普通的listview对象
        private ListView actualListView;
        //添加一个链表数组,来存放string数组,这样就可以动态增加string数组中的内容了
        private LinkedList<String> mListItems;
        //给listview添加一个普通的适配器
        private ArrayAdapter<String> mAdapter;

    这里用到了一个LinkedList的对象,这个是一个类似于ArrayList的链表数组,比较方便在开头和末尾添加String

        /**
         * 设置listview的适配器
         */
        private void initListView() {
            //通过getRefreshableView()来得到一个listview对象
            actualListView = mPullRefreshListView.getRefreshableView();
            
            String []data = new String[] {"android","ios","wp","java","c++","c#"};
            mListItems = new LinkedList<String>();
            //把string数组中的string添加到链表中
            mListItems.addAll(Arrays.asList(data));
            
            mAdapter = new ArrayAdapter<>(getApplicationContext(), 
                    android.R.layout.simple_list_item_1, mListItems);
            actualListView.setAdapter(mAdapter);
        }

    3.写一个异步任务,来模仿从网络加载数据

    这里要注意的是,加载完后要出发刷新完成和通知适配器改变的方法

    package com.kale.ptrlistviewtest;
    
    import java.util.LinkedList;
    
    import android.os.AsyncTask;
    import android.widget.ArrayAdapter;
    
    import com.handmark.pulltorefresh.library.PullToRefreshListView;
    import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
    
    /**
     * @author:Jack Tony
     * @tips  :通过异步任务来加载网络中的数据,进行更新
     * @date  :2014-10-14
     */
    public class GetDataTask extends AsyncTask<Void, Void, Void>{
    
        private PullToRefreshListView mPullRefreshListView;
        private ArrayAdapter<String> mAdapter;
        private LinkedList<String> mListItems;
        
        public GetDataTask(PullToRefreshListView listView,
                ArrayAdapter<String> adapter,LinkedList<String> listItems) {
            // TODO 自动生成的构造函数存根
            mPullRefreshListView = listView;
            mAdapter = adapter;
            mListItems = listItems;
        }
        
        @Override
        protected Void doInBackground(Void... params) {
            //模拟请求
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
            return null;
        }
        
        @Override
        protected void onPostExecute(Void result) {
            // TODO 自动生成的方法存根
            super.onPostExecute(result);
            //得到当前的模式
            Mode mode = mPullRefreshListView.getCurrentMode();
            if(mode == Mode.PULL_FROM_START) {
                mListItems.addFirst("这是刷新出来的数据");
            }
            else {
                mListItems.addLast("这是刷新出来的数据");
            }
            // 通知数据改变了
            mAdapter.notifyDataSetChanged();
            // 加载完成后停止刷新
            mPullRefreshListView.onRefreshComplete();
            
        }
        
    
    
    }

    贴上acitivty中的全部代码

    MainActivity.java

    package com.kale.ptrlistviewtest;
    
    import java.util.Arrays;
    import java.util.LinkedList;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.text.format.DateUtils;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    import android.widget.Toast;
    
    import com.handmark.pulltorefresh.library.PullToRefreshBase;
    import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
    import com.handmark.pulltorefresh.library.PullToRefreshBase.OnLastItemVisibleListener;
    import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;
    import com.handmark.pulltorefresh.library.PullToRefreshBase.State;
    import com.handmark.pulltorefresh.library.PullToRefreshListView;
    import com.handmark.pulltorefresh.library.extras.SoundPullEventListener;
    
    public class MainActivity extends Activity {
        
        //一个可以下拉刷新的listView对象
        private PullToRefreshListView mPullRefreshListView;
        //普通的listview对象
        private ListView actualListView;
        //添加一个链表数组,来存放string数组,这样就可以动态增加string数组中的内容了
        private LinkedList<String> mListItems;
        //给listview添加一个普通的适配器
        private ArrayAdapter<String> mAdapter;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            initView();
    
            //一打开应用就自动刷新,下面语句可以写到刷新按钮里面
            mPullRefreshListView.setRefreshing(true);
            //new GetDataTask(mPullRefreshListView, mAdapter, mListItems).execute();
            //mPullRefreshListView.setRefreshing(false);
    
        }
    
        private void initView() {
            initPTRListView();
            initListView();
        }
        
        /**
         * 设置下拉刷新的listview的动作
         */
        private void initPTRListView() {
            mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);
            //设置拉动监听器
            mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {
    
                @Override
                public void onRefresh(PullToRefreshBase<ListView> refreshView) {
                    //设置下拉时显示的日期和时间
                    String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),
                            DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);
    
                    // 更新显示的label
                    refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);
                    // 开始执行异步任务,传入适配器来进行数据改变
                    new GetDataTask(mPullRefreshListView, mAdapter,mListItems).execute();
                }
            });
    
            // 添加滑动到底部的监听器
            mPullRefreshListView.setOnLastItemVisibleListener(new OnLastItemVisibleListener() {
                
                @Override
                public void onLastItemVisible() {
                    Toast.makeText(getApplication(), "已经到底了", Toast.LENGTH_SHORT).show();
                }
            });
            
            //mPullRefreshListView.isScrollingWhileRefreshingEnabled();//看刷新时是否允许滑动
            //在刷新时允许继续滑动
            mPullRefreshListView.setScrollingWhileRefreshingEnabled(true);
            //mPullRefreshListView.getMode();//得到模式
            //上下都可以刷新的模式。这里有两个选择:Mode.PULL_FROM_START,Mode.BOTH,PULL_FROM_END
            mPullRefreshListView.setMode(Mode.BOTH);
            
            /**
             * 设置反馈音效
             */
            SoundPullEventListener<ListView> soundListener = new SoundPullEventListener<ListView>(this);
            soundListener.addSoundEvent(State.PULL_TO_REFRESH, R.raw.pull_event);
            soundListener.addSoundEvent(State.RESET, R.raw.reset_sound);
            soundListener.addSoundEvent(State.REFRESHING, R.raw.refreshing_sound);
            mPullRefreshListView.setOnPullEventListener(soundListener);
        }
        
        /**
         * 设置listview的适配器
         */
        private void initListView() {
            //通过getRefreshableView()来得到一个listview对象
            actualListView = mPullRefreshListView.getRefreshableView();
            
            String []data = new String[] {"android","ios","wp","java","c++","c#"};
            mListItems = new LinkedList<String>();
            //把string数组中的string添加到链表中
            mListItems.addAll(Arrays.asList(data));
            
            mAdapter = new ArrayAdapter<>(getApplicationContext(), 
                    android.R.layout.simple_list_item_1, mListItems);
            actualListView.setAdapter(mAdapter);
        }
    }

    源码下载:http://download.csdn.net/detail/shark0017/8035465

  • 相关阅读:
    CaltrainTimes从设计到发布(基于Flex的手机应用)
    使用Flex构建Web和移动参考应用程序
    使用Flex4容器若干技巧
    移动设备外观设计的基础知识
    在移动设备应用程序中使用文本的指导原则
    在移动设备应用程序中使用软键盘
    多分辨率适配(下)
    多分辨率适配(上)
    CocosBuilder 多分辨率基础
    【2019-12-31】在逆境中锻炼自己的心态
  • 原文地址:https://www.cnblogs.com/tianzhijiexian/p/4023802.html
Copyright © 2011-2022 走看看