仿美团下拉刷新效果(大众点评下拉刷新吃包子的效果也可以这么实现)

        

       虽然现在有很多的下拉刷新的开源框架可以使用,并且使用起来也都是很方便。但是如果想要修改下拉刷新的显示效果,可能用那些开源框架实现起来就不是那么方便。

       

        并且在出去面试的时候,如果被人问道下拉刷新你是怎么做的,如果你告诉别人你是用的第三方的框架,那么对你的面试并没有什么好处,而且不利于你找到高薪的工作,但是如果,你说是自己写的,那你找工作成功的几率就会大很多,而且找到高薪的工作的可能性也会更大。


       所以本文就采用自己实现的方式,实现ListView的下拉刷新,并且添加仿美团的刷新展示效果,先上效果图:


              

实现原理:

    布局

    整体的容器时使用相对布局,下层是放置了一个ImageView用于显示美团的小人,上层是放置了一个ListView(其实也可以放置别的View,看你的需要了)。下面看一下布局文件内容:


   

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/con"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--顶部拉出来的视图-->
    <ImageView
        android:id="@+id/refresh_img"
        android:src="@mipmap/pull_image"
        android:layout_marginTop="10dp"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ListView
        android:id="@+id/list"
        android:background="@android:color/white"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:entries="@array/content" />

</RelativeLayout>

然后是代码,代码里注释比较详细,这里就不在用文字进行描述了,直接看代码吧,如果看不懂可以留言。代码:

package com.libin.lbrefresh;

import android.graphics.drawable.AnimationDrawable;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Toast;


/**
 * MotionEvent
 *   1、getY()  换算过后基于View的Y坐标
 *   2、getRawY()  不经处理基于屏幕的Y坐标
 */

public class MainActivity extends AppCompatActivity {

    private ListView listView;
    private float startPX;//触摸的开始点坐标
    private int startTopMargin;//ListView的原始上边距
    private RelativeLayout.LayoutParams params;
    private ImageView refreshImg;
    private int topMargin;//随手指滑动计算的上边距(即下拉的距离)
    private AnimationDrawable drawable;
    private static final int PULL_DISTANCE = 400;//下拉刷新的触发距离
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int what = msg.what;
            //刷新结束后,复原ListView
            if(what == 100){
                drawable.stop();
                params.topMargin = startTopMargin;
                listView.setLayoutParams(params);
                refreshImg.setImageResource(R.mipmap.pull_image);
                Toast.makeText(MainActivity.this,"刷新成功",Toast.LENGTH_SHORT).show();
                /*
                这里有一段更新ListView数据的代码,就是notifyDatasetChanged()等等
                 */
            }
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.list);
        refreshImg = (ImageView) findViewById(R.id.refresh_img);
        listView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getAction();
                switch (action){
                    case MotionEvent.ACTION_DOWN:
                        //记录手指初始触摸点的坐标
                        startPX = event.getRawY();
                        //记录ListView初始的上边距
                        params = (RelativeLayout.LayoutParams) listView.getLayoutParams();
                        startTopMargin = params.topMargin;
                        break;
                    case MotionEvent.ACTION_MOVE:
                        //计算手指在屏幕上滑动过的距离
                        topMargin = (int) (event.getRawY() - startPX);
                        //判断是否达到触发刷新的距离
                        if(topMargin < PULL_DISTANCE && topMargin > 0){
                            params.topMargin = topMargin;
                            listView.setLayoutParams(params);
                        }

                        if(Build.VERSION.SDK_INT >= 11){
                            float fraction = topMargin * 1.0f / PULL_DISTANCE;
                            //缩放下拉提示小人
                            if(fraction <= 1){
                                refreshImg.setScaleX(fraction);
                                refreshImg.setScaleY(fraction);
                            }
                            //放出小人
                            else if(fraction > 1 && fraction <=1.1){
                                refreshImg.setImageResource(R.mipmap.pull_end_image_frame_01);
                            }else if(fraction > 1.1 && fraction <=1.2){
                                refreshImg.setImageResource(R.mipmap.pull_end_image_frame_02);
                            }else if(fraction > 1.2 && fraction <= 1.3){
                                refreshImg.setImageResource(R.mipmap.pull_end_image_frame_03);
                            }else if(fraction > 1.3 && fraction <= 1.4){
                                refreshImg.setImageResource(R.mipmap.pull_end_image_frame_04);
                            }else{
                                refreshImg.setImageResource(R.mipmap.pull_end_image_frame_05);
                            }
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        //未触发刷新
                        if(topMargin < PULL_DISTANCE){
                            refreshImg.setImageResource(R.mipmap.pull_image);
                            params.topMargin = startTopMargin;
                            listView.setLayoutParams(params);
                        }
                        //触发刷新(这是关键点)
                        else{
                            refreshImg.setImageResource(R.drawable.refresh);
                            drawable = (AnimationDrawable) refreshImg.getDrawable();
                            drawable.start();
                            //执行刷新功能,一般是网络请求
                            new Thread(
                                    new Runnable() {
                                        @Override
                                        public void run() {
                                            //这里添加网络请求的代码,不过因为这不是刷新的关键,故用阻塞线程模拟网络请求用了3秒
                                            try {
                                                Thread.sleep(3 * 1000);
                                            } catch (InterruptedException e) {
                                                e.printStackTrace();
                                            }
                                            //请求完毕,处理小人
                                            handler.sendEmptyMessage(100);
                                        }
                                    }
                            ).start();
                        }
                        //提示刷新
                        float deltaY = event.getRawY() - startPX;
                        if (deltaY > PULL_DISTANCE){
                            Toast.makeText(MainActivity.this,"正在刷新...",Toast.LENGTH_SHORT).show();
                        }
                        break;
                    default:
                        break;
                }
                return false;
            }
        });
    }
}



  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值