国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android刷新加載框架詳解

2019-10-22 18:20:31
字體:
來源:轉載
供稿:網友

本文實例為大家分享了Android刷新加載框架的具體代碼,供大家參考,具體內容如下

1.定義一個接口控制下拉和上拉

public interface Pullable {  /**   * 是否可下拉   */  boolean canPullDown();  /**   * 是否可上拉   */  boolean canPullUp();}

2.定義一個刷新加載布局

public class PullToRefreshLayout extends RelativeLayout {  /**   * 頭   */  private View headView;//頭視圖  private ImageView headIv;//頭圖標  private TextView headTv;//頭文字  private int headHeight;//頭高度  private float headBorder;//頭臨界  /**   * 拉   */  private View pullView;//拉視圖  private int pullHeight;//拉高度  private int pullWidth;//拉寬度  /**   * 尾   */  private View footView;//尾視圖  private ImageView footIv;//尾圖標  private TextView footTv;//尾文字  private int footHeight;//尾高度  private float footBorder;//尾臨界  /**   * 狀態   */  public static final int INIT = 0;//初始  public static final int RELEASE_TO_REFRESH = 1;//釋放刷新  public static final int REFRESHING = 2;//正在刷新  public static final int RELEASE_TO_LOAD = 3;//釋放加載  public static final int LOADING = 4;//正在加載  public static final int DONE = 5;//完成  private int state = INIT;  /**   * 接口   */  private OnRefreshListener mListener;  private float downY;//按下時Y坐標  private float lastY;//上一個Y坐標  private float pullDownY = 0;//下拉偏移量  private float pullUpY = 0;//上拉偏移量  private int offset;//偏移量  /**   * 動畫   */  private RotateAnimation rotateAnimation;  /**   * 線程   */  private Handler handler = new Handler() {    @Override    public void handleMessage(Message msg) {      super.handleMessage(msg);      if (msg != null) {        switch (msg.what) {          case 1:            headIv.clearAnimation();            break;          case 2:            footIv.clearAnimation();            break;          default:            break;        }        pullDownY = 0;        pullUpY = 0;        requestLayout();        state = INIT;        refreshViewByState();        isTouch = true;      }    }  };  /**   * 第一次執行布局   */  private boolean isLayout = false;  /**   * 在刷新過程中滑動操作   */  private boolean isTouch = false;  /**   * 手指滑動距離與下拉頭的滑動距離比,中間會隨正切函數變化   */  private float radio = 2;  /**   * 過濾多點觸碰   */  private int mEvents;  /**   * 這兩個變量用來控制pull的方向,如果不加控制,當情況滿足可上拉又可下拉時沒法下拉   */  private boolean canPullDown = true;  private boolean canPullUp = true;  public void setOnRefreshListener(OnRefreshListener listener) {    mListener = listener;  }  public PullToRefreshLayout(Context context) {    super(context);    initView(context);  }  public PullToRefreshLayout(Context context, AttributeSet attrs) {    super(context, attrs);    initView(context);  }  public PullToRefreshLayout(Context context, AttributeSet attrs, int defStyle) {    super(context, attrs, defStyle);    initView(context);  }  private void initView(Context context) {    rotateAnimation = (RotateAnimation) AnimationUtils.loadAnimation(context, R.anim.rotating);  }  private void refreshViewByState() {    switch (state) {      case INIT:        // 下拉布局初始狀態        headIv.setImageResource("下拉刷新顯示的圖片");        headTv.setText("下拉刷新");        // 上拉布局初始狀態        footIv.setImageResource("上拉加載顯示的圖片");        footTv.setText("上拉加載");        break;      case RELEASE_TO_REFRESH:        // 釋放刷新狀態        headIv.setImageResource("釋放刷新顯示的圖片");        headTv.setText("釋放刷新");        break;      case REFRESHING:        // 正在刷新狀態        headIv.setImageResource("正在刷新顯示的圖片");        headTv.setText("正在刷新");        break;      case RELEASE_TO_LOAD:        // 釋放加載狀態        footIv.setImageResource("釋放加載顯示的圖片");        footTv.setText("釋放加載");        break;      case LOADING:        // 正在加載狀態        footIv.setImageResource("正在加載顯示的圖片");        footTv.setText("正在加載");        break;      case DONE:        // 刷新或加載完畢,啥都不做        break;    }  }  /**   * 不限制上拉或下拉   */  private void releasePull() {    canPullDown = true;    canPullUp = true;  }    @Override  public boolean dispatchTouchEvent(MotionEvent ev) {    switch (ev.getActionMasked()) {      case MotionEvent.ACTION_DOWN:        downY = ev.getY();        lastY = downY;        mEvents = 0;        releasePull();        if (state != REFRESHING && state != LOADING) {          isTouch = true;        }        break;      case MotionEvent.ACTION_POINTER_DOWN:      case MotionEvent.ACTION_POINTER_UP:        // 過濾多點觸碰        mEvents = -1;        break;      case MotionEvent.ACTION_MOVE:        if (mEvents == 0) {          if (pullDownY > 0 || (((Pullable) pullView).canPullDown()              && canPullDown && state != LOADING && state != REFRESHING)) {            // 可以下拉,正在加載時不能下拉            // 對實際滑動距離做縮小,造成用力拉的感覺            pullDownY = pullDownY + (ev.getY() - lastY) / radio;            if (pullDownY < 0) {              pullDownY = 0;              canPullDown = false;              canPullUp = true;            }            if (pullDownY > getMeasuredHeight()) {              pullDownY = getMeasuredHeight();            }            if (state == REFRESHING) {              // 正在刷新的時候觸摸移動              isTouch = false;            }          } else if (pullUpY < 0              || (((Pullable) pullView).canPullUp() && canPullUp && state != REFRESHING && state != LOADING)) {            // 可以上拉,正在刷新時不能上拉            pullUpY = pullUpY + (ev.getY() - lastY) / radio;            if (pullUpY > 0) {              pullUpY = 0;              canPullDown = true;              canPullUp = false;            }            if (pullUpY < -getMeasuredHeight()) {              pullUpY = -getMeasuredHeight();            }            if (state == LOADING) {              // 正在加載的時候觸摸移動              isTouch = false;            }          }        }        if (isTouch) {          lastY = ev.getY();          if (pullDownY > 0 || pullUpY < 0) {            requestLayout();          }          if (pullDownY > 0) {            if (pullDownY <= headBorder && (state == RELEASE_TO_REFRESH || state == DONE)) {              // 如果下拉距離沒達到刷新的距離且當前狀態是釋放刷新,改變狀態為下拉刷新              state = INIT;              refreshViewByState();            }            if (pullDownY >= headBorder && state == INIT) {              // 如果下拉距離達到刷新的距離且當前狀態是初始狀態刷新,改變狀態為釋放刷新              state = RELEASE_TO_REFRESH;              refreshViewByState();            }          } else if (pullUpY < 0) {            // 下面是判斷上拉加載的,同上,注意pullUpY是負值            if (-pullUpY <= footBorder && (state == RELEASE_TO_LOAD || state == DONE)) {              state = INIT;              refreshViewByState();            }            // 上拉操作            if (-pullUpY >= footBorder && state == INIT) {              state = RELEASE_TO_LOAD;              refreshViewByState();            }          }          // 因為刷新和加載操作不能同時進行,所以pullDownY和pullUpY不會同時不為0,因此這里用(pullDownY +          // Math.abs(pullUpY))就可以不對當前狀態作區分了          if ((pullDownY + Math.abs(pullUpY)) > 8) {            // 防止下拉過程中誤觸發長按事件和點擊事件            ev.setAction(MotionEvent.ACTION_CANCEL);          }        }        break;      case MotionEvent.ACTION_UP:        if (pullDownY > headBorder || -pullUpY > footBorder) {          // 正在刷新時往下拉(正在加載時往上拉),釋放后下拉頭(上拉頭)不隱藏          isTouch = false;        }        if (state == RELEASE_TO_REFRESH) {          state = REFRESHING;          refreshViewByState();          // 刷新操作          if (mListener != null) {            canPullDown = false;            pullDownY = headBorder;            pullUpY = 0;            requestLayout();            headIv.startAnimation(rotateAnimation);            mListener.onRefresh(this);          }        } else if (state == RELEASE_TO_LOAD) {          state = LOADING;          refreshViewByState();          // 加載操作          if (mListener != null) {            canPullUp = false;            pullDownY = 0;            pullUpY = -footBorder;            requestLayout();            footIv.startAnimation(rotateAnimation);            mListener.onLoadMore(this);          }        } else {          pullDownY = 0;          pullUpY = 0;          requestLayout();        }      default:        break;    }    // 事件分發交給父類    super.dispatchTouchEvent(ev);    return true;  }  public void hideHeadView() {    handler.sendEmptyMessage(1);  }  public void hideFootView() {    handler.sendEmptyMessage(2);  }  private void initView() {    // 初始化下拉布局    headIv = (ImageView) headView.findViewById(R.id.iv_head);    headTv = (TextView) headView.findViewById(R.id.tv_head);    //初始化上拉布局    footIv = (ImageView) footView.findViewById(R.id.iv_foot);    footTv = (TextView) footView.findViewById(R.id.tv_foot);    refreshViewByState();  }  @Override  protected void onLayout(boolean changed, int l, int t, int r, int b) {    if (!isLayout) {      // 這里是第一次進來的時候做一些初始化      headView = getChildAt(0);      pullView = getChildAt(1);      footView = getChildAt(2);      headBorder = ((ViewGroup) headView).getChildAt(0).getMeasuredHeight();      footBorder = ((ViewGroup) footView).getChildAt(0).getMeasuredHeight();      headHeight = headView.getMeasuredHeight();      pullHeight = pullView.getMeasuredHeight();      footHeight = footView.getMeasuredHeight();      pullWidth = pullView.getMeasuredWidth();      initView();      isLayout = true;    }    // 改變子控件的布局,這里直接用(pullDownY + pullUpY)作為偏移量,這樣就可以不對當前狀態作區分    offset = (int) (pullDownY + pullUpY);    headView.layout(0, -headHeight + offset, pullWidth, offset);    pullView.layout(0, offset, pullWidth, pullHeight + offset);    footView.layout(0, pullHeight + offset, pullWidth, pullHeight + footHeight + offset);  }  public interface OnRefreshListener {    void onRefresh(PullToRefreshLayout pullToRefreshLayout);    void onLoadMore(PullToRefreshLayout pullToRefreshLayout);  }}

3.自定義View
ListView

public class PullableListView extends ListView implements Pullable {  public PullableListView(Context context) {    super(context);  }  public PullableListView(Context context, AttributeSet attrs) {    super(context, attrs);  }  public PullableListView(Context context, AttributeSet attrs, int defStyle) {    super(context, attrs, defStyle);  }  @Override  public boolean canPullDown() {    if (getCount() == 0) {      // 沒有item的時候也可以下拉刷新      return false;    } else if (getFirstVisiblePosition() == 0 && getChildAt(0).getTop() >= 0) {      // 滑到ListView的頂部了      return true;    } else      return false;  }  @Override  public boolean canPullUp() {    if (getCount() == 0) {      // 沒有item的時候也可以上拉加載      return false;    } else if (getLastVisiblePosition() == (getCount() - 1)) {      // 滑到底部了      if (getChildAt(getLastVisiblePosition() - getFirstVisiblePosition()) != null          && getChildAt(getLastVisiblePosition() - getFirstVisiblePosition())          .getBottom() <= getMeasuredHeight())        return true;    }    return false;  }}

GridView

public class PullableGridView extends GridView implements Pullable {  public PullableGridView(Context context) {    super(context);  }  public PullableGridView(Context context, AttributeSet attrs) {    super(context, attrs);  }  public PullableGridView(Context context, AttributeSet attrs, int defStyle) {    super(context, attrs, defStyle);  }  @Override  public boolean canPullDown() {    if (getCount() == 0) {      // 沒有item的時候也可以下拉刷新      return false;    } else if (getFirstVisiblePosition() == 0        && getChildAt(0).getTop() >= 0) {      // 滑到頂部了      return true;    } else      return false;  }  @Override  public boolean canPullUp() {    if (getCount() == 0) {      // 沒有item的時候也可以上拉加載      return false;    } else if (getLastVisiblePosition() == (getCount() - 1)) {      // 滑到底部了      if (getChildAt(getLastVisiblePosition() - getFirstVisiblePosition()) != null          && getChildAt(          getLastVisiblePosition()              - getFirstVisiblePosition()).getBottom() <= getMeasuredHeight())        return true;    }    return false;  }}

RecyclerView

public class PullableRecyclerView extends RecyclerView implements Pullable {  public PullableRecyclerView(Context context) {    super(context);  }  public PullableRecyclerView(Context context, @Nullable AttributeSet attrs) {    super(context, attrs);  }  public PullableRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {    super(context, attrs, defStyle);  }  @Override  public boolean canPullDown() {    RecyclerView.LayoutManager layoutManager = getLayoutManager();    if (layoutManager instanceof LinearLayoutManager) {      LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;      if (linearLayoutManager.getItemCount() == 0) {        return false;      } else if (linearLayoutManager.findFirstVisibleItemPosition() == 0 && linearLayoutManager.getChildAt(0).getTop() >= 0) {        return true;      } else {        return false;      }    } else if (layoutManager instanceof StaggeredGridLayoutManager) {      StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;      if (staggeredGridLayoutManager.getItemCount() == 0) {        return false;      } else {        int[] firstVisibleItems = null;        firstVisibleItems = staggeredGridLayoutManager.findFirstVisibleItemPositions(firstVisibleItems);        if (firstVisibleItems != null && firstVisibleItems.length > 0) {          if (staggeredGridLayoutManager.getChildCount() + firstVisibleItems[0] == staggeredGridLayoutManager.getItemCount()) {            return true;          }        }      }    }    return false;  }  @Override  public boolean canPullUp() {    RecyclerView.LayoutManager layoutManager = getLayoutManager();    if (layoutManager instanceof LinearLayoutManager) {      LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;      if (linearLayoutManager.getItemCount() == 0) {        return false;      } else if (linearLayoutManager.findLastVisibleItemPosition() == (linearLayoutManager.getItemCount() - 1)) {        if (linearLayoutManager.getChildAt(linearLayoutManager.findLastVisibleItemPosition() - linearLayoutManager.findFirstVisibleItemPosition()) != null            && linearLayoutManager.getChildAt(linearLayoutManager.findLastVisibleItemPosition() - linearLayoutManager.findFirstVisibleItemPosition()).getBottom() <= getMeasuredHeight()) {          return true;        }      }    } else if (layoutManager instanceof StaggeredGridLayoutManager) {      StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;      if (staggeredGridLayoutManager.getItemCount() == 0) {        return false;      } else {        int[] lastPositions = new int[staggeredGridLayoutManager.getSpanCount()];        lastPositions = staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);        if (findMax(lastPositions) >= staggeredGridLayoutManager.getItemCount() - 1) {          return true;        }      }    }    return false;  }  private int findMax(int[] lastPositions) {    int max = lastPositions[0];    for (int value : lastPositions) {      if (value > max) {        max = value;      }    }    return max;  }}

ExpandableListView

public class PullableExpandableListView extends ExpandableListView implements    Pullable {  public PullableExpandableListView(Context context) {    super(context);  }  public PullableExpandableListView(Context context, AttributeSet attrs) {    super(context, attrs);  }  public PullableExpandableListView(Context context, AttributeSet attrs,                   int defStyle) {    super(context, attrs, defStyle);  }  @Override  public boolean canPullDown() {    if (getCount() == 0) {      // 沒有item的時候也可以下拉刷新      return false;    } else if (getFirstVisiblePosition() == 0        && getChildAt(0).getTop() >= 0) {      // 滑到頂部了      return true;    } else      return false;  }  @Override  public boolean canPullUp() {    if (getCount() == 0) {      // 沒有item的時候也可以上拉加載      return false;    } else if (getLastVisiblePosition() == (getCount() - 1)) {      // 滑到底部了      if (getChildAt(getLastVisiblePosition() - getFirstVisiblePosition()) != null          && getChildAt(          getLastVisiblePosition()              - getFirstVisiblePosition()).getBottom() <= getMeasuredHeight())        return true;    }    return false;  }}

ScrollView

public class PullableScrollView extends ScrollView implements Pullable {  public PullableScrollView(Context context) {    super(context);  }  public PullableScrollView(Context context, AttributeSet attrs) {    super(context, attrs);  }  public PullableScrollView(Context context, AttributeSet attrs, int defStyle) {    super(context, attrs, defStyle);  }  @Override  public boolean canPullDown() {    if (getScrollY() == 0)      return true;    else      return false;  }  @Override  public boolean canPullUp() {    if (getScrollY() >= (getChildAt(0).getHeight() - getMeasuredHeight()))      return true;    else      return false;  }}

WebView

 public class PullableWebView extends WebView implements Pullable {  public PullableWebView(Context context) {    super(context);  }  public PullableWebView(Context context, AttributeSet attrs) {    super(context, attrs);  }  public PullableWebView(Context context, AttributeSet attrs, int defStyle) {    super(context, attrs, defStyle);  }  @Override  public boolean canPullDown() {    if (getScrollY() == 0)      return true;    else      return false;  }  @Override  public boolean canPullUp() {    if (getScrollY() >= getContentHeight() * getScale()        - getMeasuredHeight())      return true;    else      return false;  }}

ImageView

public class PullableImageView extends ImageView implements Pullable{  public PullableImageView(Context context)  {    super(context);  }  public PullableImageView(Context context, AttributeSet attrs)  {    super(context, attrs);  }  public PullableImageView(Context context, AttributeSet attrs, int defStyle)  {    super(context, attrs, defStyle);  }  @Override  public boolean canPullDown()  {    return true;  }  @Override  public boolean canPullUp()  {    return true;  }}

TextView

public class PullableTextView extends TextView implements Pullable {  public PullableTextView(Context context) {    super(context);  }  public PullableTextView(Context context, AttributeSet attrs) {    super(context, attrs);  }  public PullableTextView(Context context, AttributeSet attrs, int defStyle) {    super(context, attrs, defStyle);  }  @Override  public boolean canPullDown() {    return true;  }  @Override  public boolean canPullUp() {    return true;  }}

4.使用示例(以ListView為例)

<view.PullToRefreshLayout  android:id="@+id/ptrl"  android:layout_width="match_parent"  android:layout_height="match_parent">  <include layout="@layout/head" />  <view.PullableListView    android:id="@+id/plv"    android:layout_width="match_parent"    android:layout_height="match_parent" />  <include layout="@layout/foot" />  </view.PullToRefreshLayout>

head

<?xml version="1.0" encoding="UTF-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:id="@+id/head_view"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:background="@android:color/darker_gray">  <RelativeLayout    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_alignParentBottom="true"    android:paddingBottom="20dp"    android:paddingTop="20dp">    <RelativeLayout      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:layout_centerInParent="true">      <ImageView        android:id="@+id/iv_head"        android:layout_width="20dp"        android:layout_height="20dp"        android:layout_centerVertical="true"        android:layout_marginLeft="60dp"        android:scaleType="fitXY" />      <TextView        android:id="@+id/tv_head"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:textColor="@android:color/white"        android:textSize="16sp" />          </RelativeLayout>      </RelativeLayout>  </RelativeLayout>

foot

<?xml version="1.0" encoding="UTF-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:id="@+id/loadmore_view"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:background="@android:color/darker_gray">  <RelativeLayout    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_alignParentTop="true"    android:paddingBottom="20dp"    android:paddingTop="20dp">    <RelativeLayout      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:layout_centerInParent="true">      <ImageView        android:id="@+id/iv_foot"        android:layout_width="20dp"        android:layout_height="20dp"        android:layout_centerVertical="true"        android:layout_marginLeft="60dp"        android:scaleType="fitXY" />      <TextView        android:id="@+id/tv_foot"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:textColor="@android:color/white"        android:textSize="16sp" />    </RelativeLayout>      </RelativeLayout>  </RelativeLayout>

4.注意

自定義的View跟正常的View的使用沒有什么差別
如需實現刷新加載,必須使ptrl.setOnRefreshListener(PullToRefreshLayout.OnRefreshListener onRefreshListener);

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 芜湖市| 曲麻莱县| 资兴市| 华容县| 安远县| 泾源县| 广元市| 乡城县| 寻甸| 鄂伦春自治旗| 汤阴县| 务川| 永修县| 民县| 白河县| 开江县| 赤壁市| 梁山县| 延寿县| 甘谷县| 徐闻县| 古交市| 同心县| 清流县| 河源市| 凤冈县| 河池市| 庆城县| 通榆县| 怀仁县| 延安市| 托克逊县| 镇康县| 沂源县| 花莲县| 荥阳市| 邓州市| 武威市| 台南县| 尼玛县| 邓州市|