ListView下拉刷新具体实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ye1714505125/article/details/51035104

1、现在gitHub中有ListView的下拉刷新的框架,不过个人手贱,还是自己做了一个,懂了很多东西,哎,又不是数据结构,只是一些基本的下拉东西,在此留给自己回忆的。

2、不适宜新人学习,因为我基本不加载图片在这,只留给有基础的人忘记刷新的一些重要东西查看。

主布局文件:如果不在tab 加载什么东西的话,基本不用加载任何东西,就是一个自定义的ListView ;

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/activity_main" tools:context=".MainActivity">
<ad.workharder.com.refreshDemo.RefreshView
    android:id="@+id/refreshListView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    />


</RelativeLayout>

下拉头部上拉 布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:layout_marginTop="10dp"
    android:layout_marginBottom="10dp"
    android:orientation="horizontal">
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <ImageView
            android:id="@+id/image_arrow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/indicator_arrow"
            android:layout_centerInParent="true"/>
<!自定义ProgressBar的图片,和旋转持续的时间>
        <ProgressBar
            android:id="@+id/pb_intedimanate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:indeterminate="true"
            android:visibility="invisible"
            android:indeterminateDuration="1000"
            android:indeterminateDrawable="@drawable/intediminate_drawable"
            android:layout_centerInParent="true"
            />
    </RelativeLayout>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:orientation="vertical"
        android:gravity="center"
        android:layout_marginLeft="20dp">
        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:textColor="#aa000000"
            android:text="下拉刷新"
            />
        <TextView
            android:id="@+id/tv_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:textColor="#66666666"
            android:layout_marginTop="5dp"
            android:text="最后刷新:2012-21-21"
            />
    </LinearLayout>

</LinearLayout>

加载底部刷新布局:

<?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="wrap_content"
    android:gravity="center"
    android:orientation="horizontal">
    <ProgressBar
        android:id="@+id/pb_footer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:indeterminate="true"
        android:indeterminateDuration="1000"
        android:layout_marginTop="5dp"
        android:indeterminateDrawable="@drawable/intediminate_drawable"
        android:layout_centerInParent="true"
        />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv_footername"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="5dp"
        android:textSize="20sp"
        android:textColor="#aa000000"
        android:text="正在加载,请稍后..."/>

</LinearLayout>
布局文件代码:

public class RefreshView extends ListView {
    private View listViewHeader;
    private ImageView image_arrow;
    private ProgressBar pb_intediminate;
    private TextView tv_name;
    private TextView tv_time;
    private int listViewHeaderHeight;
    private int downY; //按下时的Y坐标
    final int PULLREFRESH=0;  //下拉刷新
    final int RELEASEFRESH=1;    //正在刷新
    final int REFRESHING=2;    //正在刷新装填
    int CURRENTSTATEREFRESH=PULLREFRESH;
    private View footerView;
    private int footerViewHeight;
    private boolean isLoading=false;//判断当前是否是加载更多


    //    AttributeSet 封装属性的列表,比如xml文件的一系列属性
    public RefreshView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    public RefreshView(Context context) {
        super(context);
        init();
    }
    private void init(){
        initHeaderView();
        initAnimation();
        initFooterView();
    }

    private void initHeaderView(){
 /*  获取头文件高度第一种方法,在头文件布局onLayout()完成后,再设置其高度
        listViewHeader = View.inflate(MainActivity.this, R.layout.layout_header, null);
        listViewHeader.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                listViewHeaderHeight=listViewHeader.getHeight();
            }
        });
        */
        //一般为更为方便,采用测量获取头文件的高度,这是第二种方法,不过,首先需要onMeasure方法执行完;

        listViewHeader=View.inflate(getContext(),R.layout.layout_header,null);
        image_arrow = (ImageView) listViewHeader.findViewById(R.id.image_arrow);
        pb_intediminate = (ProgressBar) listViewHeader.findViewById(R.id.pb_intedimanate);
        tv_name = (TextView) listViewHeader.findViewById(R.id.tv_name);
        tv_time = (TextView) listViewHeader.findViewById(R.id.tv_time);
        listViewHeader.measure(0,0);   //主动通知系统测量该View
        listViewHeaderHeight = listViewHeader.getMeasuredHeight();
        //通过设置负高度,将头文件隐藏
        listViewHeader.setPadding(0, -listViewHeaderHeight, 0, 0);
        addHeaderView(listViewHeader);  //RefreshView天然拥有头文件
    }

    private void initFooterView() {
        footerView = View.inflate(getContext(), R.layout.layout_footer, null);
        footerView.measure(0, 0);   //主动通知系统测量该View
        footerViewHeight = footerView.getMeasuredHeight();
        //通过设置负高度,将底文件隐藏
        footerView.setPadding(0, -footerViewHeight, 0, 0);
        addFooterView(footerView);
    }
    /*
         判断触摸事件
        从而执行哪段动画
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                downY = (int) ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                //如果正在处于刷新状态,则停止滑动
                if (CURRENTSTATEREFRESH==REFRESHING){
                    break;
                }
                int daltaY= (int) (ev.getY()-downY);      //判断用户手指滑动方向的距离,如果向下移动,Y 是正的,如果向上滑动,Y是负数
                int paddingTop=-listViewHeaderHeight+daltaY;      //  让头文件HeaderView 随着手指一起滑动
                if (paddingTop >= (-listViewHeaderHeight)&&getFirstVisiblePosition()==0) {
                    listViewHeader.setPadding(0,paddingTop,0,0);
                    if(paddingTop>=0&&(CURRENTSTATEREFRESH==PULLREFRESH)){
                        //由下拉刷新到松开刷新状态
                        CURRENTSTATEREFRESH=RELEASEFRESH;
                        refreshHeaderView();
                        break;
                    }else if(paddingTop<0&&(CURRENTSTATEREFRESH==RELEASEFRESH)){
                        //由松开刷新到下拉刷新状态
                        CURRENTSTATEREFRESH=PULLREFRESH;
                        refreshHeaderView();
                    }
                    return true;   //拦截TouchView 不让ListView处理ACTION_Move时间,但是会造成listView无法滑动
                }
                break;
            case MotionEvent.ACTION_UP:
                //回到隐藏
                if(CURRENTSTATEREFRESH==PULLREFRESH){
                    listViewHeader.setPadding(0,-listViewHeaderHeight,0,0);
                }else if(CURRENTSTATEREFRESH==RELEASEFRESH) {
                    //由松开刷新到正在刷新状态
                    listViewHeader.setPadding(0, 0, 0, 0);
                    CURRENTSTATEREFRESH = REFRESHING;
                    refreshHeaderView();
                    if(lisener!=null){
                        lisener.onPullRefresh();
                    }
                }
                if (getLastVisiblePosition() == (getCount() - 1) && !isLoading) {
                    footerView.setPadding(0, 0, 0, 0);  //显示出footerView
                    setSelection(getCount());   // listView 最后一条显示出来
                    isLoading = true;
                    if(lisener!=null){
                        lisener.onLoadingMoreRefresh();
                    }
                }
        }
        return super.onTouchEvent(ev);
    }
    /*
       通过状态,判断是哪种,改变箭头指向
     */
    private void refreshHeaderView(){
        switch (CURRENTSTATEREFRESH){
            case PULLREFRESH:
                tv_name.setText("下拉刷新");
                image_arrow.startAnimation(downRotateAnimation);
                break;
            case RELEASEFRESH:
                tv_name.setText("松开刷新");
                image_arrow.startAnimation(upRotateAnimaition);
                break;
            case REFRESHING:
                image_arrow.clearAnimation();//因为旋转动画可能没执行完
                image_arrow.setVisibility(View.INVISIBLE);
                pb_intediminate.setVisibility(View.VISIBLE);
                tv_name.setText("正在刷新...");
                break;
        }
    }
    /*
    获取最新时间
     */
    private String getCurrentTime(){
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yy-MM-dd HH-mm-ss");
        return simpleDateFormat.format(new Date());
    }
    /*
    定义旋转图标,以及它的旋转方向
     */
    private RotateAnimation upRotateAnimaition,downRotateAnimation;
    private void initAnimation() {
        upRotateAnimaition = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        upRotateAnimaition.setDuration(300);
        upRotateAnimaition.setFillAfter(true);
        downRotateAnimation=new RotateAnimation(-180,-360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        downRotateAnimation.setDuration(300);
        downRotateAnimation.setFillAfter(true);
    }
    /*
          完成刷新,在你获取完数据并更新完UI的时候调用该方法,重置状态
     */
    public void completeRefresh(){
        //重置底部文件
        if (isLoading){
            footerView.setPadding(0,-footerViewHeight,0,0);
            isLoading=false;
        }else{
            //重置头部文件
            listViewHeader.setPadding(0,-listViewHeaderHeight,0,0); //重置刷新,隐藏headerView
            CURRENTSTATEREFRESH=PULLREFRESH;
            pb_intediminate.setVisibility(View.INVISIBLE);
            image_arrow.setVisibility(VISIBLE);
            tv_name.setText("下拉刷新");
            tv_time.setText("最后刷新:"+getCurrentTime());
        }
    }
    /*
    定义接口,便于外部创建接口,并实现接口的方法
     */
    onRefreshLisener lisener;
    public void setOnRefreshLisener(onRefreshLisener lisener){
        this.lisener=lisener;
    }
    public interface onRefreshLisener{
        void onPullRefresh();
        void onLoadingMoreRefresh();
    }
}
主文件代码:

public class MainActivity extends AppCompatActivity {
    /*
    handler处理机制,一个延时操作,一个更新UI
     */
    Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
//           更新UI,通知adapter更新数据
            myAdater.notifyDataSetChanged();
            //重置状态,一个上拉刷新,;一个下拉刷新,待请求数据后,重置其状态,隐藏
            refreshView.completeRefresh();
        }
    };
    private RefreshView refreshView;
    private ArrayList<String> arrayList;
    private MyAdapter myAdater;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);  //去掉标题栏
        //全屏显示
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        super.onCreate(savedInstanceState);
        initView();
        initData();
    }
    /*
       初始化ListView数据
     */
    private void initView() {
        setContentView(R.layout.activity_main);
        refreshView = (RefreshView) findViewById(R.id.refreshListView);
        myAdater=new MyAdapter();
    }

    private void initData() {
        arrayList = new ArrayList<String>();
        for (int i = 0; i < 15; i++) {
            arrayList.add("listView原来的数据:" + i);
        }
        refreshView.setAdapter(myAdater);
        refreshView.setOnRefreshLisener(new RefreshView.onRefreshLisener() {
            @Override
            public void onPullRefresh() {
                //此时需要联网请求服务器数据,更新UIfalse表示 上拉请求数据
                requestDataFromServer(false);
            }

            @Override
            public void onLoadingMoreRefresh() {
                requestDataFromServer(true);
            }
        });
    }
     private void requestDataFromServer(final boolean isLoadingMore){
        new Thread(){
            public void run(){
                SystemClock.sleep(2000);  //模拟请求服务器数据的耗时操作
                if(isLoadingMore){
                    arrayList.add("下拉的数据:1");
                    arrayList.add("下拉的数据:2");
                    arrayList.add("下拉的数据:3");
                    arrayList.add("下拉的数据:4");

                }else{
                    arrayList.add(0, "下拉刷新的数据,夏老师");
                    arrayList.add(1,"下拉刷新的数据,work harder");
                }
                handler.sendEmptyMessage(0);
            }
        }.start();
    }
    /*
    初始化ListViewAdapter
     */
    class MyAdapter extends BaseAdapter {
        @Override
        public int getCount() {
            return arrayList.size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView textView = new TextView(MainActivity.this);
            textView.setText(arrayList.get(position));
            textView.setPadding(20, 20, 20, 20);
            textView.setTextSize(18);
            return textView;
        }
    }
}


猜你喜欢

转载自blog.csdn.net/ye1714505125/article/details/51035104