PullToRefresh的个性化扩展

一:实现区别下拉刷新和上拉加载

参考资料:http://blog.csdn.net/losetowin/article/details/18261389

在PullToRefresh的类库的com.handmark.pulltorefresh.library包下,打开PullToRefreshBase.java,在这个类的最后面添加代码。注意,需要重新添加library库。

//根据下拉和上拉显示的布局的可见状态类区分上拉还是下拉,然后执行相应操作
    public boolean isHeaderShown() {
        return getHeaderLayout().isShown();
    }
    
    public boolean isFooterShown() {
        return getFooterLayout().isShown();
    }
View Code

使用方法大概如下:

private boolean isRefreshing = false;//是否正在刷新的标志

private PullToRefreshListView news_list;//列表控件news_list

//设置上拉下拉事件
        news_list.setOnRefreshListener(new OnRefreshListener<ListView>() {

            @Override
            public void onRefresh(PullToRefreshBase<ListView> refreshView) {
                //在PullToRefresh的类库的com.handmark.pulltorefresh.library包下,打开PullToRefreshBase.java,在这个类的最后面添加代码。注意,需要重新添加library库。
                //原理:根据下拉和上拉显示的布局的可见状态类区分上拉还是下拉,然后执行相应操作
                if (!isRefreshing) {
                    
                    isRefreshing = true;
                    
                    if(refreshView.isHeaderShown()){
                        //下拉刷新 业务代码
                        refreshFirstPage();//刷新第一页数据
                    }else if(refreshView.isFooterShown()){
                        //上拉加载 业务代码
                        loadNextPage();//加载下一页内容
                    }
                }else{
                    //一般来说我们会开另一个线程去获取数据,所以这儿会加上一个判断,如果已经在获取数据了,就onRefreshComplete(),就是将下拉收起;否则就去开新线程取数据,取完记得也要onRefreshComplete()哦
                    news_list.onRefreshComplete();
                    isRefreshing = false;
                }
            }
        });
View Code

二:实现下拉刷新、下拉加载的图片个性化(图片居中)
参考资料:http://blog.csdn.net/superjunjin/article/details/45022595

定义刷新动画的layout

根据layout中的pull_to_refresh_header_vertical.xml文件修改成如下(图片居中,文字全部设置为gone。不占用空间)

<?xml version="1.0" encoding="utf-8"?>
<!-- (1)实现下拉刷新、下拉加载的动画个性化(图片居中) -->
<merge xmlns:android="http://schemas.android.com/apk/res/android" >

    <FrameLayout
        android:id="@+id/fl_inner"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="@dimen/header_footer_top_bottom_padding"
        android:paddingLeft="@dimen/header_footer_left_right_padding"
        android:paddingRight="@dimen/header_footer_left_right_padding"
        android:paddingTop="@dimen/header_footer_top_bottom_padding" >

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center" >

            <ImageView
                android:id="@+id/pull_to_refresh_image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center" />
            
            <ProgressBar
                android:id="@+id/pull_to_refresh_progress"
                style="?android:attr/progressBarStyleSmall"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:indeterminate="true"
                android:visibility="gone" />
            
        </FrameLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center_horizontal"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/pull_to_refresh_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:singleLine="true"
                android:textAppearance="?android:attr/textAppearance"
                android:textStyle="bold"
                android:visibility="gone" />

            <TextView
                android:id="@+id/pull_to_refresh_sub_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:singleLine="true"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:visibility="gone" />
        </LinearLayout>
    </FrameLayout>

</merge>
pull_to_refresh_header_custom.xml

设置自定义动画效果

 设置一个简单的京东小人走的动画效果,在drawable文件夹下新建一个xml

<?xml version="1.0" encoding="utf-8"?>
<!-- (2)实现下拉刷新、下拉加载的动画个性化(图片居中) -->
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
    
    <item android:drawable="@drawable/app_refresh_people_0" android:duration="100"></item>
    <item android:drawable="@drawable/app_refresh_people_1" android:duration="100"></item>
    <item android:drawable="@drawable/app_refresh_people_2" android:duration="100"></item>
    <item android:drawable="@drawable/app_refresh_people_3" android:duration="100"></item>
    
</animation-list>
jd_refreshlist.xml

新建刷新动画的layout,TweenAnimLoadingLayout,类似于之前的源码中的FlipLoadingLayout和RotateLoadingLayout

package com.handmark.pulltorefresh.library.internal;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.View;

import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation;
import com.handmark.pulltorefresh.library.R;
/**
 * (3)实现下拉刷新、下拉加载的动画个性化(图片居中)*/
public class TweenAnimLoadingLayout extends LoadingLayout{
    
    private AnimationDrawable animationDrawable;//创建动画序列对象
    

    public TweenAnimLoadingLayout(Context context, Mode mode,
            Orientation scrollDirection, TypedArray attrs) {
        super(context, mode, scrollDirection, attrs);
        // TODO Auto-generated constructor stub
        
        //初始化
        mHeaderImage.setImageResource(R.drawable.jd_refreshlist);
        animationDrawable = (AnimationDrawable) mHeaderImage.getDrawable();
        
        
    }

    // 默认图片 
    protected int getDefaultDrawableResId() {
        // TODO Auto-generated method stub
        return R.drawable.app_refresh_people_0;
    }

    @Override
    protected void onLoadingDrawableSet(Drawable imageDrawable) {
        
    }

    @Override
    protected void onPullImpl(float scaleOfLayout) {
        // TODO Auto-generated method stub
        
    }

     // 下拉以刷新  
    protected void pullToRefreshImpl() {
        // TODO Auto-generated method stub
        
    }

    // 正在刷新时回调  
    protected void refreshingImpl() {
        // 播放帧动画  
        animationDrawable.start();
    }

    // 释放以刷新  
    protected void releaseToRefreshImpl() {
        // TODO Auto-generated method stub
        
    }

    // 重新设置  
    protected void resetImpl() {
         mHeaderImage.setVisibility(View.VISIBLE);  
         mHeaderImage.clearAnimation();  

        
    }

}
TweenAnimLoadingLayout

替换之前的布局文件,在LoadingLayout类的构造函数中修改引用的布局文件:

public LoadingLayout(Context context, final Mode mode, final Orientation scrollDirection, TypedArray attrs) {
        super(context);
        mMode = mode;
        mScrollDirection = scrollDirection;

        switch (scrollDirection) {
            case HORIZONTAL:
                LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_horizontal, this);
                
                break;
            case VERTICAL:
            default:
                //LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_vertical, this);
                
                /*(4)实现下拉刷新、下拉加载的动画个性化(图片居中)*/
                LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_custom, this);
                break;
        }
LoadingLayout

替换之前的刷新layout为TweenAnimLoadingLayout

找到library项目com.handmark.pulltorefresh.library包下的PullToRefreshListView的createLoadingLayout进入,在createLoadingLayout方法中再进入createLoadingLayout,找到最原始的新建动画layout的地方,把默认的RotateLoadingLayout改成TweenAnimLoadingLayout就行了。在PullToRefreshBase类下

LoadingLayout createLoadingLayout(Context context, Mode mode, Orientation scrollDirection, TypedArray attrs) {
            switch (this) {
                case ROTATE:
                default:
                    //return new RotateLoadingLayout(context, mode, scrollDirection, attrs);
                    /*(5)实现下拉刷新、下拉加载的动画个性化(图片居中)*/
                    return new TweenAnimLoadingLayout(context, mode, scrollDirection, attrs);
                case FLIP:
                    return new FlipLoadingLayout(context, mode, scrollDirection, attrs);
            }
        }
PullToRefreshBase

三:实现下拉刷新、下拉加载的动画自定义

1、需要将项目中用到的动画文件和图片资源复制一份到library工程中。

2、主要修改RotateLoadingLayout文件

/*******************************************************************************
 * Copyright 2011, 2012 Chris Banes.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.handmark.pulltorefresh.library.internal;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Matrix;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView.ScaleType;

import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation;
import com.handmark.pulltorefresh.library.R;

public class RotateLoadingLayout extends LoadingLayout {

    static final int ROTATION_ANIMATION_DURATION = 1200;

    private final Animation mRotateAnimation;
    private final Matrix mHeaderImageMatrix;

    private float mRotationPivotX, mRotationPivotY;

    private final boolean mRotateDrawableWhilePulling;
    
    /*(1)实现自定义加载动画*/
    private boolean mUseIntrinsicAnimation;//标记传入的drawable是否是AnimationDrawable
    private AnimationDrawable animationDrawable;//创建动画序列对象

    public RotateLoadingLayout(Context context, Mode mode, Orientation scrollDirection, TypedArray attrs) {
        super(context, mode, scrollDirection, attrs);

        mRotateDrawableWhilePulling = attrs.getBoolean(R.styleable.PullToRefresh_ptrRotateDrawableWhilePulling, true);

        mHeaderImage.setScaleType(ScaleType.MATRIX);
        mHeaderImageMatrix = new Matrix();
        mHeaderImage.setImageMatrix(mHeaderImageMatrix);

        mRotateAnimation = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        mRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR);
        mRotateAnimation.setDuration(ROTATION_ANIMATION_DURATION);
        mRotateAnimation.setRepeatCount(Animation.INFINITE);
        mRotateAnimation.setRepeatMode(Animation.RESTART);
    }

    public void onLoadingDrawableSet(Drawable imageDrawable) {
        
        /*(2)实现自定义加载动画*/
        //如果传进来的是动画,那么
        if(imageDrawable instanceof AnimationDrawable){
            
            mUseIntrinsicAnimation = true;//设置标记值为true
            mHeaderImage.setImageResource(R.drawable.jd_refreshlist);//给图标引用想用的动画(此处需要保证项目中用到的动画文件和图片资源复制一份到library中)
            animationDrawable = (AnimationDrawable) imageDrawable;
        }
        else{
            if (null != imageDrawable) {
                mRotationPivotX = Math.round(imageDrawable.getIntrinsicWidth() / 2f);
                mRotationPivotY = Math.round(imageDrawable.getIntrinsicHeight() / 2f);
            }
        }
        
    }

    protected void onPullImpl(float scaleOfLayout) {
        /*(2)实现自定义加载动画*/
        //如果传进来的是动画,那么
        if(mUseIntrinsicAnimation){
            
        }else{
            float angle;
            if (mRotateDrawableWhilePulling) {
                angle = scaleOfLayout * 90f;
            } else {
                angle = Math.max(0f, Math.min(180f, scaleOfLayout * 360f - 180f));
            }

            mHeaderImageMatrix.setRotate(angle, mRotationPivotX, mRotationPivotY);
            mHeaderImage.setImageMatrix(mHeaderImageMatrix);
        }
        
        
    }

    // 正在刷新时回调 
    protected void refreshingImpl() {
         
        /*(2)实现自定义加载动画*/
        //如果传进来的是动画,那么
        if(mUseIntrinsicAnimation){
            animationDrawable.start();// 播放帧动画
        }else{
            mHeaderImage.startAnimation(mRotateAnimation);// 播放帧动画
        }
        
    }

     // 重新设置
    protected void resetImpl() {
        /*(2)实现自定义加载动画*/
        //如果传进来的是动画,那么
        if(mUseIntrinsicAnimation){
            mHeaderImage.setVisibility(View.VISIBLE);  
            mHeaderImage.clearAnimation();  
        }else{
            mHeaderImage.clearAnimation();
            resetImageRotation();
        }
        
        
    }

    private void resetImageRotation() {
        /*(2)实现自定义加载动画*/
        //如果传进来的是动画,那么
        if(mUseIntrinsicAnimation){
            
        }else{
            if (null != mHeaderImageMatrix) {
                mHeaderImageMatrix.reset();
                mHeaderImage.setImageMatrix(mHeaderImageMatrix);
            }
        }
        
        
    }

    // 下拉以刷新  
    protected void pullToRefreshImpl() {
        // NO-OP
    }

     // 释放以刷新  
    protected void releaseToRefreshImpl() {
        // NO-OP
    }

    // 默认图片 
    protected int getDefaultDrawableResId() {
        /*(2)实现自定义加载动画*/
        //如果传进来的是动画,那么
        if(mUseIntrinsicAnimation){
            return R.drawable.app_refresh_people_0;
        }else{
            return R.drawable.default_ptr_rotate;
        }
        
    }

}
RotateLoadingLayout

3、使用方法

//额外的设置:设置下拉刷新和上拉加载的图片和文字,背景颜色等
    private void setPullToRefreshAttribute(){
        
        ILoadingLayout startLabels = news_list.getLoadingLayoutProxy(true, false);
        startLabels.setPullLabel("下拉刷新...");// 刚下拉时,显示的提示
        startLabels.setReleaseLabel("松开刷新...");//下来达到一定距离时,显示的提示
        startLabels.setRefreshingLabel("正在刷新...");// 刷新时
        
        /*(3)实现自定义加载动画*/
        //设置加载动画图标:方式一
        AnimationDrawable jdAnimation = (AnimationDrawable) getResources().getDrawable(R.drawable.jd_refreshlist);
        startLabels.setLoadingDrawable(jdAnimation);
        
        
        ILoadingLayout endLabels = news_list.getLoadingLayoutProxy(false, true);
        endLabels.setPullLabel("上拉加载...");// 刚下拉时,显示的提示
        endLabels.setReleaseLabel("松开加载...");//下来达到一定距离时,显示的提示
        endLabels.setRefreshingLabel("正在加载...");// 刷新时
        /*(3)实现自定义加载动画*/
        //设置加载动画图标:方式二
        Drawable drawable2 = (Drawable) getResources().getDrawable(R.drawable.progressbar1);
        endLabels.setLoadingDrawable(drawable2);
    }
View Code

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值