选择ViewGroup而不是单个View的理由就是通用性
下拉过程分为3个状态
1.下拉,未满足释放刷新的高度,显示“下拉刷新”
2.下拉,满足释放刷新的高度,显示“释放刷新”
3.释放,显示“刷新”
接着我们Touch事件 有
1. 按下
2.按下移动
3.松开
<<刷新控件Demo下载地址>>
接着必须要知道的方法onInterceptTouchEvent,用于在OnTouchEvent之前截取一次事件
public boolean onInterceptTouchEvent(MotionEvent event)
return false;//表示未消费此事件,将事件传递下一层View return true;//表示消费了此事件,将不再下传
用于主要的逻辑处理
public boolean onTouchEvent(MotionEvent event)
通过判断HeaderView的TopMargin来判断是否满足释放刷新条件
Code:
public class RefreshView extends LinearLayout{ private Scroller scroller; private LinearLayout refreshView; private ImageView refreshIndicatorView; private int refreshTargetTop = -60; private ProgressBar bar; private TextView downTextView; private TextView timeTextView; private LinearLayout refereshLinearLayout; private RefreshListener refreshListener; private String downTextString; private String releaseTextString; private Long refreshTime = null; private int lastX; private int lastY; private boolean isDragging = false;// 拉动标记 private boolean isRefreshEnabled = true;// 是否可刷新标记 private boolean isRefreshing = false;// 在刷新中标记 private Context mContext; public RefreshView(Context context) { // TODO Auto-generated constructor stub this(context, null); } public RefreshView(Context context,AttributeSet attrs) { super(context,attrs); // TODO Auto-generated constructor stub mContext = context; init(); } private void init(){ scroller = new Scroller(mContext); refreshView =(LinearLayout)View.inflate(mContext, R.layout.refresh_top_item, null); // 拉动时候的视图 refreshIndicatorView = (ImageView)refreshView.findViewById(R.id.indicator); downTextView = (TextView)refreshView.findViewById(R.id.refresh_hint); // 刷新时候的视图 refereshLinearLayout = (LinearLayout)refreshView .findViewById(R.id.referesh_linearlayout); bar = (ProgressBar)refreshView.findViewById(R.id.progress); timeTextView =(TextView)refreshView.findViewById(R.id.refresh_time); LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT , -refreshTargetTop); lp.topMargin = refreshTargetTop; lp.gravity = Gravity.CENTER; addView(refreshView,lp); downTextString = mContext.getResources() .getString(R.string.refresh_down_text); releaseTextString = mContext.getResources() .getString(R.string.refresh_release_text); } // 首次截取 事件 @Override public boolean onInterceptTouchEvent(MotionEvent event) { // TODO Auto-generated method stub int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastY = y; break; case MotionEvent.ACTION_MOVE: int m = y - lastY; lastY = y; if(canScroll(m)){ return true; } break; } return false; } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub if(isRefreshing) return false; int y = (int) event.getY(); switch(event.getAction()){ case MotionEvent.ACTION_DOWN: lastY = y; break; case MotionEvent.ACTION_MOVE: int m = y - lastY; doMovement(m); lastY = y; break; case MotionEvent.ACTION_UP: fling(); break; } return true; } private void fling(){ if(isRefreshing) return; LinearLayout.LayoutParams lp = (LayoutParams)refreshView .getLayoutParams(); if(lp.topMargin > 0){ refresh(); }else{ returnInitState(); } } private void returnInitState() { // TODO Auto-generated method stub LinearLayout.LayoutParams lp = (LayoutParams)refreshView .getLayoutParams(); int i = lp.topMargin; scroller.startScroll(0, i, 0, refreshTargetTop - i);// 回滚到初始状态 invalidate(); } private void refresh() { // TODO Auto-generated method stub LinearLayout.LayoutParams lp = (LayoutParams)refreshView .getLayoutParams(); int i = lp.topMargin; refreshIndicatorView.setVisibility(View.GONE); downTextView.setVisibility(View.GONE); refereshLinearLayout.setVisibility(View.VISIBLE); // 回滚到第一格位置 scroller.startScroll(0, i, 0, -i); invalidate(); if(refreshListener != null){ refreshListener.onRefresh(this); isRefreshing = true; } } public void finishRefresh() { LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.refreshView .getLayoutParams(); int i = lp.topMargin; scroller.startScroll(0, i, 0, refreshTargetTop); invalidate(); // refreshIndicatorView.setVisibility(View.VISIBLE); // timeTextView.setVisibility(View.VISIBLE); isRefreshing = false; setRefreshDate(Calendar.getInstance().getTime()); } @Override public void computeScroll() { // TODO Auto-generated method stub //super.computeScroll(); if(scroller.computeScrollOffset()){ int i = this.scroller.getCurrY(); LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.refreshView .getLayoutParams(); lp.topMargin = i; refreshView.setLayoutParams(lp); refreshView.invalidate(); invalidate(); } } private void doMovement(int moveY){ LinearLayout.LayoutParams lp = (LayoutParams)refreshView.getLayoutParams(); lp.topMargin = (int)(lp.topMargin + moveY * 0.3);// 修改上边距 refreshView.setLayoutParams(lp); refreshView.invalidate(); invalidate(); if(refreshTime != null) setRefreshTime(refreshTime); downTextView.setVisibility(View.VISIBLE); refreshIndicatorView.setVisibility(View.VISIBLE); if(lp.topMargin > 0){ downTextView.setText(mContext.getResources().getString(R.string.refresh_release_text)); refreshIndicatorView.setImageResource(R.drawable.refresh_arrow_up); }else{ downTextView.setText(mContext.getResources().getString(R.string.refresh_down_text)); refreshIndicatorView.setImageResource(R.drawable.refresh_arrow_down); } } private void setRefreshTime(Long time){ refreshTime = time; } public void setRefreshEnabled(boolean b) { this.isRefreshEnabled = b; } public void setRefreshListener(RefreshListener listener) { this.refreshListener = listener; } private void setRefreshDate(Date date) { SimpleDateFormat format = new SimpleDateFormat("MM-dd hh:mm"); timeTextView.setText("更新与:" + format.format(date)); } private boolean canScroll(int moveY){ View childView; if(moveY < 0){ return false; } if(getChildCount() > 1){ childView = this.getChildAt(1); if(childView instanceof ListView){ if(((ListView) childView).getFirstVisiblePosition() == 0) return true; else return false; }else if (childView instanceof ScrollView){ if(((ScrollView)childView).getScrollY() == 0) return true; else return false; }else if(childView instanceof GridView){ if(((GridView) childView).getFirstVisiblePosition() == 0) return true; else return false; } } return true; } public interface RefreshListener { public void onRefresh(RefreshView view); } }
<?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="match_parent" android:background="#EEEEEEEE" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal" > <ImageView android:id="@+id/indicator" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/refresh_hint" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:id="@+id/referesh_linearlayout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" /> <ProgressBar android:id="@+id/progress" style="?android:attr/progressBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="正在获取数据..." /> <TextView android:id="@+id/refresh_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="更新与:" /> </LinearLayout> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" /> </LinearLayout> </LinearLayout>
Adapter
import java.util.List; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; public class MyListAdapter extends BaseAdapter { List<String> list; @Override public int getCount() { // TODO Auto-generated method stub return list.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return list.get(list.size()-position-1); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return list.size()-position-1; } @Override public View getView(int position, View convertView, ViewGroup parent) { TextView textview = new TextView(parent.getContext()); textview.setText(list.get(list.size()-position-1)); return textview; } public List<String> getList() { return list; } public void setList(List<String> list) { this.list = list; } }
import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.widget.ListView; import com.ishow.chenjq.RefreshView; import com.ishow.chenjq.RefreshView.RefreshListener;; public class MainActivity extends Activity { private RefreshView refreshableLinearLayout; private ListView listView; private MyListAdapter adapter; private List<String> list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); preinitUI(); initUI(); } private void preinitUI() { adapter = new MyListAdapter(); list = new ArrayList<String>(); addLists(10); adapter.setList(list); } private void initUI() { setContentView(R.layout.referesh_view); refreshableLinearLayout = (RefreshView) findViewById(R.id.refresh_root); refreshableLinearLayout.setRefreshListener(listener); listView = (ListView) findViewById(R.id.listview); listView.setAdapter(adapter); } RefreshListener listener = new RefreshListener() { @Override public void onRefresh(RefreshView view) { referesh(); } }; protected void referesh() { new AsyncTask<Void, Void, Void>() { protected Void doInBackground(Void... params) { try { Thread.sleep(2000); } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Void result) { addLists(1); refreshableLinearLayout.finishRefresh(); } }.execute(); } private void addLists(int n){ n += list.size(); for(int i=list.size();i<n;i++){ list.add("选项"+i); } } }
<?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="match_parent" android:orientation="vertical" > <com.ishow.chenjq.RefreshView android:id="@+id/refresh_root" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@+id/listview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingTop="100px" android:paddingBottom="80px" android:paddingRight="90px" android:paddingLeft="10px" android:cacheColorHint="@android:color/transparent" android:descendantFocusability="blocksDescendants" android:divider="#FFCC00" android:dividerHeight="0dip" /> </com.ishow.chenjq.RefreshView> </LinearLayout>