android中的下拉刷新

来源:互联网 发布:数据透视表怎么做差异 编辑:程序博客网 时间:2024/06/05 09:48

1.目前主要的下拉刷新大致分为三种实现方式:


    a.比较通用的,像官方SwipeRefreshLayout,github上也有很多种实现,属于在外层包裹。




   b。其实下拉刷新用的最多的还是在listview中,给listview添加head,控制head的padding值




   c。 同上,但是是控制head的高度的


2.下面演示控制head的padding实现下拉刷新

    这种方式并不灵活,比较灵活的是像android-Ultra-Pull-to-Refresh这种,外层包裹的,可以包裹任何view,但是在listview中用head的padding有特殊使用场景比如说,listview 有一个head,而下拉是在这个head的下面的。

                                        



代码:


MainActivity.java

package cn.edu.sxu.www.customerpullrefresh;import android.graphics.Color;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.Gravity;import android.view.View;import android.widget.AbsListView;import android.widget.AdapterView;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.TextView;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {    private ListView customerlistview;    private MyAdapter myAdapter;    private List<String> lists;    private LinearLayout activity_main;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        activity_main= (LinearLayout) findViewById(R.id.activity_main);//        customerlistview= (ListView) findViewById(R.id.customerlistview);        customerlistview=new CustomerListView(this) {            @Override            public View addHeadView() {                TextView textView=new TextView(MainActivity.this);                textView.setBackgroundColor(Color.parseColor("#ff00ff"));                textView.setGravity(Gravity.CENTER);                textView.setText("listview头部");                AbsListView.LayoutParams params=new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT,200);                textView.setLayoutParams(params);                addHeaderView(textView);                return textView;            }        };        customerlistview.setSelector(R.drawable.bg_item);        activity_main.addView(customerlistview);        lists=new ArrayList<>();        for(int i=0;i<20;i++)        {            lists.add(""+i);        }        myAdapter=new MyAdapter(this,lists);        customerlistview.setAdapter(myAdapter);        myAdapter.notifyDataSetChanged();        customerlistview.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                String desc = (String) parent.getAdapter().getItem(position);                MToast.showToast(MainActivity.this,desc);            }        });    }}



CustomerListView.java

package cn.edu.sxu.www.customerpullrefresh;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewTreeObserver;import android.widget.ListView;import android.widget.Scroller;/** * Created by ${huozhenpeng} on 17/6/29. * Company : www.miduo.com */public abstract class CustomerListView extends ListView {    private Context context;    public CustomerListView(Context context) {        this(context, null);    }    public CustomerListView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        this.context = context;        init();    }    public abstract View addHeadView();    public CustomerListView(Context context, AttributeSet attrs) {        this(context, attrs, -1);    }    private View headView;    private int mHeaderHeight;    private View firstView;    private void init() {        if (headView == null) {            headView = LayoutInflater.from(context).inflate(R.layout.head_view, null);        }        firstView = addHeadView();        addHeaderView(headView);        mScrollChecker = new ScrollChecker();        headView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {            @Override            public void onGlobalLayout() {                mHeaderHeight = headView.getMeasuredHeight();                headView.setPadding(0, -headView.getMeasuredHeight(), 0, 0);                getViewTreeObserver().removeGlobalOnLayoutListener(this);            }        });    }    @Override    protected void onFinishInflate() {        super.onFinishInflate();    }    private void setPadding(int paddingTop) {        if (paddingTop >= 0)            paddingTop = 0;        if (paddingTop <= -mHeaderHeight)            paddingTop = -mHeaderHeight;        headView.setPadding(0, paddingTop, 0, 0);    }    //作用主要是一次下拉还没有结束之后又进行下一次下拉(这种的话,效果会好点,连续。。。。。)    private int initPadding=-500;    @Override    public boolean onTouchEvent(MotionEvent ev) {        switch (ev.getAction()) {            case MotionEvent.ACTION_DOWN:                Y = (int) ev.getY();                if(runnable!=null)                {                    //移除回调,                    initPadding=headView.getPaddingTop();                    CustomerListView.this.removeCallbacks(runnable);                    mScrollChecker.removeCallBacks();                }                break;            case MotionEvent.ACTION_MOVE:                curY = (int) ev.getY();                //firstview是区分下拉刷新上面还有没有headview                if (firstView == null) {                    if (getFirstVisiblePosition() == 0 && Math.abs(headView.getPaddingTop()) == mHeaderHeight) {                        if (curY > Y) {                            setPadding(initPadding + (curY - Y));                            return true;                        } else {                        }                    } else if (getFirstVisiblePosition() > 0) {                    } else if (Math.abs(headView.getPaddingTop()) <= mHeaderHeight) {                        setPadding(initPadding + (curY - Y));                        return true;                    }                } else {                    if (getFirstVisiblePosition() == 0 && firstView.getBottom() == firstView.getHeight()) {                        if (curY > Y) {                            setPadding(initPadding + (curY - Y));                            return true;                        } else {                        }                    } else {                    }                }                break;            case MotionEvent.ACTION_UP:                if(firstView!=null)                {                    if (Math.abs(headView.getPaddingTop()) < mHeaderHeight&&getFirstVisiblePosition()<2) {                        onRelease();                        return true;                    }                    else                    {                        setPadding(-mHeaderHeight);                    }                }                else                {                    if (Math.abs(headView.getPaddingTop()) < mHeaderHeight&&getFirstVisiblePosition()<1) {                        onRelease();                        return true;                    }                    else                    {                        setPadding(-mHeaderHeight);                    }                }                break;        }        return super.onTouchEvent(ev);    }    private int Y;    private int curY;    //释放时,contentView的top值    private int releaseTop;    private Runnable runnable;    /**     * 假设每次让回复到250px的时候执行正在刷新操作     */    private void onRelease() {        releaseTop = headView.getPaddingTop();        if (Math.abs(headView.getPaddingTop()) <= mHeaderHeight / 2) {            mScrollChecker.tryToScrollTo(releaseTop + mHeaderHeight / 2, 1000);            runnable=new Runnable() {                @Override                public void run() {                    //刷新2s后恢复到初始位置                    //不要用这个,getTop值恢复过程中会变化的                    mScrollChecker.tryToScrollTo(mHeaderHeight / 2, 1500);                }            };            postDelayed(runnable, 2000);        } else {            //相当于不执行刷新            mScrollChecker.tryToScrollTo(releaseTop + mHeaderHeight, 1500);        }    }    private ScrollChecker mScrollChecker;    private int oldPadding;    private boolean finish = true;    private int currentPadding;    class ScrollChecker implements Runnable {        private Scroller mScroller;        public ScrollChecker() {            mScroller = new Scroller(getContext());        }        @Override        public void run() {            finish = !mScroller.computeScrollOffset() || mScroller.isFinished();            if (!finish) {                if (headView.getPaddingTop() < -mHeaderHeight) {                    headView.setPadding(0, -mHeaderHeight, 0, 0);                } else if (headView.getPaddingTop() > 0) {                    headView.setPadding(0, -mHeaderHeight, 0, 0);                } else {                    currentPadding = -mScroller.getCurrY() + oldPadding;                    headView.setPadding(0, -mScroller.getCurrY() + oldPadding, 0, 0);                    post(this);                }            }        }        public void tryToScrollTo(int to, int duration) {            oldPadding = headView.getPaddingTop();            mScroller.startScroll(0, 0, 0, to, duration);            post(this);        }        public void removeCallBacks() {            removeCallbacks(this);        }    }}




MToast.java

package cn.edu.sxu.www.customerpullrefresh;import android.content.Context;import android.view.Gravity;import android.widget.Toast;/** *  * Toast替换 *  */public class MToast {private static Toast mToast;public static void showToast(Context context, String text) {if (mToast == null) {mToast = Toast.makeText(context, text, Toast.LENGTH_SHORT);} else {mToast.setText(text);mToast.setDuration(Toast.LENGTH_SHORT);}mToast.setGravity(Gravity.CENTER, 0, 0);mToast.show();}public static void showToast2(Context context, String text) {if (mToast == null) {mToast = Toast.makeText(context, text, Toast.LENGTH_LONG);} else {mToast.setText(text);mToast.setDuration(Toast.LENGTH_LONG);}mToast.setGravity(Gravity.CENTER, 0, 0);mToast.show();}public static void cancelToast() {if (mToast != null) {mToast.cancel();}}}


MyAdapter.java
package cn.edu.sxu.www.customerpullrefresh;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import java.util.List;/** * Created by ${huozhenpeng} on 17/6/29. * Company : www.miduo.com */public class MyAdapter extends BaseAdapter {    private Context context;    private List<String> lists;    public MyAdapter(Context context,List<String> lists)    {        this.context=context;        this.lists=lists;    }    @Override    public int getCount() {        return lists.size();    }    @Override    public Object getItem(int position) {        return lists.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        convertView= LayoutInflater.from(context).inflate(R.layout.item,null);        TextView textView= (TextView) convertView.findViewById(R.id.text);        textView.setText(lists.get(position));        return convertView;    }}


activity_main2.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    >    <View        android:layout_width="match_parent"        android:layout_height="1px"        android:background="#000000"        /></LinearLayout>



head_view.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    >    <LinearLayout        android:orientation="vertical"        android:background="#00ff00"        android:layout_width="match_parent"        android:layout_height="500px">        <TextView            android:id="@+id/tv_title"            android:layout_width="match_parent"            android:layout_height="200px"            android:text="头部"            android:gravity="center"            android:textColor="#00aabb"            />        <ProgressBar            android:layout_gravity="center"            android:id="@+id/pb_progress"            android:layout_width="wrap_content"            android:layout_height="250px"            android:layout_alignParentBottom="true"            android:layout_centerHorizontal="true"            />    </LinearLayout></LinearLayout>







item.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    >    <TextView        android:id="@+id/text"        android:layout_width="match_parent"        android:layout_height="100dp"        android:gravity="center"        /></RelativeLayout>



源码下载:

点击打开链接