ListView下拉刷新功能的简单实现(慕课网视频总结 ,已测试实现)

来源:互联网 发布:java常用算法手册 宋娟 编辑:程序博客网 时间:2024/06/17 00:12
ListView的下拉刷新功能应该是现在应用最广泛的功能了,手机屏幕毕竟有限,不能同一时间加载所有数据,需要我们及时刷新,而现在下拉刷新功能的实现就会解决这个问题,因此,本博文就ListView的下拉刷新功能的具体实现展开叙述,也将自己已经真机测试通过的代码奉上,当然还有截图啦~~~我的代码是建立在上篇博文已经实现的ListView的适配基础上进行修改的,注释都有,需要的直接拿走,下边直接上代码啦~~~MainActivity.java:
    package com.example.listviewpushtorefresh;import java.util.ArrayList;import java.util.List;import com.example.listviewpushtorefresh.RefreshListView.IReflashListener;import bean.Person;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.widget.ListView;public class MainActivity extends Activity implements IReflashListener {    private RefreshListView listview;    MyAdapter adapter;    List<Person> list= new ArrayList<Person>();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        listview = (RefreshListView) findViewById(R.id.listview);        listview.setInterface(this);        adapter = new MyAdapter(MainActivity.this,0,getData());        listview.setAdapter(adapter);    }    private List<Person> getData() {        // TODO Auto-generated method stub        for(int i=0;i<20;i++)        {            Person p = new Person(R.drawable.ic_launcher,i+"","我是第"+i+"项");            list.add(p);        }        return list;    }    private List<Person> getReflashData() {        // TODO Auto-generated method stub//      List<Person> list= new ArrayList<Person>();        for(int i=0;i<2;i++)        {            Person p = new Person(R.drawable.ic_launcher,i+"","我是第"+i+"项刷新数据");            list.add(i,p);        }        return list;    }    @Override    public void onReflash() {        // TODO Auto-generated method stub        Handler handler = new Handler();        handler.postDelayed(new Runnable(){            @Override            public void run() {                // TODO Auto-generated method stub                //获取最新数据                getReflashData();                //通知界面显示                showList(getReflashData());                //通知listview刷新数据完毕                listview.reflashComplete();            }}, 2000);    }   private void showList(List<Person> objects){       if(adapter == null){           listview.setInterface(this);           adapter=new MyAdapter(MainActivity.this,0,getReflashData());           listview.setAdapter(adapter);       }else{           adapter.onDateChanger(getReflashData());       }   }}

自定义的RefreshListView,继承于ListView,RefreshListView.java:

package com.example.listviewpushtorefresh;import java.text.SimpleDateFormat;import java.util.Date;import android.annotation.SuppressLint;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.ViewGroup;import android.view.animation.RotateAnimation;import android.widget.AbsListView;import android.widget.AbsListView.OnScrollListener;import android.widget.ImageView;import android.widget.ListView;import android.widget.ProgressBar;import android.widget.TextView;/**   *    * 项目名称:ListViewPushToRefresh   * 类名称:RefreshListView   * 类描述:   * 创建人:dell   * 创建时间:2016年3月3日 下午8:37:56   * 修改人:dell   * 修改时间:2016年3月3日 下午8:37:56   * 修改备注:   * @version    *    */public class RefreshListView extends ListView implements OnScrollListener{    private static final int REFRESHING = 0;    View header;//顶部布局文件    int headerHeight;//顶部布局文件的高度    int firstVisibleItem;//当前第一个可见的item的位置    boolean isRemark;//标记,当前是在listview的最顶端摁下的    int startY;//摁下是的Y值    int state;//当前的状态    final int NONE=0;//正常状态    final int PULL=1;//提示下拉状态    final int RELESE=2;//提示释放状态    final int REFLASHING=3;//正在刷新状态    int scrollState;    IReflashListener iReflashListener;//刷新数据的接口    //自定义view,要重写所有的构造方法    public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initView(context);    }    @SuppressLint("NewApi")    public RefreshListView(Context context, AttributeSet attrs,            int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);        initView(context);    }    public RefreshListView(Context context, AttributeSet attrs) {        super(context, attrs);        initView(context);    }    public RefreshListView(Context context) {        super(context);        initView(context);    }    /*     * 初始化界面,添加顶部布局文件到listview     */    @SuppressLint("InflateParams")    private void initView(Context context){        LayoutInflater inflater = LayoutInflater.from(context);        header = inflater.inflate(R.layout.header_layout, null);        measureView(header);        headerHeight =header.getMeasuredHeight();        Log.i("tag", "headerHeight="+headerHeight);        topPadding(-headerHeight);        this.addHeaderView(header);        this.setOnScrollListener(this);    }    //通知父布局占有多大地    private void measureView(View view){        ViewGroup.LayoutParams p = view.getLayoutParams();        if(p==null)        {            p =  new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);        }        int width = ViewGroup.getChildMeasureSpec(0, 0, p.width);        int height;        int tempHeight = p.height;        if(tempHeight>0)        {            height = MeasureSpec.makeMeasureSpec(tempHeight,MeasureSpec.EXACTLY);        }        else        {            height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);        }        view.measure(width, height);    }    /*     * 设置header布局的上边距     */    private void topPadding(int topPadding){        header.setPadding(header.getPaddingLeft(), topPadding, header.getPaddingRight(), header.getPaddingBottom());    }    @Override    public void onScrollStateChanged(AbsListView view, int scrollState) {        // TODO Auto-generated method stub        this.scrollState = scrollState;    }    @Override    public void onScroll(AbsListView view, int firstVisibleItem,            int visibleItemCount, int totalItemCount) {        this.firstVisibleItem=firstVisibleItem;    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        // TODO Auto-generated method stub        switch(ev.getAction()){        case MotionEvent.ACTION_DOWN:            if(firstVisibleItem==0){                isRemark = true;                startY = (int) ev.getY();            }            break;        case MotionEvent.ACTION_UP:            if(state==RELESE){                state=REFLASHING;                reflashViewByState();                //加载最新数据                iReflashListener.onReflash();            }            else if(state==PULL){                state=NONE;                isRemark = false;                reflashViewByState();            }            break;        case MotionEvent.ACTION_MOVE:            onMove(ev);            break;        }        return super.onTouchEvent(ev);    }    /*     * 判断移动过程中的操作     */    private void onMove(MotionEvent ev){        if(!isRemark){            return;        }        int tempY = (int) ev.getY();        int space = tempY-startY;        int topPadding= space-headerHeight;        switch(state){        case NONE:            if(space>0)            {                state = PULL;                reflashViewByState();            }            break;        case PULL:            topPadding(topPadding);            if(space>headerHeight+30 && scrollState==SCROLL_STATE_TOUCH_SCROLL){                state = RELESE;                reflashViewByState();            }            break;        case RELESE:            topPadding(topPadding);            if(space<headerHeight+30 ){                state = PULL;                reflashViewByState();            }else if(space<=0){                state = NONE;                reflashViewByState();                isRemark = false;            }            break;        case REFLASHING:            break;        }    }    /**     * 根据当前状态改变界面显示     */    private void reflashViewByState() {        TextView tip = (TextView) header.findViewById(R.id.tip);        ImageView arrow = (ImageView) header.findViewById(R.id.arrow);        ProgressBar progress = (ProgressBar) header.findViewById(R.id.progress);        RotateAnimation anim = new RotateAnimation(0,180, RotateAnimation.RELATIVE_TO_SELF,0.5f,RotateAnimation.RELATIVE_TO_SELF,0.5f);        anim.setDuration(500);        anim.setFillAfter(true);        RotateAnimation anim1 = new RotateAnimation(180,0, RotateAnimation.RELATIVE_TO_SELF,0.5f,RotateAnimation.RELATIVE_TO_SELF,0.5f);        anim1.setDuration(500);        anim1.setFillAfter(true);        switch(state){        case NONE:            arrow.clearAnimation();            topPadding(-headerHeight);            break;        case PULL:            arrow.setVisibility(View.VISIBLE);            progress.setVisibility(View.GONE);            tip.setText("下拉可以刷新");            arrow.clearAnimation();            arrow.setAnimation(anim1);            break;        case RELESE:            arrow.setVisibility(View.VISIBLE);            progress.setVisibility(View.GONE);            tip.setText("松开可以刷新");            arrow.clearAnimation();            arrow.setAnimation(anim);            break;        case REFLASHING:            topPadding(50);            arrow.setVisibility(View.GONE);            progress.setVisibility(View.VISIBLE);            tip.setText("正在刷新");            arrow.clearAnimation();            break;        }    }    /**     * 获取完数据     */    public void reflashComplete(){        state = NONE;        isRemark = false;        reflashViewByState();        TextView lastupdatetime = (TextView) header.findViewById(R.id.lastupdate_time);        SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");        Date date = new Date(System.currentTimeMillis());        String time = format.format(date);        lastupdatetime.setText(time);    }    public void setInterface(IReflashListener iReflashListener){        this.iReflashListener = iReflashListener;    }    /**     *     *        * 刷新数据接口       * @version        *     */    public interface IReflashListener{        public void onReflash();    }}

下拉刷新出来的头部文件header_layout.xml:

<?xml version="1.0" encoding="utf-8"?>     <RelativeLayout          xmlns:android="http://schemas.android.com/apk/res/android"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_gravity="center_horizontal">        <LinearLayout            android:id="@+id/layout"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentTop="true"            android:layout_centerHorizontal="true"            android:orientation="vertical" >            <TextView                android:id="@+id/tip"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="下拉可以刷新!" />            <TextView                android:id="@+id/lastupdate_time"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="n分钟前更新" />        </LinearLayout>        <ImageView            android:id="@+id/arrow"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentTop="true"            android:layout_toLeftOf="@+id/layout"            android:src="@drawable/arrow" />        <ProgressBar            android:id="@+id/progress"            style="?android:attr/progressBarStyleSmall"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerVertical="true"            android:layout_toLeftOf="@+id/arrow"            android:visibility="gone" />    </RelativeLayout>

主布局文件activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent" >  <com.example.listviewpushtorefresh.RefreshListView       android:layout_width="match_parent"      android:layout_height="wrap_content"      android:id="@+id/listview"      android:layout_margin="2dp"      android:divider="#fafad2"      android:dividerHeight="1dp"      >  </com.example.listviewpushtorefresh.RefreshListView></RelativeLayout>

自定义适配器MyAdapter.java:

package com.example.listviewpushtorefresh;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.ImageView;import android.widget.TextView;import bean.Person;public class MyAdapter extends ArrayAdapter<Person> {    private int resoureId;    private List<Person> objects;    private Context context;    public MyAdapter(Context context, int resourceId, List<Person> objects) {        super(context, resourceId, objects);        // TODO Auto-generated constructor stub        this.objects=objects;        this.context=context;    }    private static class ViewHolder    {        ImageView imageView;        TextView title;        TextView content;    }    @Override    public int getCount() {        // TODO Auto-generated method stub        return objects.size();    }    @Override    public Person getItem(int position) {        // TODO Auto-generated method stub        return objects.get(position);    }    @Override    public long getItemId(int position) {        // TODO Auto-generated method stub        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        // TODO Auto-generated method stub        ViewHolder viewHolder = null;        if(convertView==null)        {            viewHolder=new ViewHolder();            LayoutInflater mInflater=LayoutInflater.from(context);            convertView = mInflater.inflate(R.layout.item, null);            viewHolder.imageView = (ImageView) convertView.findViewById(R.id.imageview);            viewHolder.title = (TextView) convertView.findViewById(R.id.title);            viewHolder.content = (TextView) convertView.findViewById(R.id.content);            convertView.setTag(viewHolder);        }        else        {            viewHolder = (ViewHolder) convertView.getTag();        }        Person person = objects.get(position);        if(null!=person)        {            viewHolder.imageView.setBackgroundResource(person.getPicture());            viewHolder.title.setText(person.getTitle());            viewHolder.content.setText(person.getContent());        }        return convertView;    }    public void onDateChanger(List<Person> reflashData) {        // TODO Auto-generated method stub        this.objects=reflashData;        this.notifyDataSetChanged();    }}

自定义的类Person.java:

package bean;public class Person { private int mPicture; private String mTitle; private String mContent; public  Person(int picture,String title,String content){     this.mPicture = picture;     this.mTitle = title;     this.mContent = content; }public int getPicture() {    return mPicture;}public void setmPicture(int mPicture) {    this.mPicture = mPicture;}public String getTitle() {    return mTitle;}public void setTitle(String mTitle) {    this.mTitle = mTitle;}public String getContent() {    return mContent;}public void setContent(String mContent) {    this.mContent = mContent;}}

每个条目的布局文件item.xml:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#a4d3ee">    <ImageView         android:id="@+id/imageview"        android:layout_width="50dp"        android:layout_height="wrap_content"        android:background="@drawable/ic_launcher"        />         <TextView         android:id="@+id/title"        android:layout_width="150dp"        android:layout_height="wrap_content"        android:text="title"        android:textSize="20sp"        android:layout_toRightOf="@+id/imageview"/>    <TextView         android:id="@+id/content"        android:layout_width="150dp"        android:layout_height="wrap_content"        android:text="content"        android:layout_alignLeft="@+id/title"        android:layout_below="@+id/title"/></RelativeLayout>

下面上运行截图:
刷新前:
这里写图片描述
刷新后:
这里写图片描述

OK,至此所有代码结束了,代码可能有不完善的地方,还请路过的大神多多指教哇!!!

经检查发现,刷新数据时总会一次刷新三次,现在已经把bug修改好了,下面把修改过的部分再次附上,没有修改的都和上边一样:
修改过的MainActivity.java:

package com.example.listviewpushtorefresh;import java.util.ArrayList;import java.util.List;import com.example.listviewpushtorefresh.RefreshListView.IReflashListener;import bean.Person;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.widget.ListView;public class MainActivity extends Activity implements IReflashListener {    private RefreshListView listview;    MyAdapter adapter;    List<Person> list= new ArrayList<Person>();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        listview = (RefreshListView) findViewById(R.id.listview);        listview.setInterface(this);        adapter = new MyAdapter(MainActivity.this,0,getData());        listview.setAdapter(adapter);    }    private List<Person> getData() {        // TODO Auto-generated method stub        for(int i=0;i<20;i++)        {            Person p = new Person(R.drawable.ic_launcher,i+"","我是第"+i+"项");            list.add(p);        }        return list;    }    private List<Person> getReflashData() {        // TODO Auto-generated method stub//      List<Person> list= new ArrayList<Person>();        for(int i=0;i<2;i++)        {            Person p = new Person(R.drawable.ic_launcher,i+"","我是第"+i+"项刷新数据");            list.add(i,p);        }        return list;    }    @Override    public void onReflash() {        // TODO Auto-generated method stub        Handler handler = new Handler();        handler.postDelayed(new Runnable(){            @Override            public void run() {                // TODO Auto-generated method stub                //获取最新数据//              getReflashData();                //通知界面显示                showList(getReflashData());                //通知listview刷新数据完毕                listview.reflashComplete();            }}, 2000);    }   private void showList(List<Person> objects){       if(adapter == null){           listview.setInterface(this);           adapter=new MyAdapter(MainActivity.this,0,objects);           listview.setAdapter(adapter);       }else{           adapter.onDateChanger(objects);       }   }}
0 0