自定义控件之上拉刷新下拉加载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
- 自定义控件之上拉刷新下拉加载RefreshListView
- 上拉加载-下拉刷新控件 RefreshListView
- RefreshListView 下拉刷新和上拉加载
- 自定义控件之ListView下拉刷新,上拉加载更多
- 自定义控件(四)-下拉刷新与上拉加载
- 自定义控件-下拉刷新和上拉加载的listView
- 自定义XlistView(上拉加载,下拉刷新)控件
- 自定义控件实现ListView下拉刷新和上拉加载
- 自定义下拉刷新上拉加载控件(SwipeRefreshLayout + recyclerView)
- android自定义下拉刷新和上拉加载控件
- 微信小程序之上拉加载和下拉刷新
- react-native之上拉加载,下拉刷新组件封装
- 下拉刷新,上拉加载控件
- 上拉刷新下拉加载控件-PullToRefresh
- 上拉加载下拉刷新控件
- 自定义下拉刷新上拉加载动画
- 自定义ListView下拉刷新上拉加载
- Android 自定义下拉刷新上拉加载
- tabbar的隐藏和出现
- opencv Mat 内存分配
- Spring3 -- IOC简单介绍 01
- 维生素E乳
- DAS, SAN, NAS 和IPSAN
- 自定义控件之上拉刷新下拉加载RefreshListView
- EditText属性大全
- Spinner下拉列表控件
- Android实现类似微信的延迟加载的Fragment——LazyFragment
- Minimum Depth of Binary Tree
- ubuntu开机自动登陆
- 论文笔记1《基于ID3决策树改进算法的客户流失预测分析》
- mybatis foreach
- Qtopia-2.2.2在x86平台编译--错误修改总汇