功能:下拉刷新listview,没有下拉刷新的时候,自动隐藏刷新属性,可以下拉listview
步骤:1.创建layout布局,该布局为下拉刷新的布局
代码:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center"> <ImageView android:id="@+id/img_View" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/title_icon_refresh" android:layout_marginRight="5dp"/> <TextView android:id="@+id/refresh_textView" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="正在刷新......"/> </LinearLayout>
2.创建class类PillToRefreshListView ,继承自Listview,然后在构造函数中对上面布局的控件实例化,在编写
setAdapter()方法,实现将第一行的刷新listview隐藏
代码:
package RefreshListView; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.TextView; import app.coolweather.com.weibo.R; /** *在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。 具体作用: 1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入; 2、对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。 * Created by Administrator on 2016/9/29. */ public class PullToRefreshListView extends ListView { private LayoutInflater mlayoutInflater; private LinearLayout mlinearLayout; public ImageView mimageView; public TextView mtextView; //lsitview下拉刷新的对象声明 //初始化状态 private static final int TAP_TO_REFRESH=1; //下拉刷新状态 private static final int PULL_TO_REFRESH=2; //释放刷新状态 private static final int RELEASE_TO_REDRESH=3; //正在刷新状态 private static final int Refresh=4; //HeadView的高度 private int mHeadViewHeight; //当前listview的刷新状态 private int mRefreshState; private int mLastMotionY; public PullToRefreshListView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public void init(Context context){ mlayoutInflater=LayoutInflater.from(context); //在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。 具体作用: // 1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入; // 2、对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。 mlinearLayout= (LinearLayout) mlayoutInflater.inflate(R.layout.refresh_listview,this,false); mimageView= (ImageView) mlinearLayout.findViewById(R.id.img_View); mtextView= (TextView) mlinearLayout.findViewById(R.id.refresh_textView); // mimageView.setMinimumWidth(50); // mimageView.setMinimumHeight(50); //将控件加入到头部 addHeaderView(mlinearLayout); measureView(mlinearLayout); } @Override public void setAdapter(ListAdapter adapter) { super.setAdapter(adapter); setSelection(1);//让下拉刷新控件,隐藏起来 }
//上面代码为在listview的最上面加入一个刷新布局,在没有点击下拉listview的时候,将这个布局隐藏起来
//下面的代码为控制下拉的距离,想下拉多少就下拉多少,而不是下拉多少不受控制
@Override public boolean onTouchEvent(MotionEvent ev) { switch(ev.getAction()){ //按下 case MotionEvent.ACTION_DOWN: mLastMotionY= (int) ev.getY(); break; //拖动 case MotionEvent.ACTION_MOVE: applyHeadViewPadding(ev); break; //弹起 case MotionEvent.ACTION_UP: break; default: break; } return super.onTouchEvent(ev); } /** * 不断去更改HeadView视图的Top Padding属性 * @param event */ private void applyHeadViewPadding(MotionEvent event){ int pointCount=event.getHistorySize(); for(int i=0;i<pointCount;i++){ //获取历史累计的高定 int hisY= (int) event.getHistoricalY(i); int topPadding= (int) (((hisY-mLastMotionY)-mHeadViewHeight)/1.5); mlinearLayout.setPadding(mlinearLayout.getPaddingLeft(),topPadding,mlinearLayout.getPaddingRight(),mlinearLayout.getPaddingBottom()); } } /** * 测量HeadVie的高度 * @param child */ protected void measureView(View child){ ViewGroup.LayoutParams p=child.getLayoutParams(); if(p==null) { p=new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT); } int childWidthSpec=ViewGroup.getChildMeasureSpec(0,0,p.width); int lpHeight=p.height; int childHeightSpec; //更具提供的大小和模式创建一个测量值 if(lpHeight>0){ childHeightSpec=MeasureSpec.makeMeasureSpec(lpHeight,MeasureSpec.EXACTLY); } else{ childHeightSpec=MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED); } child.measure(childWidthSpec,childHeightSpec); } }
第三部:在加载Adapter的Activity,对应的布局文件中,加载上面的类
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/qgreen"> <!--空间大小用px,局利用sp,dp--> <!--加载标题样式文件--> <include android:id="@+id/layout_title_bar" layout="@layout/title_bar"/> <include android:id="@+id/layout_progress" layout="@layout/progress" /> <RefreshListView.PullToRefreshListView android:id="@+id/refresh_list_view_17878" android:layout_width="match_parent" android:layout_height="wrap_content" > </RefreshListView.PullToRefreshListView> <ListView android:id="@+id/list_view_home" android:layout_height="wrap_content" android:layout_width="match_parent" android:dividerHeight="1dp" android:cacheColorHint="#000000" android:paddingBottom="80dp" /><!--android:divider="@drawable/line"--> </LinearLayout>
最后,在Activity中加载adapter:
private PullToRefreshListView pullToRefreshListView;
private static String[] data={"1","2","3","4","5","6","7","8","9","10","2","3","4","5","6","7","8","9","10"}
//实例化刷新listview pullToRefreshListView= (PullToRefreshListView) findViewById(R.id.refresh_list_view_17878); ArrayAdapter<String> adapter1=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,data); pullToRefreshListView.setAdapter(adapter1);
效果图