自定义控件之上拉刷新下拉加载RefreshListView

来源:互联网 发布:netflix prize 数据集 编辑:程序博客网 时间:2024/05/23 02:15
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.MotionEvent;import android.view.View;import android.view.animation.Animation;import android.view.animation.RotateAnimation;import android.widget.AbsListView;import android.widget.AbsListView.OnScrollListener;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.ProgressBar;import android.widget.TextView;import com.study.smartservice.R;@SuppressLint("SimpleDateFormat")public class RefreshListView extends ListView implements OnScrollListener {private LinearLayout refresh_listview_header_root;private LinearLayout refresh_listview_header_view;private ImageView refresh_listview_header_image;private ProgressBar refresh_listview_header_progress;private TextView refresh_listview_header_text;private TextView refresh_listview_header_date;private RotateAnimation animationUp;private RotateAnimation animationDown;private View customView;private int headerHeight;// 下拉刷新private static final int PULL_REFRESH = 1;// 释放刷新private static final int RELEASE_REFRESH = 2;// 正在刷新private static final int IS_REFRESHING = 3;private static final String tag = "RefreshListView";private static int CURRENTOPTION = PULL_REFRESH;private OnRefreshListener onRefreshListener;// 模拟请求网络的逻辑// private Handler handler = new Handler() {// public void handleMessage(android.os.Message msg) {// onRefreshFinish();// };// };public RefreshListView(Context context) {super(context);initHeader();initFooter();setOnScrollListener(this);}public RefreshListView(Context context, AttributeSet attrs) {super(context, attrs);initHeader();initFooter();setOnScrollListener(this);}// 初始化头布局private void initHeader() {// 总布局:包含刷新头,ViewPager,该布局要加入ListView当做listView的头布局View viewHeader = View.inflate(getContext(),R.layout.refresh_listview_header, null);// 刷新头布局:包含ViewPager,在下面会提供一个方法,将viewPager的view添加到此布局的下方refresh_listview_header_root = (LinearLayout) viewHeader.findViewById(R.id.refresh_listview_header_root);// 刷新头布局:不包含ViewPagerrefresh_listview_header_view = (LinearLayout) viewHeader.findViewById(R.id.refresh_listview_header_view);// 刷新头图片refresh_listview_header_image = (ImageView) viewHeader.findViewById(R.id.refresh_listview_header_image);// 刷新头ProgressBarrefresh_listview_header_progress = (ProgressBar) viewHeader.findViewById(R.id.refresh_listview_header_progress);// 刷新头文字refresh_listview_header_text = (TextView) viewHeader.findViewById(R.id.refresh_listview_header_text);// 刷新头时间refresh_listview_header_date = (TextView) viewHeader.findViewById(R.id.refresh_listview_header_date);// 一开始刷新头不能出现,因此计算刷新头对应的高度refresh_listview_header_view.measure(0, 0);// 获取测量后的高度headerHeight = refresh_listview_header_view.getMeasuredHeight();// 相当于隐藏了刷新头refresh_listview_header_view.setPadding(0, -headerHeight, 0, 0);// 给当前listView添加一个头布局,即将包含刷新头和ViewPager的布局加入ListView头部this.addHeaderView(viewHeader);// 初始化动画initAnimation();}// 初始化底部布局private void initFooter() {View viewFooter = View.inflate(getContext(),R.layout.refresh_listview_footer, null);refresh_listview_footer_foot = (LinearLayout) viewFooter.findViewById(R.id.refresh_listview_footer_foot);refresh_listview_footer_foot.measure(0, 0);footerdHeight = refresh_listview_footer_foot.getMeasuredHeight();refresh_listview_footer_foot.setPadding(0, -footerdHeight, 0, 0);// 给当前listView添加一个底部布局,即将包含刷新底部布局加入此ListViewthis.addFooterView(viewFooter);}private void initAnimation() {// 把图片朝上动画animationUp = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF, 0.5f);// 旋转时间animationUp.setDuration(500);// 旋转过后保持位置animationUp.setFillAfter(true);// 把图片朝下动画animationDown = new RotateAnimation(-180, -360,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);// 旋转时间animationDown.setDuration(500);// 旋转过后保持位置animationDown.setFillAfter(true);}/** * 下拉和上拉的两个接口 *  * @author TCL */public interface OnRefreshListener {public void pullDownRefresh();public void pullUpLoad();}public void onRefreshFinish() {// 下拉刷新完毕的方法if (CURRENTOPTION == IS_REFRESHING) {CURRENTOPTION = PULL_REFRESH;refresh_listview_header_progress.setVisibility(View.INVISIBLE);refresh_listview_header_text.setText("下拉刷新");refresh_listview_header_image.setVisibility(View.VISIBLE);refresh_listview_header_view.setPadding(0, -headerHeight, 0, 0);}if (isLoading) {isLoading = false;refresh_listview_footer_foot.setPadding(0, -footerdHeight, 0, 0);}}public void setOnRefreshListener(OnRefreshListener onRefreshListener) {this.onRefreshListener = onRefreshListener;}// 监听手势的事件private int downY = -1;private int firstVisibleItem = -1;private LinearLayout refresh_listview_footer_foot;private int footerdHeight;private boolean isLoading;@Overridepublic boolean onTouchEvent(MotionEvent ev) {switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:downY = (int) ev.getY();break;case MotionEvent.ACTION_MOVE:if (downY == -1) {downY = (int) ev.getY();}int moveY = (int) ev.getY();// 正在刷新的时候不让ListView拖动if (CURRENTOPTION == IS_REFRESHING) {break;}// 获取ListView所在屏幕上左上角坐标int[] listViewLocation = new int[2];// 给数组赋值this.getLocationOnScreen(listViewLocation);// 获取当前ListView对应的Y值int listViewY = listViewLocation[1];// 获取轮播图在屏幕左上角的坐标int[] customViewLoction = new int[2];customView.getLocationOnScreen(customViewLoction);int customViewY = customViewLoction[1];if (listViewY > customViewY) {break;}int padding = -headerHeight + moveY - downY;// moveY-downY>0,此时向下拉,并且当前的第一个条目是索引中的第一个if (padding > -headerHeight && firstVisibleItem == 0) {// 响应下拉刷新头展示的操作if (padding > 0 && CURRENTOPTION == PULL_REFRESH) {// 此时已经完整的吧刷新头拉出来了并且当前状态是下拉刷新CURRENTOPTION = RELEASE_REFRESH;setCurrentOpiton();Log.i(tag, "释放刷新");}if (padding < 0 && CURRENTOPTION == RELEASE_REFRESH) {// 刷新头一部分显示,一部分隐藏CURRENTOPTION = PULL_REFRESH;setCurrentOpiton();Log.i(tag, "下拉刷新");}refresh_listview_header_view.setPadding(0, padding, 0, 0);// 保证手放开的时候去响应up事件return true;}break;case MotionEvent.ACTION_UP:if (CURRENTOPTION == RELEASE_REFRESH) {CURRENTOPTION = IS_REFRESHING;// 刷新setCurrentOpiton();// 结合逻辑去做刷新操作(回调)if (onRefreshListener != null) {onRefreshListener.pullDownRefresh();}// handler.sendEmptyMessageDelayed(0, 2000);refresh_listview_header_view.setPadding(0, 0, 0, 0);} else if (CURRENTOPTION == PULL_REFRESH) {// 做一个弹回的操作refresh_listview_header_view.setPadding(0, -headerHeight, 0, 0);}break;}return super.onTouchEvent(ev);}/** * 处理状态的方法 */public void setCurrentOpiton() {switch (CURRENTOPTION) {case RELEASE_REFRESH:refresh_listview_header_text.setText("释放刷新");refresh_listview_header_image.startAnimation(animationUp);break;case PULL_REFRESH:refresh_listview_header_text.setText("下拉刷新");refresh_listview_header_image.startAnimation(animationDown);break;case IS_REFRESHING:refresh_listview_header_text.setText("正在刷新");refresh_listview_header_image.clearAnimation();refresh_listview_header_image.setVisibility(View.GONE);refresh_listview_header_progress.setVisibility(View.VISIBLE);refresh_listview_header_date.setText(getTime());}}private String getTime() {Date date = new Date();SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return dateFormat.format(date);}// 提供一个方法将轮播图对应的view放置进来public void addCustomView(View v) {customView = v;// 因为该布局中已有一个刷新头,所以再添加的view在刷新头下方refresh_listview_header_root.addView(customView);}@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {// 监听ListView滚动状态发生改变的方法if (scrollState == OnScrollListener.SCROLL_STATE_FLING|| scrollState == OnScrollListener.SCROLL_STATE_IDLE) {// 当前最后一个可见条目if (getLastVisiblePosition() == getAdapter().getCount() - 1&& !isLoading) {// 加载更多操作isLoading = true;refresh_listview_footer_foot.setPadding(0, 0, 0, 0);// 加载更多的逻辑(回调)if (onRefreshListener != null) {onRefreshListener.pullUpLoad();}// handler.sendEmptyMessageDelayed(0, 2000);}}}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {// 当前滚动操作的头对应索引this.firstVisibleItem = firstVisibleItem;}}

refresh_listview_header.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/refresh_listview_header_root"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="vertical" >    <!-- 刷新头 -->    <LinearLayout        android:id="@+id/refresh_listview_header_view"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal" >        <!-- 左侧图片 -->        <FrameLayout            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_margin="5dp" >            <ImageView                android:id="@+id/refresh_listview_header_image"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_gravity="center"                android:src="@drawable/common_listview_headview_red_arrow" />            <ProgressBar                android:id="@+id/refresh_listview_header_progress"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:visibility="invisible" />        </FrameLayout>        <!-- 刷新文字 -->        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="vertical"             android:layout_gravity="center"            android:gravity="center">            <TextView                android:id="@+id/refresh_listview_header_text"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="下拉刷新" />            <TextView                android:id="@+id/refresh_listview_header_date"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="1999-10-10" />        </LinearLayout>    </LinearLayout>    <!-- 在此添加轮播图 --></LinearLayout>

refresh_listview_footer.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/refresh_listview_footer_foot"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="horizontal"     android:gravity="center">   <ProgressBar        android:layout_width="wrap_content"       android:layout_height="wrap_content"/>   <TextView        android:layout_gravity="center"       android:gravity="center"       android:layout_width="wrap_content"       android:layout_height="wrap_content"       android:text="正在加载"       android:textSize="20sp"/></LinearLayout>


0 0
原创粉丝点击