Android View 下拉上拉刷新 适合各种控件

来源:互联网 发布:手机淘宝如何上架宝贝 编辑:程序博客网 时间:2024/05/21 04:00
package com.example.xrefreshview;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.Window;import android.view.WindowManager;// Demo 下载地址   http://download.csdn.net/detail/u014540181/9587980//android  View 下拉上拉刷新  适合各种控件//http://blog.csdn.net/u014540181   关注我的博客,相互交流,学习,进步,祝你生活工作愉快//2016-07-27  19:45public class MainActivity extends Activity {    private MeasureListView list_v;    private ScrollViewAdapter  adapter;    private List<String> list;    private Context mContext;    @Override    protected void onCreate(Bundle savedInstanceState) {        requestWindowFeature(Window.FEATURE_NO_TITLE);        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mContext = this;        list = new ArrayList<String>();        for (int i = 0; i < 5; i++) {            list.add("=="+i);        }        adapter = new ScrollViewAdapter(mContext, list);        list_v = (MeasureListView) findViewById(R.id.list_v);        list_v.setAdapter(adapter);        ((PullToRefreshLayout) findViewById(R.id.refresh_view))        .setOnRefreshListener(new MyListener());    }}
// MainActivity 的布局文件<com.example.xrefreshview.PullToRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/refresh_view"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <include layout="@layout/refresh_head" />    <!-- 支持所有实现Pullable接口的View -->    <com.example.xrefreshview.PullableScrollView        android:layout_width="match_parent"        android:layout_height="match_parent" >        <RelativeLayout            android:layout_width="wrap_content"            android:layout_height="wrap_content" >            <com.example.xrefreshview.MeasureListView                android:id="@+id/list_v"        android:layout_width="match_parent"        android:layout_height="match_parent"         android:layout_alignParentTop="true"        />            <LinearLayout                android:id="@+id/imagesLayout"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:gravity="center_horizontal"                android:orientation="vertical"                android:layout_below="@id/list_v"                 >                <ImageView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:background="@drawable/photo_test" />                <ImageView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:background="@drawable/photo_test" />                <ImageView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:background="@drawable/photo_test" />                <ImageView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:background="@drawable/photo_test" />                <ImageView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:background="@drawable/photo_test" />                <ImageView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:background="@drawable/photo_test" />            </LinearLayout>        </RelativeLayout>    </com.example.xrefreshview.PullableScrollView>    <include layout="@layout/load_more" /></com.example.xrefreshview.PullToRefreshLayout>
package com.example.xrefreshview;import java.util.Timer;import java.util.TimerTask;import android.content.Context;import android.graphics.Canvas;import android.graphics.LinearGradient;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.RectF;import android.graphics.Shader.TileMode;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.animation.AnimationUtils;import android.view.animation.LinearInterpolator;import android.view.animation.RotateAnimation;import android.widget.RelativeLayout;import android.widget.TextView;/** * 自定义的布局,用来管理三个子控件,其中一个是下拉头,一个是包含内容的pullableView(可以是实现Pullable接口的的任何View), * 还有一个上拉头,更多详解见博客http://blog.csdn.net/zhongkejingwang/article/details/38868463 *  * @author 陈靖 */public class PullToRefreshLayout extends RelativeLayout{    public static final String TAG = "PullToRefreshLayout";    // 初始状态    public static final int INIT = 0;    // 释放刷新    public static final int RELEASE_TO_REFRESH = 1;    // 正在刷新    public static final int REFRESHING = 2;    // 释放加载    public static final int RELEASE_TO_LOAD = 3;    // 正在加载    public static final int LOADING = 4;    // 操作完毕    public static final int DONE = 5;    // 当前状态    private int state = INIT;    // 刷新回调接口    private OnRefreshListener mListener;    // 刷新成功    public static final int SUCCEED = 0;    // 刷新失败    public static final int FAIL = 1;    // 按下Y坐标,上一个事件点Y坐标    private float downY, lastY;    // 下拉的距离。注意:pullDownY和pullUpY不可能同时不为0    public float pullDownY = 0;    // 上拉的距离    private float pullUpY = 0;    // 释放刷新的距离    private float refreshDist = 200;    // 释放加载的距离    private float loadmoreDist = 200;    private MyTimer timer;    // 回滚速度    public float MOVE_SPEED = 8;    // 第一次执行布局    private boolean isLayout = false;    // 在刷新过程中滑动操作    private boolean isTouch = false;    // 手指滑动距离与下拉头的滑动距离比,中间会随正切函数变化    private float radio = 2;    // 下拉箭头的转180°动画    private RotateAnimation rotateAnimation;    // 均匀旋转动画    private RotateAnimation refreshingAnimation;    // 下拉头    private View refreshView;    // 下拉的箭头    private View pullView;    // 正在刷新的图标    private View refreshingView;    // 刷新结果图标    private View refreshStateImageView;    // 刷新结果:成功或失败    private TextView refreshStateTextView;    // 上拉头    private View loadmoreView;    // 上拉的箭头    private View pullUpView;    // 正在加载的图标    private View loadingView;    // 加载结果图标    private View loadStateImageView;    // 加载结果:成功或失败    private TextView loadStateTextView;    // 实现了Pullable接口的View    private View pullableView;    // 过滤多点触碰    private int mEvents;    // 这两个变量用来控制pull的方向,如果不加控制,当情况满足可上拉又可下拉时没法下拉    private boolean canPullDown = true;    private boolean canPullUp = true;    /**     * 执行自动回滚的handler     */    Handler updateHandler = new Handler()    {        @Override        public void handleMessage(Message msg)        {            // 回弹速度随下拉距离moveDeltaY增大而增大            MOVE_SPEED = (float) (8 + 5 * Math.tan(Math.PI / 2                    / getMeasuredHeight() * (pullDownY + Math.abs(pullUpY))));            if (!isTouch)            {                // 正在刷新,且没有往上推的话则悬停,显示"正在刷新..."                if (state == REFRESHING && pullDownY <= refreshDist)                {                    pullDownY = refreshDist;                    timer.cancel();                } else if (state == LOADING && -pullUpY <= loadmoreDist)                {                    pullUpY = -loadmoreDist;                    timer.cancel();                }            }            if (pullDownY > 0)                pullDownY -= MOVE_SPEED;            else if (pullUpY < 0)                pullUpY += MOVE_SPEED;            if (pullDownY < 0)            {                // 已完成回弹                pullDownY = 0;                pullView.clearAnimation();                // 隐藏下拉头时有可能还在刷新,只有当前状态不是正在刷新时才改变状态                if (state != REFRESHING && state != LOADING)                    changeState(INIT);                timer.cancel();            }            if (pullUpY > 0)            {                // 已完成回弹                pullUpY = 0;                pullUpView.clearAnimation();                // 隐藏下拉头时有可能还在刷新,只有当前状态不是正在刷新时才改变状态                if (state != REFRESHING && state != LOADING)                    changeState(INIT);                timer.cancel();            }            // 刷新布局,会自动调用onLayout            requestLayout();        }    };    public void setOnRefreshListener(OnRefreshListener listener)    {        mListener = listener;    }    public PullToRefreshLayout(Context context)    {        super(context);        initView(context);    }    public PullToRefreshLayout(Context context, AttributeSet attrs)    {        super(context, attrs);        initView(context);    }    public PullToRefreshLayout(Context context, AttributeSet attrs, int defStyle)    {        super(context, attrs, defStyle);        initView(context);    }    private void initView(Context context)    {        timer = new MyTimer(updateHandler);        rotateAnimation = (RotateAnimation) AnimationUtils.loadAnimation(                context, R.anim.reverse_anim);        refreshingAnimation = (RotateAnimation) AnimationUtils.loadAnimation(                context, R.anim.rotating);        // 添加匀速转动动画        LinearInterpolator lir = new LinearInterpolator();        rotateAnimation.setInterpolator(lir);        refreshingAnimation.setInterpolator(lir);    }    private void hide()    {        timer.schedule(5);    }    /**     * 完成刷新操作,显示刷新结果。注意:刷新完成后一定要调用这个方法     */    /**     * @param refreshResult     *            PullToRefreshLayout.SUCCEED代表成功,PullToRefreshLayout.FAIL代表失败     */    public void refreshFinish(int refreshResult)    {        refreshingView.clearAnimation();        refreshingView.setVisibility(View.GONE);        switch (refreshResult)        {        case SUCCEED:            // 刷新成功            refreshStateImageView.setVisibility(View.VISIBLE);            refreshStateTextView.setText(R.string.refresh_succeed);            refreshStateImageView                    .setBackgroundResource(R.drawable.refresh_succeed);            break;        case FAIL:        default:            // 刷新失败            refreshStateImageView.setVisibility(View.VISIBLE);            refreshStateTextView.setText(R.string.refresh_fail);            refreshStateImageView                    .setBackgroundResource(R.drawable.refresh_failed);            break;        }        // 刷新结果停留1秒        new Handler()        {            @Override            public void handleMessage(Message msg)            {                changeState(DONE);                hide();            }        }.sendEmptyMessageDelayed(0, 1000);    }    /**     * 加载完毕,显示加载结果。注意:加载完成后一定要调用这个方法     *      * @param refreshResult     *            PullToRefreshLayout.SUCCEED代表成功,PullToRefreshLayout.FAIL代表失败     */    public void loadmoreFinish(int refreshResult)    {        loadingView.clearAnimation();        loadingView.setVisibility(View.GONE);        switch (refreshResult)        {        case SUCCEED:            // 加载成功            loadStateImageView.setVisibility(View.VISIBLE);            loadStateTextView.setText(R.string.load_succeed);            loadStateImageView.setBackgroundResource(R.drawable.load_succeed);            break;        case FAIL:        default:            // 加载失败            loadStateImageView.setVisibility(View.VISIBLE);            loadStateTextView.setText(R.string.load_fail);            loadStateImageView.setBackgroundResource(R.drawable.load_failed);            break;        }        // 刷新结果停留1秒        new Handler()        {            @Override            public void handleMessage(Message msg)            {                changeState(DONE);                hide();            }        }.sendEmptyMessageDelayed(0, 1000);    }    private void changeState(int to)    {        state = to;        switch (state)        {        case INIT:            // 下拉布局初始状态            refreshStateImageView.setVisibility(View.GONE);            refreshStateTextView.setText(R.string.pull_to_refresh);            pullView.clearAnimation();            pullView.setVisibility(View.VISIBLE);            // 上拉布局初始状态            loadStateImageView.setVisibility(View.GONE);            loadStateTextView.setText(R.string.pullup_to_load);            pullUpView.clearAnimation();            pullUpView.setVisibility(View.VISIBLE);            break;        case RELEASE_TO_REFRESH:            // 释放刷新状态            refreshStateTextView.setText(R.string.release_to_refresh);            pullView.startAnimation(rotateAnimation);            break;        case REFRESHING:            // 正在刷新状态            pullView.clearAnimation();            refreshingView.setVisibility(View.VISIBLE);            pullView.setVisibility(View.INVISIBLE);            refreshingView.startAnimation(refreshingAnimation);            refreshStateTextView.setText(R.string.refreshing);            break;        case RELEASE_TO_LOAD:            // 释放加载状态            loadStateTextView.setText(R.string.release_to_load);            pullUpView.startAnimation(rotateAnimation);            break;        case LOADING:            // 正在加载状态            pullUpView.clearAnimation();            loadingView.setVisibility(View.VISIBLE);            pullUpView.setVisibility(View.INVISIBLE);            loadingView.startAnimation(refreshingAnimation);            loadStateTextView.setText(R.string.loading);            break;        case DONE:            // 刷新或加载完毕,啥都不做            break;        }    }    /**     * 不限制上拉或下拉     */    private void releasePull()    {        canPullDown = true;        canPullUp = true;    }    /*     * (非 Javadoc)由父控件决定是否分发事件,防止事件冲突     *      * @see android.view.ViewGroup#dispatchTouchEvent(android.view.MotionEvent)     */    @Override    public boolean dispatchTouchEvent(MotionEvent ev)    {        switch (ev.getActionMasked())        {        case MotionEvent.ACTION_DOWN:            downY = ev.getY();            lastY = downY;            timer.cancel();            mEvents = 0;            releasePull();            break;        case MotionEvent.ACTION_POINTER_DOWN:        case MotionEvent.ACTION_POINTER_UP:            // 过滤多点触碰            mEvents = -1;            break;        case MotionEvent.ACTION_MOVE:            if (mEvents == 0)            {                if (((Pullable) pullableView).canPullDown() && canPullDown                        && state != LOADING)                {                    // 可以下拉,正在加载时不能下拉                    // 对实际滑动距离做缩小,造成用力拉的感觉                    pullDownY = pullDownY + (ev.getY() - lastY) / radio;                    if (pullDownY < 0)                    {                        pullDownY = 0;                        canPullDown = false;                        canPullUp = true;                    }                    if (pullDownY > getMeasuredHeight())                        pullDownY = getMeasuredHeight();                    if (state == REFRESHING)                    {                        // 正在刷新的时候触摸移动                        isTouch = true;                    }                } else if (((Pullable) pullableView).canPullUp() && canPullUp                        && state != REFRESHING)                {                    // 可以上拉,正在刷新时不能上拉                    pullUpY = pullUpY + (ev.getY() - lastY) / radio;                    if (pullUpY > 0)                    {                        pullUpY = 0;                        canPullDown = true;                        canPullUp = false;                    }                    if (pullUpY < -getMeasuredHeight())                        pullUpY = -getMeasuredHeight();                    if (state == LOADING)                    {                        // 正在加载的时候触摸移动                        isTouch = true;                    }                } else                    releasePull();            } else                mEvents = 0;            lastY = ev.getY();            // 根据下拉距离改变比例            radio = (float) (2 + 2 * Math.tan(Math.PI / 2 / getMeasuredHeight()                    * (pullDownY + Math.abs(pullUpY))));            requestLayout();            if (pullDownY <= refreshDist && state == RELEASE_TO_REFRESH)            {                // 如果下拉距离没达到刷新的距离且当前状态是释放刷新,改变状态为下拉刷新                changeState(INIT);            }            if (pullDownY >= refreshDist && state == INIT)            {                // 如果下拉距离达到刷新的距离且当前状态是初始状态刷新,改变状态为释放刷新                changeState(RELEASE_TO_REFRESH);            }            // 下面是判断上拉加载的,同上,注意pullUpY是负值            if (-pullUpY <= loadmoreDist && state == RELEASE_TO_LOAD)            {                changeState(INIT);            }            if (-pullUpY >= loadmoreDist && state == INIT)            {                changeState(RELEASE_TO_LOAD);            }            // 因为刷新和加载操作不能同时进行,所以pullDownY和pullUpY不会同时不为0,因此这里用(pullDownY +            // Math.abs(pullUpY))就可以不对当前状态作区分了            if ((pullDownY + Math.abs(pullUpY)) > 8)            {                // 防止下拉过程中误触发长按事件和点击事件                ev.setAction(MotionEvent.ACTION_CANCEL);            }            break;        case MotionEvent.ACTION_UP:            if (pullDownY > refreshDist || -pullUpY > loadmoreDist)                // 正在刷新时往下拉(正在加载时往上拉),释放后下拉头(上拉头)不隐藏                isTouch = false;            if (state == RELEASE_TO_REFRESH)            {                changeState(REFRESHING);                // 刷新操作                if (mListener != null)                    mListener.onRefresh(this);            } else if (state == RELEASE_TO_LOAD)            {                changeState(LOADING);                // 加载操作                if (mListener != null)                    mListener.onLoadMore(this);            }            hide();        default:            break;        }        // 事件分发交给父类        super.dispatchTouchEvent(ev);        return true;    }    private void initView()    {        // 初始化下拉布局        pullView = refreshView.findViewById(R.id.pull_icon);        refreshStateTextView = (TextView) refreshView                .findViewById(R.id.state_tv);        refreshingView = refreshView.findViewById(R.id.refreshing_icon);        refreshStateImageView = refreshView.findViewById(R.id.state_iv);        // 初始化上拉布局        pullUpView = loadmoreView.findViewById(R.id.pullup_icon);        loadStateTextView = (TextView) loadmoreView                .findViewById(R.id.loadstate_tv);        loadingView = loadmoreView.findViewById(R.id.loading_icon);        loadStateImageView = loadmoreView.findViewById(R.id.loadstate_iv);    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b)    {        if (!isLayout)        {            // 这里是第一次进来的时候做一些初始化            refreshView = getChildAt(0);            pullableView = getChildAt(1);            loadmoreView = getChildAt(2);            isLayout = true;            initView();            refreshDist = ((ViewGroup) refreshView).getChildAt(0)                    .getMeasuredHeight();            loadmoreDist = ((ViewGroup) loadmoreView).getChildAt(0)                    .getMeasuredHeight();        }        // 改变子控件的布局,这里直接用(pullDownY + pullUpY)作为偏移量,这样就可以不对当前状态作区分        refreshView.layout(0,                (int) (pullDownY + pullUpY) - refreshView.getMeasuredHeight(),                refreshView.getMeasuredWidth(), (int) (pullDownY + pullUpY));        pullableView.layout(0, (int) (pullDownY + pullUpY),                pullableView.getMeasuredWidth(), (int) (pullDownY + pullUpY)                        + pullableView.getMeasuredHeight());        loadmoreView.layout(0,                (int) (pullDownY + pullUpY) + pullableView.getMeasuredHeight(),                loadmoreView.getMeasuredWidth(),                (int) (pullDownY + pullUpY) + pullableView.getMeasuredHeight()                        + loadmoreView.getMeasuredHeight());    }    class MyTimer    {        private Handler handler;        private Timer timer;        private MyTask mTask;        public MyTimer(Handler handler)        {            this.handler = handler;            timer = new Timer();        }        public void schedule(long period)        {            if (mTask != null)            {                mTask.cancel();                mTask = null;            }            mTask = new MyTask(handler);            timer.schedule(mTask, 0, period);        }        public void cancel()        {            if (mTask != null)            {                mTask.cancel();                mTask = null;            }        }        class MyTask extends TimerTask        {            private Handler handler;            public MyTask(Handler handler)            {                this.handler = handler;            }            @Override            public void run()            {                handler.obtainMessage().sendToTarget();            }        }    }    /**     * 刷新加载回调接口     *      * @author chenjing     *      */    public interface OnRefreshListener    {        /**         * 刷新操作         */        void onRefresh(PullToRefreshLayout pullToRefreshLayout);        /**         * 加载操作         */        void onLoadMore(PullToRefreshLayout pullToRefreshLayout);    }}
package com.example.xrefreshview;import android.content.Context;import android.util.AttributeSet;import android.widget.ScrollView;public class PullableScrollView extends ScrollView implements Pullable{    public PullableScrollView(Context context)    {        super(context);    }    public PullableScrollView(Context context, AttributeSet attrs)    {        super(context, attrs);    }    public PullableScrollView(Context context, AttributeSet attrs, int defStyle)    {        super(context, attrs, defStyle);    }    public boolean canPullDown()    {        if (getScrollY() == 0)            return true;        else            return false;    }    public boolean canPullUp()    {        if (getScrollY() >= (getChildAt(0).getHeight() - getMeasuredHeight()))            return true;        else            return false;    }}
package com.example.xrefreshview;import android.content.Context;import android.util.AttributeSet;import android.widget.ListView;/** * 测量高度listview * @ClassName: MeasureListView  * @Description: TODO  * @author Comsys-Administrator  * @date 2015-6-7 下午6:31:36 * 要是 ListView 放在 ScrollView 里面使用,就这样写 */public class MeasureListView extends ListView {    public MeasureListView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle); // TODO Auto-generated constructor stub    }    public MeasureListView(Context context, AttributeSet attrs) {        super(context, attrs); // TODO Auto-generated constructor stub    }    public MeasureListView(Context context) {        super(context); // TODO Auto-generated constructor stub    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int hSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,                MeasureSpec.AT_MOST);        super.onMeasure(widthMeasureSpec, hSpec);    }}
package com.example.xrefreshview;public interface Pullable{    /**     * 判断是否可以下拉,如果不需要下拉功能可以直接return false     *      * @return true如果可以下拉否则返回false     */    boolean canPullDown();    /**     * 判断是否可以上拉,如果不需要上拉功能可以直接return false     *      * @return true如果可以上拉否则返回false     */    boolean canPullUp();}
package com.example.xrefreshview;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;public class ScrollViewAdapter extends BaseAdapter{    private LayoutInflater layoutInflater;    private Context mContext;    private List<String> list;    private ViewHolder viewHolder;    public ScrollViewAdapter(Context mContext,List<String> list){        this.mContext = mContext;        this.layoutInflater = LayoutInflater.from(mContext);        this.list = list;    }    @Override    public int getCount() {        return list.size();    }    @Override    public Object getItem(int position) {        return list.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        if(convertView == null){            viewHolder = new ViewHolder();            convertView = layoutInflater.inflate(R.layout.item_adapter, null);            viewHolder.itemTv = (TextView) convertView.findViewById(R.id.tex_m);             convertView.setTag(viewHolder);         }else{             viewHolder = (ViewHolder) convertView.getTag();         }        viewHolder.itemTv.setText(list.get(position));        return convertView;    }    class ViewHolder{        TextView itemTv;    }}
//  ScrollViewAdapter 的布局文件<?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" >    <TextView         android:layout_width="match_parent"        android:layout_height="40dp"        android:id="@+id/tex_m"        android:layout_marginLeft="50dp"        /></LinearLayout>
package com.example.xrefreshview;import com.example.xrefreshview.PullToRefreshLayout.OnRefreshListener;import android.os.Handler;import android.os.Message;public class MyListener implements OnRefreshListener{    public void onRefresh(final PullToRefreshLayout pullToRefreshLayout)    {        // 下拉刷新操作        new Handler()        {            @Override            public void handleMessage(Message msg)            {                // 千万别忘了告诉控件刷新完毕了哦!                pullToRefreshLayout.refreshFinish(PullToRefreshLayout.SUCCEED);            }        }.sendEmptyMessageDelayed(0, 5000);    }    public void onLoadMore(final PullToRefreshLayout pullToRefreshLayout)    {        // 加载操作        new Handler()        {            @Override            public void handleMessage(Message msg)            {                // 千万别忘了告诉控件加载完毕了哦!                pullToRefreshLayout.loadmoreFinish(PullToRefreshLayout.SUCCEED);            }        }.sendEmptyMessageDelayed(0, 5000);    }}
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/loadmore_view"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@color/gray" >    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:paddingBottom="20dp"        android:paddingTop="20dp" >        <RelativeLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_centerInParent="true" >            <ImageView                android:id="@+id/pullup_icon"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_centerVertical="true"                android:layout_marginLeft="60dp"                android:background="@drawable/pullup_icon_big" />            <ImageView                android:id="@+id/loading_icon"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_centerVertical="true"                android:layout_marginLeft="60dp"                android:background="@drawable/loading"                android:visibility="gone" />            <TextView                android:id="@+id/loadstate_tv"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_centerInParent="true"                android:text="@string/pullup_to_load"                android:textColor="@color/black"                android:textSize="16sp" />            <ImageView                android:id="@+id/loadstate_iv"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_centerVertical="true"                android:layout_marginRight="8dp"                android:layout_toLeftOf="@id/loadstate_tv"                android:visibility="gone" />        </RelativeLayout>    </RelativeLayout></RelativeLayout>
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/head_view"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@color/light_blue" >    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:paddingBottom="20dp"        android:paddingTop="20dp" >        <RelativeLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_centerInParent="true" >            <ImageView                android:id="@+id/pull_icon"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_centerVertical="true"                android:layout_marginLeft="60dp"                android:background="@drawable/pull_icon_big" />            <ImageView                android:id="@+id/refreshing_icon"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_centerVertical="true"                android:layout_marginLeft="60dp"                android:background="@drawable/refreshing"                android:visibility="gone" />            <TextView                android:id="@+id/state_tv"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_centerInParent="true"                android:text="@string/pull_to_refresh"                android:textColor="@color/white"                android:textSize="16sp" />            <ImageView                android:id="@+id/state_iv"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_centerVertical="true"                android:layout_marginRight="8dp"                android:layout_toLeftOf="@id/state_tv"                android:visibility="gone" />        </RelativeLayout>    </RelativeLayout></RelativeLayout>
  // 在res下面建个 anim  文件夹  把这个文件放进去<?xml version="1.0" encoding="utf-8"?><rotate xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="100"    android:fillAfter="true"    android:fromDegrees="0"    android:pivotX="50%"    android:pivotY="50%"    android:repeatCount="0"    android:toDegrees="180" ></rotate>
// 在res下面建个 anim  文件夹  把这个文件放进去<?xml version="1.0" encoding="utf-8"?><rotate xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="1500"    android:fillAfter="true"    android:fromDegrees="0"    android:pivotX="50%"    android:pivotY="50%"    android:repeatCount="-1"    android:toDegrees="360" ></rotate>
<?xml version="1.0" encoding="utf-8"?><resources>    <string name="app_name">通用版下拉刷新上拉加载控件</string>    <string name="head">这里是HeadView</string>    <string name="pull_to_refresh">下拉刷新</string>    <string name="release_to_refresh">释放立即刷新</string>    <string name="refreshing">正在刷新...</string>    <string name="refresh_succeed">刷新成功</string>    <string name="refresh_fail">刷新失败</string>    <string name="pullup_to_load">上拉加载更多</string>    <string name="release_to_load">释放立即加载</string>    <string name="loading">正在加载...</string>    <string name="load_succeed">加载成功</string>    <string name="load_fail">加载失败</string></resources>
<?xml version="1.0" encoding="utf-8"?><resources>    <color name="white">#FFFFFF</color>    <color name="black">#000000</color>    <color name="gray">#aaaaaa</color>    <color name="light_blue">#6593cb</color></resources>

// Demo 下载地址 http://download.csdn.net/detail/u014540181/9587980

0 0
原创粉丝点击