版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ye1714505125/article/details/51035104
1、现在gitHub中有ListView的下拉刷新的框架,不过个人手贱,还是自己做了一个,懂了很多东西,哎,又不是数据结构,只是一些基本的下拉东西,在此留给自己回忆的。
2、不适宜新人学习,因为我基本不加载图片在这,只留给有基础的人忘记刷新的一些重要东西查看。
主布局文件:如果不在tab 加载什么东西的话,基本不用加载任何东西,就是一个自定义的ListView ;
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:showIn="@layout/activity_main" tools:context=".MainActivity"> <ad.workharder.com.refreshDemo.RefreshView android:id="@+id/refreshListView" android:layout_width="match_parent" android:layout_height="wrap_content" /> </RelativeLayout>
下拉头部上拉 布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:layout_marginTop="10dp" android:layout_marginBottom="10dp" android:orientation="horizontal"> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:id="@+id/image_arrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/indicator_arrow" android:layout_centerInParent="true"/>
<!自定义ProgressBar的图片,和旋转持续的时间> <ProgressBar android:id="@+id/pb_intedimanate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:indeterminate="true" android:visibility="invisible" android:indeterminateDuration="1000" android:indeterminateDrawable="@drawable/intediminate_drawable" android:layout_centerInParent="true" /> </RelativeLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginBottom="10dp" android:orientation="vertical" android:gravity="center" android:layout_marginLeft="20dp"> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:textColor="#aa000000" android:text="下拉刷新" /> <TextView android:id="@+id/tv_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:textColor="#66666666" android:layout_marginTop="5dp" android:text="最后刷新:2012-21-21" /> </LinearLayout> </LinearLayout>
加载底部刷新布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal"> <ProgressBar android:id="@+id/pb_footer" android:layout_width="wrap_content" android:layout_height="wrap_content" android:indeterminate="true" android:indeterminateDuration="1000" android:layout_marginTop="5dp" android:indeterminateDrawable="@drawable/intediminate_drawable" android:layout_centerInParent="true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv_footername" android:layout_marginLeft="15dp" android:layout_marginTop="5dp" android:textSize="20sp" android:textColor="#aa000000" android:text="正在加载,请稍后..."/> </LinearLayout>布局文件代码:
public class RefreshView extends ListView { private View listViewHeader; private ImageView image_arrow; private ProgressBar pb_intediminate; private TextView tv_name; private TextView tv_time; private int listViewHeaderHeight; private int downY; //按下时的Y坐标 final int PULLREFRESH=0; //下拉刷新 final int RELEASEFRESH=1; //正在刷新 final int REFRESHING=2; //正在刷新装填 int CURRENTSTATEREFRESH=PULLREFRESH; private View footerView; private int footerViewHeight; private boolean isLoading=false;//判断当前是否是加载更多 // AttributeSet 封装属性的列表,比如xml文件的一系列属性 public RefreshView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public RefreshView(Context context) { super(context); init(); } private void init(){ initHeaderView(); initAnimation(); initFooterView(); } private void initHeaderView(){ /* 获取头文件高度第一种方法,在头文件布局onLayout()完成后,再设置其高度 listViewHeader = View.inflate(MainActivity.this, R.layout.layout_header, null); listViewHeader.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { listViewHeaderHeight=listViewHeader.getHeight(); } }); */ //一般为更为方便,采用测量获取头文件的高度,这是第二种方法,不过,首先需要onMeasure方法执行完; listViewHeader=View.inflate(getContext(),R.layout.layout_header,null); image_arrow = (ImageView) listViewHeader.findViewById(R.id.image_arrow); pb_intediminate = (ProgressBar) listViewHeader.findViewById(R.id.pb_intedimanate); tv_name = (TextView) listViewHeader.findViewById(R.id.tv_name); tv_time = (TextView) listViewHeader.findViewById(R.id.tv_time); listViewHeader.measure(0,0); //主动通知系统测量该View listViewHeaderHeight = listViewHeader.getMeasuredHeight(); //通过设置负高度,将头文件隐藏 listViewHeader.setPadding(0, -listViewHeaderHeight, 0, 0); addHeaderView(listViewHeader); //RefreshView天然拥有头文件 } private void initFooterView() { footerView = View.inflate(getContext(), R.layout.layout_footer, null); footerView.measure(0, 0); //主动通知系统测量该View footerViewHeight = footerView.getMeasuredHeight(); //通过设置负高度,将底文件隐藏 footerView.setPadding(0, -footerViewHeight, 0, 0); addFooterView(footerView); } /* 判断触摸事件 从而执行哪段动画 */ @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()){ case MotionEvent.ACTION_DOWN: downY = (int) ev.getY(); break; case MotionEvent.ACTION_MOVE: //如果正在处于刷新状态,则停止滑动 if (CURRENTSTATEREFRESH==REFRESHING){ break; } int daltaY= (int) (ev.getY()-downY); //判断用户手指滑动方向的距离,如果向下移动,Y 是正的,如果向上滑动,Y是负数 int paddingTop=-listViewHeaderHeight+daltaY; // 让头文件HeaderView 随着手指一起滑动 if (paddingTop >= (-listViewHeaderHeight)&&getFirstVisiblePosition()==0) { listViewHeader.setPadding(0,paddingTop,0,0); if(paddingTop>=0&&(CURRENTSTATEREFRESH==PULLREFRESH)){ //由下拉刷新到松开刷新状态 CURRENTSTATEREFRESH=RELEASEFRESH; refreshHeaderView(); break; }else if(paddingTop<0&&(CURRENTSTATEREFRESH==RELEASEFRESH)){ //由松开刷新到下拉刷新状态 CURRENTSTATEREFRESH=PULLREFRESH; refreshHeaderView(); } return true; //拦截TouchView 不让ListView处理ACTION_Move时间,但是会造成listView无法滑动 } break; case MotionEvent.ACTION_UP: //回到隐藏 if(CURRENTSTATEREFRESH==PULLREFRESH){ listViewHeader.setPadding(0,-listViewHeaderHeight,0,0); }else if(CURRENTSTATEREFRESH==RELEASEFRESH) { //由松开刷新到正在刷新状态 listViewHeader.setPadding(0, 0, 0, 0); CURRENTSTATEREFRESH = REFRESHING; refreshHeaderView(); if(lisener!=null){ lisener.onPullRefresh(); } } if (getLastVisiblePosition() == (getCount() - 1) && !isLoading) { footerView.setPadding(0, 0, 0, 0); //显示出footerView setSelection(getCount()); //让 listView 最后一条显示出来 isLoading = true; if(lisener!=null){ lisener.onLoadingMoreRefresh(); } } } return super.onTouchEvent(ev); } /* 通过状态,判断是哪种,改变箭头指向 */ private void refreshHeaderView(){ switch (CURRENTSTATEREFRESH){ case PULLREFRESH: tv_name.setText("下拉刷新"); image_arrow.startAnimation(downRotateAnimation); break; case RELEASEFRESH: tv_name.setText("松开刷新"); image_arrow.startAnimation(upRotateAnimaition); break; case REFRESHING: image_arrow.clearAnimation();//因为旋转动画可能没执行完 image_arrow.setVisibility(View.INVISIBLE); pb_intediminate.setVisibility(View.VISIBLE); tv_name.setText("正在刷新..."); break; } } /* 获取最新时间 */ private String getCurrentTime(){ SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yy-MM-dd HH-mm-ss"); return simpleDateFormat.format(new Date()); } /* 定义旋转图标,以及它的旋转方向 */ private RotateAnimation upRotateAnimaition,downRotateAnimation; private void initAnimation() { upRotateAnimaition = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); upRotateAnimaition.setDuration(300); upRotateAnimaition.setFillAfter(true); downRotateAnimation=new RotateAnimation(-180,-360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); downRotateAnimation.setDuration(300); downRotateAnimation.setFillAfter(true); } /* 完成刷新,在你获取完数据并更新完UI的时候调用该方法,重置状态 */ public void completeRefresh(){ //重置底部文件 if (isLoading){ footerView.setPadding(0,-footerViewHeight,0,0); isLoading=false; }else{ //重置头部文件 listViewHeader.setPadding(0,-listViewHeaderHeight,0,0); //重置刷新,隐藏headerView CURRENTSTATEREFRESH=PULLREFRESH; pb_intediminate.setVisibility(View.INVISIBLE); image_arrow.setVisibility(VISIBLE); tv_name.setText("下拉刷新"); tv_time.setText("最后刷新:"+getCurrentTime()); } } /* 定义接口,便于外部创建接口,并实现接口的方法 */ onRefreshLisener lisener; public void setOnRefreshLisener(onRefreshLisener lisener){ this.lisener=lisener; } public interface onRefreshLisener{ void onPullRefresh(); void onLoadingMoreRefresh(); } }主文件代码:
public class MainActivity extends AppCompatActivity { /* handler处理机制,一个延时操作,一个更新UI */ Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { // 更新UI,通知adapter更新数据 myAdater.notifyDataSetChanged(); //重置状态,一个上拉刷新,;一个下拉刷新,待请求数据后,重置其状态,隐藏 refreshView.completeRefresh(); } }; private RefreshView refreshView; private ArrayList<String> arrayList; private MyAdapter myAdater; @Override protected void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); //去掉标题栏 //全屏显示 this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); super.onCreate(savedInstanceState); initView(); initData(); } /* 初始化ListView数据 */ private void initView() { setContentView(R.layout.activity_main); refreshView = (RefreshView) findViewById(R.id.refreshListView); myAdater=new MyAdapter(); } private void initData() { arrayList = new ArrayList<String>(); for (int i = 0; i < 15; i++) { arrayList.add("listView原来的数据:" + i); } refreshView.setAdapter(myAdater); refreshView.setOnRefreshLisener(new RefreshView.onRefreshLisener() { @Override public void onPullRefresh() { //此时需要联网请求服务器数据,更新UI,false表示 上拉请求数据 requestDataFromServer(false); } @Override public void onLoadingMoreRefresh() { requestDataFromServer(true); } }); } private void requestDataFromServer(final boolean isLoadingMore){ new Thread(){ public void run(){ SystemClock.sleep(2000); //模拟请求服务器数据的耗时操作 if(isLoadingMore){ arrayList.add("下拉的数据:1"); arrayList.add("下拉的数据:2"); arrayList.add("下拉的数据:3"); arrayList.add("下拉的数据:4"); }else{ arrayList.add(0, "下拉刷新的数据,夏老师"); arrayList.add(1,"下拉刷新的数据,work harder"); } handler.sendEmptyMessage(0); } }.start(); } /* 初始化ListView的Adapter */ class MyAdapter extends BaseAdapter { @Override public int getCount() { return arrayList.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { TextView textView = new TextView(MainActivity.this); textView.setText(arrayList.get(position)); textView.setPadding(20, 20, 20, 20); textView.setTextSize(18); return textView; } } }