上拉刷新、下拉加载

来源:互联网 发布:巨人网络现在怎么样 编辑:程序博客网 时间:2024/06/07 14:17

思路:
listView来做

效果图:

mainActivity

package com.maker_huige.myapplication;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.view.ViewGroup;import android.view.Window;import android.widget.BaseAdapter;import android.widget.TextView;import com.maker_huige.ui.RejectListView;import java.util.ArrayList;public class MainActivity extends AppCompatActivity {    RejectListView rl;    ArrayList<String> strings;    MyAdapter adapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_main);        initUI();        rl.setRejectListener(new RejectListView.OnRejectListener(){            @Override            public void onReject() {                new Thread(){                    @Override                    public void run() {                        try {                            Thread.sleep(200);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                        strings.add(0,"我是下拉出来的数据");                        runOnUiThread(new Runnable() {                            @Override                            public void run() {                                adapter.notifyDataSetChanged();                                rl.onRejectComplete();//刷新结束,恢复界面效果                            }                        });                    }                }.start();            }            @Override            public void onLoadMore() {                new Thread(){                    @Override                    public void run() {                        try {                            Thread.sleep(200);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                        strings.add("我是加载更多出来的数据");                        runOnUiThread(new Runnable() {                            @Override                            public void run() {                                adapter.notifyDataSetChanged();                                rl.onRejectComplete();//刷新结束,恢复界面效果                            }                        });                    }                }.start();            }        });        adapter = new MyAdapter();        rl.setAdapter(adapter);    }    private void initUI() {        rl = (RejectListView) findViewById(R.id.listview);        strings = new ArrayList<String>();        for(int i = 0; i< 30; i++){            strings.add("这是一个listView" + i);        }    }    class MyAdapter extends BaseAdapter{        @Override        public int getCount() {            return strings.size();        }        @Override        public View getView(int i, View view, ViewGroup viewGroup) {            TextView textView = new TextView(getApplicationContext());            textView.setText(getItem(i));            textView.setTextSize(26f);            return textView;        }        @Override        public String getItem(int i) {            return strings.get(i);        }        @Override        public long getItemId(int i) {            return i;        }    }}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.maker_huige.myapplication.MainActivity">    <com.maker_huige.ui.RejectListView        android:id="@+id/listview"        android:layout_width="match_parent"        android:layout_height="match_parent">    </com.maker_huige.ui.RejectListView></LinearLayout>

RejectListView

package com.maker_huige.ui;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.animation.Animation;import android.view.animation.RotateAnimation;import android.widget.AbsListView;import android.widget.ImageView;import android.widget.ListView;import android.widget.ProgressBar;import android.widget.TextView;import com.maker_huige.myapplication.R;import java.text.SimpleDateFormat;public class RejectListView extends ListView implements AbsListView.OnScrollListener{    View mHeader_view;    int mMeasuredHeight;    float Down_y;    float Move_y;    public static final int PULL_TO_REFRESH = 0;//下拉刷新    public static final int RELEASE_REFRESH = 1;//释放刷新    public static final int REFRESHING = 2;     //刷新中    int currentState = PULL_TO_REFRESH;    RotateAnimation rotate_up;    RotateAnimation rotate_dow;    ImageView mArrowView;    ProgressBar mPb;    TextView mTitle;    TextView mDes;    View mFooterView;    boolean isLoadMore;    int mFooterdHeight;    private OnRejectListener onRejectListener;    public RejectListView(Context context) {        super(context);        init();    }    public RejectListView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    public RejectListView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    private void init() {        initHeader();        initAnimation();        initFooter();        setOnScrollListener(this);    }    private void initFooter() {        mFooterView = View.inflate(getContext(), R.layout.listview_footer, null);        mFooterView.measure(0,0);        mFooterdHeight = mFooterView.getMeasuredHeight();        addFooterView(mFooterView);    }    private void initAnimation() {        // 向上转, 围绕着自己的中心, 逆时针旋转0 -> -180.        rotate_up = new RotateAnimation(0f,-180f, Animation.RELATIVE_TO_SELF,0.5f,                Animation.RELATIVE_TO_SELF,0.5f);        rotate_up.setDuration(500);        rotate_up.setFillAfter(true);        // 向下转, 围绕着自己的中心, 逆时针旋转 -180 -> -360        rotate_dow = new RotateAnimation(-180f,-360f, Animation.RELATIVE_TO_SELF,0.5f,                Animation.RELATIVE_TO_SELF,0.5f);        rotate_dow.setDuration(500);        rotate_dow.setFillAfter(true);    }    private void initHeader() {        mHeader_view = View.inflate(getContext(), R.layout.listview_header,null);        //提前手动测量宽高        mHeader_view.measure(0,0);        mMeasuredHeight = mHeader_view.getMeasuredHeight();        mHeader_view.setPadding(0,-mMeasuredHeight,0,0);        mArrowView = (ImageView) mHeader_view.findViewById(R.id.arrowView);        mPb = (ProgressBar) mHeader_view.findViewById(R.id.pb);        mTitle = (TextView) mHeader_view.findViewById(R.id.tv_title);        mDes = (TextView) mHeader_view.findViewById(R.id.tv_des);        addHeaderView(mHeader_view);    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        switch (ev.getAction()){            case MotionEvent.ACTION_DOWN:                Down_y = ev.getY();                break;            case MotionEvent.ACTION_MOVE:                Move_y = ev.getY();                if (currentState == REFRESHING){                    return super.onTouchEvent(ev);                }            float offset = Move_y - Down_y;//移动的偏移量            //只有偏移量>0,并且当前第一个可见条目索引是0,才放大头部            if(offset>0 && getFirstVisiblePosition() == 0){//                    int paddingTop = -自身高度 + 偏移量                    int paddingTop = (int)(-mMeasuredHeight + offset);                    mHeader_view.setPadding(0,paddingTop,0,0);                    if(paddingTop >= 0 && currentState != RELEASE_REFRESH){//头部完全显示                        //切换成释放刷新模式                        currentState = RELEASE_REFRESH;                        //更新最新的状态值,并更新头部内容                        updateHeader();                    }else if(paddingTop <0 && currentState != PULL_TO_REFRESH){                        //切换成下拉刷新模式                        currentState = PULL_TO_REFRESH;                        //更新最新的状态值,并更新头部内容                        updateHeader();                    }                    return true;//当前事件被我们处理并消费                }            break;            case MotionEvent.ACTION_UP:            if (currentState == PULL_TO_REFRESH){                    mHeader_view.setPadding(0,-mMeasuredHeight,0,0);                }else if (currentState == RELEASE_REFRESH){                    mHeader_view.setPadding(0,0,0,0);                    currentState = REFRESHING;                    updateHeader();                }            break;        }        return super.onTouchEvent(ev);    }    private void updateHeader() {        switch (currentState){            case RELEASE_REFRESH://释放刷新模式                mArrowView.startAnimation(rotate_up);                mTitle.setText("释放刷新");                break;            case PULL_TO_REFRESH://下拉刷新模式                mArrowView.startAnimation(rotate_dow);                mTitle.setText("下拉刷新");                break;            case REFRESHING://刷新中                mArrowView.clearAnimation();                mArrowView.setVisibility(View.INVISIBLE);                mPb.setVisibility(View.VISIBLE);                mTitle.setText("正在刷新中...");                if (onRejectListener != null){                    onRejectListener.onReject();//通知调用者,让其网络加载更多数据                }                break;        }    }    public void onRejectComplete() {        if (isLoadMore){            //加载更多            mFooterView.setPadding(0,-mFooterdHeight,0,0);            isLoadMore = false;        }else{            //下拉刷新            currentState = PULL_TO_REFRESH;            mTitle.setText("下拉刷新");            mHeader_view.setPadding(0,-mMeasuredHeight,0,0);            mPb.setVisibility(View.INVISIBLE);            mArrowView.setVisibility(View.VISIBLE);            String time = getTime();            mDes.setText("最后刷新时间" + time);        }    }    public void setRejectListener(OnRejectListener onRejectListener) {        this.onRejectListener =onRejectListener;    }    private String getTime() {        long millis = System.currentTimeMillis();        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        return  format.format(millis);    }    /**会用到原码的一些常量     *  int SCROLL_STATE_FLING = 2;滑翔        int SCROLL_STATE_IDLE = 0;空闲        int SCROLL_STATE_TOUCH_SCROLL = 1;触摸滑动     * @param absListView     * @param i     */    @Override    public void onScrollStateChanged(AbsListView absListView, int i) {        if (isLoadMore){            return;        }        //状态更新的时候        if(i == SCROLL_STATE_IDLE && getLastVisiblePosition() >= getCount()-1){            isLoadMore = true;            mFooterView.setPadding(0,0,0,0);            setSelection(getCount());            if (onRejectListener != null){                onRejectListener.onLoadMore();            }        }    }    @Override    public void onScroll(AbsListView absListView, int i, int i1, int i2) {        //滑动过程    }    public interface OnRejectListener{        void onReject();//下拉刷新        void onLoadMore();//加载更多    }}

listview_header.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:padding="5dp"    android:orientation="horizontal" android:layout_width="match_parent"    android:layout_height="match_parent">    <FrameLayout        android:layout_width="50dp"        android:layout_height="50dp">        <ImageView            android:id="@+id/arrowView"            android:layout_gravity="center"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:src="@mipmap/common_listview_headview_red_arrow"/>        <ProgressBar            android:id="@+id/pb"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:visibility="invisible"            />    </FrameLayout>    <LinearLayout        android:layout_marginLeft="10dp"        android:gravity="center"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical">        <TextView            android:id="@+id/tv_title"            android:textColor="#f00"            android:textSize="26dp"            android:text="下拉更新"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />        <TextView            android:id="@+id/tv_des"            android:singleLine="true"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:textColor="#000"            android:textSize="16dp"            android:text="2016年12月27日15:28:11"            />    </LinearLayout></LinearLayout>

listview_footer.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:gravity="center"    android:orientation="horizontal" android:layout_width="match_parent"    android:layout_height="match_parent">    <ProgressBar        android:layout_margin="5dp"        android:layout_width="50dp"        android:layout_height="50dp" />    <TextView        android:layout_marginLeft="5dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textSize="26dp"        android:textColor="#f00"        android:text="加载更多"        /></LinearLayout>
0 0