ListView下拉刷新
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ListView下拉刷新相关的知识,希望对你有一定的参考价值。
自定义ListView:
1 package com.yuanlei.my.listviewrefresh.view; 2 3 import android.content.Context; 4 import android.util.AttributeSet; 5 import android.util.Log; 6 import android.view.LayoutInflater; 7 import android.view.MotionEvent; 8 import android.view.View; 9 import android.view.ViewGroup; 10 import android.view.animation.RotateAnimation; 11 import android.widget.AbsListView; 12 import android.widget.ImageView; 13 import android.widget.ListView; 14 import android.widget.ProgressBar; 15 import android.widget.TextView; 16 17 import com.yuanlei.my.listviewrefresh.R; 18 19 import java.text.SimpleDateFormat; 20 import java.util.Date; 21 22 /** 23 * Created by 袁磊 on 2016/11/4. 24 */ 25 public class ReFreshListView extends ListView implements AbsListView.OnScrollListener { 26 View header;//顶部布局文件 27 int headerHeight;//顶部布局文件的高度 28 int firstVisibleItem;//当前第一个可见的Item的位置 29 int scrollState;//listView当前滚动状态 30 boolean isRemark;//标记,当前是在listView最顶端摁下的 31 int startY;//摁下时的Y值 32 33 int state;//当前的状态 34 final int NONE = 0;//正常状态 35 final int PULL = 1;//提示下拉状态 36 final int RELESE = 2;//提示释放状态 37 final int REFRESHING = 3;//刷新状态 38 39 private IRefreshListener iRefreshListener;//刷新数据的接口 40 41 public ReFreshListView(Context context) { 42 super(context); 43 initView(context); 44 45 } 46 47 public ReFreshListView(Context context, AttributeSet attrs) { 48 super(context, attrs); 49 initView(context); 50 } 51 52 public ReFreshListView(Context context, AttributeSet attrs, int defStyleAttr) { 53 super(context, attrs, defStyleAttr); 54 initView(context); 55 } 56 57 /** 58 * 初始化界面,添加顶部布局文件到ListView 59 * 60 * @param context 61 */ 62 private void initView(Context context) { 63 LayoutInflater inflater = LayoutInflater.from(context); 64 header = inflater.inflate(R.layout.header_layout, null); 65 measureView(header); 66 headerHeight = header.getMeasuredHeight(); 67 Log.i("TAG", "headerHeight=" + headerHeight); 68 topPadding(-headerHeight); 69 this.addHeaderView(header); 70 this.setOnScrollListener(this); 71 } 72 73 /** 74 * 通知父布局,占用的宽,高 75 * 76 * @param view 77 */ 78 private void measureView(View view) { 79 ViewGroup.LayoutParams p = view.getLayoutParams(); 80 if (p == null) { 81 p = new ViewGroup.LayoutParams(ViewGroup. 82 LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 83 } 84 int width = ViewGroup.getChildMeasureSpec(0, 0, p.width); 85 int height; 86 int tempHeight = p.height; 87 if (tempHeight > 0) { 88 height = MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY); 89 } else { 90 height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 91 } 92 view.measure(width, height); 93 } 94 95 /** 96 * 设置header布局上边距 97 * 98 * @param topPadding 99 */ 100 private void topPadding(int topPadding) { 101 header.setPadding(header.getPaddingLeft(), topPadding, header.getPaddingRight(), header.getPaddingBottom()); 102 header.invalidate(); 103 } 104 105 @Override 106 public void onScrollStateChanged(AbsListView view, int scrollState) { 107 this.scrollState = scrollState; 108 } 109 110 @Override 111 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 112 this.firstVisibleItem = firstVisibleItem; 113 } 114 115 @Override 116 public boolean onTouchEvent(MotionEvent ev) { 117 switch (ev.getAction()) { 118 case MotionEvent.ACTION_DOWN: 119 if (firstVisibleItem == 0) { 120 isRemark = true; 121 startY = (int) ev.getY(); 122 } 123 break; 124 case MotionEvent.ACTION_MOVE: 125 onMove(ev); 126 break; 127 case MotionEvent.ACTION_UP: 128 if (state == RELESE) { 129 state = REFRESHING; 130 //加载最新数据 131 refreshViewByState(); 132 iRefreshListener.onRefresh(); 133 } else if (state == PULL) { 134 state = NONE; 135 isRemark = false; 136 refreshViewByState(); 137 } 138 break; 139 } 140 return super.onTouchEvent(ev); 141 } 142 143 /** 144 * 判断移动过程操作 145 * 146 * @param ev 147 */ 148 private void onMove(MotionEvent ev) { 149 if (!isRemark) { 150 return; 151 } 152 int tempY = (int) ev.getY(); 153 int space = tempY - startY; 154 int topPadding = space - headerHeight; 155 switch (state) { 156 case NONE: 157 if (space > 0) { 158 state = PULL; 159 refreshViewByState(); 160 } 161 break; 162 case PULL: 163 topPadding(topPadding); 164 if (space > headerHeight + 30 && scrollState == SCROLL_STATE_TOUCH_SCROLL) { 165 state = RELESE; 166 refreshViewByState(); 167 } 168 break; 169 case RELESE: 170 topPadding(topPadding); 171 if (space < headerHeight + 30) { 172 state = PULL; 173 refreshViewByState(); 174 } else if (space <= 0) { 175 state = NONE; 176 isRemark = false; 177 refreshViewByState(); 178 } 179 break; 180 } 181 } 182 183 /** 184 * 根据当前状态,改变界面显示 185 */ 186 private void refreshViewByState() { 187 TextView tip = (TextView) header.findViewById(R.id.tv_header_hint); 188 ImageView arrow = (ImageView) header.findViewById(R.id.iv_header_arrow); 189 ProgressBar progress = (ProgressBar) findViewById(R.id.pb_header_refresh); 190 RotateAnimation anim = new RotateAnimation(0, 180, 191 RotateAnimation.RELATIVE_TO_SELF, 0.5f, 192 RotateAnimation.RELATIVE_TO_SELF, 0.5f); 193 anim.setDuration(500); 194 anim.setFillAfter(true); 195 RotateAnimation anim1 = new RotateAnimation(180, 0, 196 RotateAnimation.RELATIVE_TO_SELF, 0.5f, 197 RotateAnimation.RELATIVE_TO_SELF, 0.5f); 198 anim1.setDuration(500); 199 anim1.setFillAfter(true); 200 switch (state) { 201 case NONE: 202 arrow.clearAnimation(); 203 topPadding(-headerHeight); 204 break; 205 case PULL: 206 arrow.setVisibility(View.VISIBLE); 207 progress.setVisibility(View.GONE); 208 tip.setText("下拉可以刷新"); 209 arrow.clearAnimation(); 210 arrow.setAnimation(anim1); 211 break; 212 case RELESE: 213 arrow.setVisibility(View.VISIBLE); 214 progress.setVisibility(View.GONE); 215 tip.setText("松开可以刷新"); 216 arrow.clearAnimation(); 217 arrow.setAnimation(anim); 218 break; 219 case REFRESHING: 220 topPadding(50); 221 arrow.setVisibility(View.GONE); 222 progress.setVisibility(View.VISIBLE); 223 tip.setText("正在刷新"); 224 arrow.clearAnimation(); 225 break; 226 } 227 } 228 229 /** 230 * 获取完数据后 231 */ 232 public void refreshComplete() { 233 state = NONE; 234 isRemark = false; 235 refreshViewByState(); 236 TextView lastUpdateTime = (TextView) header.findViewById(R.id.tv_header_time); 237 SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日hh:mm:ss"); 238 Date date = new Date(System.currentTimeMillis()); 239 String time = format.format(date); 240 lastUpdateTime.setText(time); 241 } 242 243 public void setInterface(IRefreshListener iRefreshListener) { 244 this.iRefreshListener = iRefreshListener; 245 } 246 247 /** 248 * 刷新数据的接口 249 */ 250 public interface IRefreshListener { 251 void onRefresh(); 252 } 253 }
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical"> 6 7 <RelativeLayout 8 android:layout_width="match_parent" 9 android:layout_height="wrap_content" 10 android:layout_marginBottom="10dp" 11 android:layout_marginTop="10dp"> 12 13 <LinearLayout 14 android:id="@+id/ll_header" 15 android:layout_width="wrap_content" 16 android:layout_height="wrap_content" 17 android:layout_centerInParent="true" 18 android:gravity="center" 19 android:orientation="vertical"> 20 21 <TextView 22 android:id="@+id/tv_header_hint" 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content" 25 android:text="下拉可以刷新" /> 26 27 <TextView 28 android:id="@+id/tv_header_time" 29 android:layout_width="wrap_content" 30 android:layout_height="wrap_content" 31 android:text="0000年00月00日" /> 32 </LinearLayout> 33 34 <ImageView 35 android:id="@+id/iv_header_arrow" 36 android:layout_width="wrap_content" 37 android:layout_height="wrap_content" 38 android:layout_centerVertical="true" 39 android:layout_marginRight="20dp" 40 android:layout_toLeftOf="@id/ll_header" 41 android:src="@mipmap/pull_to_refresh_arrow" /> 42 43 <ProgressBar 44 android:id="@+id/pb_header_refresh" 45 style="?android:attr/progressBarStyleSmall" 46 android:layout_width="wrap_content" 47 android:layout_height="wrap_content" 48 android:layout_centerVertical="true" 49 android:layout_marginRight="20dp" 50 android:layout_toLeftOf="@id/ll_header" 51 android:visibility="gone" /> 52 </RelativeLayout> 53 54 55 </LinearLayout>
使用:
MainActivity:
1 package com.yuanlei.my.listviewrefresh; 2 3 import android.os.Bundle; 4 import android.os.Handler; 5 import android.support.v7.app.AppCompatActivity; 6 7 import com.yuanlei.my.listviewrefresh.view.ReFreshListView; 8 9 import java.util.ArrayList; 10 import java.util.List; 11 12 public class MainActivity extends AppCompatActivity implements ReFreshListView.IRefreshListener { 13 private ReFreshListView refreshLvContent; 14 private MyAdapter adapter; 15 private List<Bean> list; 16 17 @Override 18 protected void onCreate(Bundle savedInstanceState) { 19 super.onCreate(savedInstanceState); 20 setContentView(R.layout.activity_main); 21 refreshLvContent = (ReFreshListView) findViewById(R.id.lv_main_content); 22 setData(); 23 showData(list); 24 } 25 26 private void setData() { 27 list = new ArrayList<>(); 28 for (int i = 0; i < 10; i++) { 29 Bean bean = new Bean(); 30 bean.setIcon(R.mipmap.ic_launcher); 31 bean.setText("默认的数据" + i + ""); 32 list.add(bean); 33 } 34 } 35 36 private void showData(List<Bean> list) { 37 if (adapter == null) { 38 refreshLvContent.setInterface(this); 39 adapter = new MyAdapter(list, this); 40 refreshLvContent.setAdapter(adapter); 41 } else { 42 adapter.onDataChange(list); 43 } 44 } 45 46 private void setRefreshData() { 47 for (int i = 0; i < 2; i++) { 48 Bean bean = new Bean(); 49 bean.setIcon(R.mipmap.ic_launcher); 50 bean.setText("刷新的数据+++++" + i + ""); 51 list.add(0, bean); 52 } 53 } 54 55 @Override 56 public void onRefresh() { 57 Handler handler = new Handler(); 58 handler.postDelayed(new Runnable() { 59 @Override 60 public void run() { 61 setRefreshData();//获取最新数据 62 showData(list);//通知界面 显示 63 refreshLvContent.refreshComplete();//通知ListView刷新数据完毕 64 } 65 }, 2000); 66 } 67 }
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent"> 5 6 <com.yuanlei.my.listviewrefresh.view.ReFreshListView 7 android:id="@+id/lv_main_content" 8 android:layout_width="match_parent" 9 android:layout_height="match_parent" /> 10 </RelativeLayout>
Bean:
1 package com.yuanlei.my.listviewrefresh; 2 3 /** 4 * Created by 袁磊 on 2016/11/4. 5 */ 6 public class Bean { 7 private int icon; 8 private String text; 9 10 public String getText() { 11 return text; 12 } 13 14 public void setText(String text) { 15 this.text = text; 16 } 17 18 public int getIcon() { 19 return icon; 20 } 21 22 public void setIcon(int icon) { 23 this.icon = icon; 24 } 25 }
MyAdapter:
1 package com.yuanlei.my.listviewrefresh; 2 3 import android.content.Context; 4 import android.view.LayoutInflater; 5 import android.view.View; 6 import android.view.ViewGroup; 7 import android.widget.BaseAdapter; 8 import android.widget.ImageView; 9 import android.widget.TextView; 10 11 import java.util.List; 12 13 /** 14 * Created by 袁磊 on 2016/11/4. 15 */ 16 public class MyAdapter extends BaseAdapter { 17 private List<Bean> list; 18 private LayoutInflater inflater; 19 20 public MyAdapter(List<Bean> list, Context context) { 21 this.list = list; 22 inflater = LayoutInflater.from(context); 23 } 24 25 public void onDataChange(List<Bean> list) { 26 this.list = list; 27 this.notifyDataSetChanged(); 28 } 29 30 @Override 31 public int getCount() { 32 return list == null ? 0 : list.size(); 33 } 34 35 @Override 36 public Object getItem(int position) { 37 return list.get(position); 38 } 39 40 @Override 41 public long getItemId(int position) { 42 return position; 43 } 44 45 @Override 46 public View getView(int position, View convertView, ViewGroup parent) { 47 Holder holder = null; 48 if (convertView == null) { 49 convertView = inflater.inflate(R.layout.item_list, null); 50 holder = new Holder(); 51 holder.ivIcon = (ImageView) convertView.findViewById(R.id.iv_item_list); 52 holder.tvText = (TextView) convertView.findViewById(R.id.tv_item_list); 53 convertView.setTag(holder); 54 } else { 55 holder = (Holder) convertView.getTag(); 56 } 57 holder.ivIcon.setImageResource(list.get(position).getIcon()); 58 holder.tvText.setText(list.get(position).getText()); 59 return convertView; 60 } 61 62 class Holder { 63 ImageView ivIcon; 64 TextView tvText; 65 } 66 }
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:gravity="center_vertical" 6 android:orientation="horizontal"> 7 8 <ImageView 9 android:id="@+id/iv_item_list" 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" 12 android:src="@mipmap/ic_launcher" /> 13 14 <TextView 15 android:id="@+id/tv_item_list" 16 android:layout_width="0dp" 17 android:layout_height="wrap_content" 18 android:layout_weight="1" 19 android:text="默认数据" 20 android:textSize="16sp" /> 21 22 </LinearLayout>
以上是关于ListView下拉刷新的主要内容,如果未能解决你的问题,请参考以下文章