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

首頁 > 系統 > Android > 正文

Android仿XListView支持下拉刷新和上劃加載更多的自定義RecyclerView

2019-12-12 06:23:37
字體:
來源:轉載
供稿:網友

首先給大家展示下效果圖,感覺還不錯,請繼續往下閱讀:

下拉刷新:

      


上劃加載

      

在項目更新的過程中,遇到了一個將XListView換成recyclerView的需求,而且更換完之后大體效果不能變,但是對于下拉刷新這樣的效果,谷歌給出的解決方案是把RecyclerView放在一個SwipeRefreshLayout中,但是這樣其實是拉下一個小圓形控件實現的,和XListView的header效果不同。在網上找了很多的別人代碼,都沒有實現我想要的效果,于是自己動手寫了一個。

具體實現的效果有以下幾條

下拉刷新功能:

1、實現一個有彈性的拖出效果:思路參考XListView,recyclerView的position=0的位置放一個header布局,這個布局的margin top默認為負的布局高度,所以這塊布局就一直處于屏幕外部,在下拉的時候通過onTouchListener根據手指的移動動態修改margin top,慢慢的拖出,當拖出的距離也就是margin top變為正數以后,就蓋面header布局的狀態,改變箭頭的方向并改變提示語

2、實現有彈性的回彈效果:用timerTask寫了一個動態修改的header布局的margin top的動畫,每隔一定的時間減小margin top的值,當用戶松手的時候通過一個函數updateHeaderHeight()來執行這個動畫。

3、實現用戶非手動拖拉的自動刷新效果:這個recyclerView還有一個方法叫forceRefresh(),就是不需要用戶手動下拉,頭部自己滾動出來,然后刷新完再自己收回去,自動下拉也是用一個timerTask每隔十幾毫秒增加margin top的值讓頭部慢慢露出來

上劃加載更多功能:

1、實現滾動到底部自動停住效果: 有時候recyclerVIew滾動太快,滾到底部的時候會根據慣性向上飄,這個地方到底的時候監控recyclerView滾動速度,如果非常快說明是慣性滾動,就不修改footer布局的高度

2、實現向上拖動效果:復寫了recyclerView的onScrollListener,在手指向上滾動的時候,通過updateFooterHeight()方法動態修改底部footerView的margin bottom,同headerView一樣,在手指移動的時候讓這個margin跟著變大,以增加footer布局的高度,而且手指移動的越網上,增加的margin的高度就越小,實現一個有彈性的上拉效果,防止誤操作。

3、實現自動回彈的效果:通過監控footer布局的margin bottom來確定松手的時候是否需要開始刷新,如果margin bottom大于某個值得時候就修改footer布局的狀態從normal變成ready,在ready狀態下松手就開始刷新操作,回彈也像header布局一樣通過一個timerTask每隔十幾毫秒修改margin的大小來實現回彈效果

注意事項:

1、為了實現頭部和底部的代碼分離,頭部用的是onTouchListener,底部用的是onScrollListener

2、本recyclerVIew里面已經內置了一個layoutManager,所以不要給recyclerView再設置layoutManager,否則會出現頭部不出來,下拉報空指針的情況,底部出現但是滑動沒有效果

3、這個recyclerView內置了一個抽象類作為adapter,請繼承這個內置的AlxDragRecyclerViewAdapter使用,或者按照這里面的邏輯重新寫adapter

有其他的問題歡迎問我

4、一些常用的功能,比如設置該控件是否能夠支持下拉加載和上拉刷新,等等api接口,請直接參考XListView的用法即可

使用方法:

繼承AlxDragRecyclerViewAdapter寫一個adapter,然后寫兩個類分別實現OnRefreshListener和LoadMoreListener,把具體的刷新邏輯寫在里面,在準備好顯示數據后調用adapter的notifyDataSetChanged()方法或notifyItemInserted()方法,并執行該recyclerView的stopLoadmore()方法和stopRefresh()方法。

下面是代碼,這個控件有很多的內部類,包括頭部,底部的布局控件(CustomDragHeaderView,CustomDragFooterView),adapter,layoutmanager都已經以內部類的方式集成在里面,減少遷移時候的復雜度

import android.content.Context;import android.graphics.Color;import android.os.Handler;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.util.AttributeSet;import android.util.Log;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.WindowManager;import android.view.animation.Animation;import android.view.animation.RotateAnimation;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.TextView;import com.xxx.app.R;import java.util.List;import java.util.Timer;import java.util.TimerTask;/** * Created by Alex on 2016/1/27. */public class AlxRefreshLoadMoreRecyclerView extends RecyclerView { private int footerHeight = -1; LinearLayoutManager layoutManager; // -- footer view private CustomDragRecyclerFooterView mFooterView; private boolean mEnablePullLoad; private boolean mPullLoading; private boolean isBottom; private boolean mIsFooterReady = false; private LoadMoreListener loadMoreListener; // -- header view private CustomDragHeaderView mHeaderView; private boolean mEnablePullRefresh = true; private boolean mIsRefreshing; private boolean isHeader; private boolean mIsHeaderReady = false; private Timer timer; private float oldY; Handler handler = new Handler(); private OnRefreshListener refreshListener; private AlxDragRecyclerViewAdapter adapter; private int maxPullHeight = 50;//最多下拉高度的px值 private static final int HEADER_HEIGHT = 68;//頭部高度68dp private static final int MAX_PULL_LENGTH = 150;//最多下拉150dp private OnClickListener footerClickListener; public AlxRefreshLoadMoreRecyclerView(Context context) {  super(context);  initView(context); } public AlxRefreshLoadMoreRecyclerView(Context context, AttributeSet attrs) {  super(context, attrs);  initView(context); } public AlxRefreshLoadMoreRecyclerView(Context context, AttributeSet attrs, int defStyle) {  super(context, attrs, defStyle);  initView(context); } public void setAdapter(AlxDragRecyclerViewAdapter adapter){  super.setAdapter(adapter);  this.adapter = adapter; } public boolean ismPullLoading() {  return mPullLoading; } public boolean ismIsRefreshing() {  return mIsRefreshing; } private void updateFooterHeight(float delta) {  if(mFooterView==null)return;  int bottomMargin = mFooterView.getBottomMargin();//  Log.i("Alex3","初始delta是"+delta);  if(delta>50)delta = delta/6;  if(delta>0) {//越往下滑越難滑   if(bottomMargin>maxPullHeight)delta = delta*0.65f;   else if(bottomMargin>maxPullHeight * 0.83333f)delta = delta*0.7f;   else if(bottomMargin>maxPullHeight * 0.66667f)delta = delta*0.75f;   else if(bottomMargin>maxPullHeight >> 1)delta = delta*0.8f;   else if(bottomMargin>maxPullHeight * 0.33333f)delta = delta*0.85f;   else if(bottomMargin>maxPullHeight * 0.16667F && delta > 20)delta = delta*0.2f;//如果是因為慣性向下迅速的俯沖   else if(bottomMargin>maxPullHeight * 0.16667F)delta = delta*0.9f;//   Log.i("Alex3","bottomMargin是"+mFooterView.getBottomMargin()+" delta是"+delta);  }  int height = mFooterView.getBottomMargin() + (int) (delta+0.5);  if (mEnablePullLoad && !mPullLoading) {   if (height > 150){//必須拉超過一定距離才加載更多//   if (height > 1){//立即刷新    mFooterView.setState(CustomDragRecyclerFooterView.STATE_READY);    mIsFooterReady = true;//    Log.i("Alex2", "ready");   } else {    mFooterView.setState(CustomDragRecyclerFooterView.STATE_NORMAL);    mIsFooterReady = false;//    Log.i("Alex2", "nomal");   }  }  mFooterView.setBottomMargin(height); } private void resetFooterHeight() {  int bottomMargin = mFooterView.getBottomMargin();  if (bottomMargin > 20) {   Log.i("Alex2", "準備重置高度,margin是" + bottomMargin + "自高是" + footerHeight);   this.smoothScrollBy(0,-bottomMargin);   //一松手就立即開始加載   if(mIsFooterReady){    startLoadMore();   }  } } public void setLoadMoreListener(LoadMoreListener listener){  this.loadMoreListener = listener; } public void initView(Context context){  layoutManager = new LinearLayoutManager(context);//自帶layoutManager,請勿設置  layoutManager.setOrientation(LinearLayoutManager.VERTICAL);  WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);  int height = wm.getDefaultDisplay().getHeight();  layoutManager.offsetChildrenVertical(height*2);//預加載2/3的卡片  this.setLayoutManager(layoutManager);//  Log.i("Alex", "屏幕密度為" + getContext().getResources().getDisplayMetrics().density);  maxPullHeight = dp2px(getContext().getResources().getDisplayMetrics().density,MAX_PULL_LENGTH);//最多下拉150dp  this.footerClickListener = new footerViewClickListener();  this.addOnScrollListener(new RecyclerView.OnScrollListener() {   @Override   public void onScrollStateChanged(RecyclerView recyclerView, int newState) {    super.onScrollStateChanged(recyclerView, newState);    switch (newState){     case RecyclerView.SCROLL_STATE_IDLE://      Log.i("Alex2", "停下了||放手了");      if(isBottom)resetFooterHeight();      break;     case RecyclerView.SCROLL_STATE_DRAGGING://      Log.i("Alex2", "開始拖了,現在margin是" + (mFooterView == null ? "" : mFooterView.getBottomMargin()));      break;     case RecyclerView.SCROLL_STATE_SETTLING://      Log.i("Alex2", "開始慣性移動");      break;    }   }   @Override   public void onScrolled(RecyclerView recyclerView, int dx, int dy) {    super.onScrolled(recyclerView, dx, dy);    int lastItemPosition = layoutManager.findLastVisibleItemPosition();//    Log.i("Alex2","mEnable是"+mEnablePullLoad+"lastitemPosition是"+lastItemPosition+" itemcount是"+layoutManager.getItemCount());    if(lastItemPosition == layoutManager.getItemCount()-1 && mEnablePullLoad) {//如果到了最后一個     isBottom = true;     mFooterView = (CustomDragRecyclerFooterView)layoutManager.findViewByPosition(layoutManager.findLastVisibleItemPosition());//一開始還不能hide,因為hide得到最后一個可見的就不是footerview了//     Log.i("Alex2","到底啦!!"+"mfooterView是"+mFooterView);     if(mFooterView!=null) mFooterView.setOnClickListener(footerClickListener);     if(footerHeight==-1 && mFooterView!=null){      mFooterView.show();      mFooterView.setState(CustomDragRecyclerFooterView.STATE_NORMAL);      footerHeight = mFooterView.getMeasuredHeight();//這里的測量一般不會出問題//      Log.i("Alex2", "底部高度為" + footerHeight);     }     updateFooterHeight(dy);    }else if(lastItemPosition == layoutManager.getItemCount()-1 && mEnablePullLoad){//如果到了倒數第二個     startLoadMore();//開始加載更多    }    else {     isBottom = false;    }   }  }); } /**  * 設置是否開啟上拉加載更多的功能  *  * @param enable  */ public void setPullLoadEnable(boolean enable) {  mPullLoading = false;  mEnablePullLoad = enable;  if(adapter!=null)adapter.setPullLoadMoreEnable(enable);//adapter和recyclerView要同時設置  if(mFooterView==null)return;  if (!mEnablePullLoad) {//   this.smoothScrollBy(0,-footerHeight);   mFooterView.hide();   mFooterView.setOnClickListener(null);   mFooterView.setBottomMargin(0);   //make sure "pull up" don't show a line in bottom when listview with one page  } else {   mFooterView.show();   mFooterView.setState(CustomDragRecyclerFooterView.STATE_NORMAL);   mFooterView.setVisibility(VISIBLE);   //make sure "pull up" don't show a line in bottom when listview with one page   // both "pull up" and "click" will invoke load more.   mFooterView.setOnClickListener(new OnClickListener() {    @Override    public void onClick(View v) {     startLoadMore();    }   });  } } /**  * 停止loadmore  */ public void stopLoadMore() {  if (mPullLoading == true) {   mPullLoading = false;   if(mFooterView==null)return;   mFooterView.show();   mFooterView.setState(CustomDragRecyclerFooterView.STATE_ERROR);  } } private void startLoadMore() {  if(mPullLoading)return;  mPullLoading = true;  if(mFooterView!=null)mFooterView.setState(CustomDragRecyclerFooterView.STATE_LOADING);  Log.i("Alex2", "現在開始加載");  mIsFooterReady = false;  if (loadMoreListener != null) {   loadMoreListener.onLoadMore();  } } /**  * 在刷新時要執行的方法  */ public interface LoadMoreListener{  public void onLoadMore(); } /**  * 點擊loadMore后要執行的事件  */ class footerViewClickListener implements OnClickListener {  @Override  public void onClick(View v) {   startLoadMore();  } } private void updateHeaderHeight(float delta) {  mHeaderView = (CustomDragHeaderView) layoutManager.findViewByPosition(0);//  Log.i("Alex2", "現在在頭部!!!! header自高是" + mHeaderView.getHeight() + " margin 是" + mHeaderView.getTopMargin());//自高一般不會算錯//  Log.i("Alex2", "正在設置margin" + mHeaderView.getTopMargin() +"delta是"+delta);  if(delta>0){//如果是往下拉   int topMargin = mHeaderView.getTopMargin();   if(topMargin>maxPullHeight * 0.33333f)delta = delta*0.5f;   else if(topMargin>maxPullHeight * 0.16667F)delta = delta*0.55f;   else if(topMargin>0)delta = delta*0.6f;   else if(topMargin<0)delta = delta*0.6f;//如果沒有被完全拖出來   mHeaderView.setTopMargin(mHeaderView.getTopMargin() + (int)delta);  } else{//如果是推回去   if(!mIsRefreshing || mHeaderView.getTopMargin()>0) {//在刷新的時候不把margin設為負值以在慣性滑動的時候能滑回去    this.scrollBy(0, (int) delta);//禁止既滾動,又同時減少觸摸//    Log.i("Alex2", "正在往回推" + delta);    mHeaderView.setTopMargin(mHeaderView.getTopMargin() + (int) delta);   }  }  if(mHeaderView.getTopMargin()>0 && !mIsRefreshing){   mIsHeaderReady = true;   mHeaderView.setState(CustomDragHeaderView.STATE_READY);  }//設置為ready狀態  else if(!mIsRefreshing){   mIsHeaderReady = false;   mHeaderView.setState(CustomDragHeaderView.STATE_NORMAL);  }//設置為普通狀態并且縮回去 } @Override public void smoothScrollToPosition(final int position) {  super.smoothScrollToPosition(position);  final Timer scrollTimer = new Timer();  TimerTask timerTask = new TimerTask() {   @Override   public void run() {    int bottomCardPosition = layoutManager.findLastVisibleItemPosition();    if(bottomCardPosition<position+1){//如果要向下滾     handler.post(new Runnable() {      @Override      public void run() {       smoothScrollBy(0,50);      }     });    }else if(bottomCardPosition>position){//如果要向上滾     handler.post(new Runnable() {      @Override      public void run() {       smoothScrollBy(0,-50);      }     });    }else {     if(scrollTimer!=null)scrollTimer.cancel();    }   }  };  scrollTimer.schedule(timerTask,0,20); } /**  * 在用戶非手動強制刷新的時候,通過一個動畫把頭部一點點冒出來  */ private void smoothShowHeader(){  if(mHeaderView==null)return;//  if(layoutManager.findFirstVisibleItemPosition()!=0){//如果刷新完畢的時候用戶沒有注視header//   mHeaderView.setTopMargin(0);//   return;//  }  if(timer!=null)timer.cancel();  final TimerTask timerTask = new TimerTask() {   @Override   public void run() {    if(mHeaderView==null){     if(timer!=null)timer.cancel();     return;    }//    Log.i("Alex2","topMargin是"+mHeaderView.getTopMargin()+" height是"+mHeaderView.getHeight());    if(mHeaderView.getTopMargin()<0){     handler.post(new Runnable() {      @Override      public void run() {       if (mIsRefreshing) {//如果目前是ready狀態或者正在刷新狀態        mHeaderView.setTopMargin(mHeaderView.getTopMargin() +2);       }      }     });    } else if(timer!=null){//如果已經完全縮回去了,但是動畫還沒有結束,就結束掉動畫     timer.cancel();    }   }  };  timer = new Timer();  timer.scheduleAtFixedRate(timerTask,0,16); } /**  * 在用戶松手的時候讓頭部自動收縮回去  */ private void resetHeaderHeight() {  if(mHeaderView==null)mHeaderView = (CustomDragHeaderView) layoutManager.findViewByPosition(0);  if(layoutManager.findFirstVisibleItemPosition()!=0){//如果刷新完畢的時候用戶沒有注視header   mHeaderView.setTopMargin(-mHeaderView.getRealHeight());   return;  }  if(timer!=null)timer.cancel();  final TimerTask timerTask = new TimerTask() {   @Override   public void run() {    if(mHeaderView==null)return;//    Log.i("Alex2","topMargin是"+mHeaderView.getTopMargin()+" height是"+mHeaderView.getHeight());    if(mHeaderView.getTopMargin()>-mHeaderView.getRealHeight()){//如果header沒有完全縮回去     handler.post(new Runnable() {      @Override      public void run() {       if (mIsHeaderReady || mIsRefreshing) {//如果目前是ready狀態或者正在刷新狀態//        Log.i("Alex2", "現在是ready狀態");        int delta = mHeaderView.getTopMargin() / 9;        if (delta < 5) delta = 5;        if (mHeaderView.getTopMargin() > 0)         mHeaderView.setTopMargin(mHeaderView.getTopMargin() - delta);       } else {//如果是普通狀態//        Log.i("Alex2", "現在是普通狀態");        mHeaderView.setTopMargin(mHeaderView.getTopMargin() - 5);       }      }     });    } else if(timer!=null){//如果已經完全縮回去了,但是動畫還沒有結束,就結束掉動畫     timer.cancel();     handler.post(new Runnable() {      @Override      public void run() {       mHeaderView.setState(mHeaderView.STATE_FINISH);      }     });    }   }  };  timer = new Timer();  timer.scheduleAtFixedRate(timerTask,0,10); } /**  * 頭部是通過onTouchEvent控制的  * @param event  * @return  */ @Override public boolean onTouchEvent(MotionEvent event) {  switch (event.getAction()) {   case MotionEvent.ACTION_MOVE:    int delta = (int)(event.getY()-oldY);    oldY = event.getY();    if (layoutManager.findViewByPosition(0) instanceof CustomDragHeaderView) {     isHeader = true;     updateHeaderHeight(delta);//更新margin高度    }else{     isHeader = false;     if(mHeaderView!=null && !mIsRefreshing)mHeaderView.setTopMargin(-mHeaderView.getRealHeight());    }    break;//   case MotionEvent.ACTION_DOWN://    Log.i("Alex", "touch down");//    oldY = event.getY();//    if(timer!=null)timer.cancel();//    break;   case MotionEvent.ACTION_UP://    Log.i("Alex", "抬手啦!!!! touch up ");    if(mIsHeaderReady && !mIsRefreshing)startRefresh();    if(isHeader)resetHeaderHeight();//抬手之后恢復高度    break;   case MotionEvent.ACTION_CANCEL://    Log.i("Alex", "touch cancel");    break;  }  return super.onTouchEvent(event); } /**  * 因為設置了子元素的onclickListener之后,ontouch方法的down失效,所以要在分發前獲取手指的位置  * @param ev  * @return  */ @Override public boolean dispatchTouchEvent(MotionEvent ev) {  // TODO Auto-generated method stub  switch (ev.getAction()) {   case MotionEvent.ACTION_DOWN://    Log.i("Alex", "touch down分發前");    oldY = ev.getY();    if (timer != null) timer.cancel();    break;  }  return super.dispatchTouchEvent(ev); } public void setOnRefreshListener(OnRefreshListener listener){  this.refreshListener = listener; } /**  * 設置是否支持下啦刷新的功能  *  * @param enable  */ public void setPullRefreshEnable(boolean enable) {  mIsRefreshing = false;  mEnablePullRefresh = enable;  if(mHeaderView==null)return;  if (!mEnablePullRefresh) {   mHeaderView.setOnClickListener(null);  } else {   mHeaderView.setState(CustomDragFooterView.STATE_NORMAL);   mHeaderView.setVisibility(VISIBLE);  } } /**  * 停止下拉刷新,并且通過動畫讓頭部自己縮回去  */ public void stopRefresh() {  if (mIsRefreshing == true) {   mIsRefreshing = false;   mIsHeaderReady = false;   if(mHeaderView==null)return;   mHeaderView.setState(CustomDragFooterView.STATE_NORMAL);   resetHeaderHeight();  } } /**  * 在用戶沒有用手控制的情況下,通過動畫把頭部露出來并且執行刷新  */ public void forceRefresh(){  if(mHeaderView==null)mHeaderView = (CustomDragHeaderView) layoutManager.findViewByPosition(0);  if(mHeaderView!=null)mHeaderView.setState(CustomDragHeaderView.STATE_REFRESHING);  mIsRefreshing = true;  Log.i("Alex2", "現在開始強制刷新");  mIsHeaderReady = false;  smoothShowHeader();  if (refreshListener != null)refreshListener.onRefresh(); } private void startRefresh() {  mIsRefreshing = true;  mHeaderView.setState(CustomDragHeaderView.STATE_REFRESHING);  Log.i("Alex2", "現在開始加載");  mIsHeaderReady = false;  if (refreshListener != null) refreshListener.onRefresh(); } public interface OnRefreshListener{  public void onRefresh(); } /**  * 適用于本recycler的頭部下拉刷新view  */ public static class CustomDragHeaderView extends LinearLayout {  public final static int STATE_NORMAL = 0;  public final static int STATE_READY = 1;  public final static int STATE_REFRESHING = 2;  public final static int STATE_FINISH = 3;  public float screenDensity;  private final int ROTATE_ANIM_DURATION = 180;  private Context mContext;  private View mContentView;  private View mProgressBar;  private ImageView mArrowImageView;  private TextView mHintTextView;  private Animation mRotateUpAnim;  private Animation mRotateDownAnim;  public CustomDragHeaderView(Context context) {   super(context);   initView(context);  }  public CustomDragHeaderView(Context context, AttributeSet attrs) {   super(context, attrs);   initView(context);  }  private int mState;  public void setState(int state) {   if (state == mState)    return;   if (state == STATE_REFRESHING) { // 顯示進度    mArrowImageView.clearAnimation();    mArrowImageView.setVisibility(View.INVISIBLE);    mProgressBar.setVisibility(View.VISIBLE);   } else { // 顯示箭頭圖片    mArrowImageView.setVisibility(View.VISIBLE);    mProgressBar.setVisibility(View.INVISIBLE);   }   switch (state) {    case STATE_NORMAL:     if (mState == STATE_READY) {      mArrowImageView.startAnimation(mRotateDownAnim);      mHintTextView.setText(R.string.xlistview_header_hint_normal);     }     else if (mState == STATE_REFRESHING) {//如果是從刷新狀態過來//      mArrowImageView.clearAnimation();      mArrowImageView.setVisibility(INVISIBLE);      mHintTextView.setText("load completed");     }     break;    case STATE_READY:     if (mState != STATE_READY) {      mArrowImageView.clearAnimation();      mArrowImageView.startAnimation(mRotateUpAnim);     }      mHintTextView.setText(R.string.xlistview_header_hint_ready);     break;    case STATE_REFRESHING:      mHintTextView.setText(R.string.xlistview_header_hint_loading);     break;    case STATE_FINISH:     mArrowImageView.setVisibility(View.VISIBLE);     mHintTextView.setText(R.string.xlistview_header_hint_normal);     break;    default:   }   mState = state;  }  public void setTopMargin(int height) {   if (mContentView==null) return ;   LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();   lp.topMargin = height;   mContentView.setLayoutParams(lp);  }  //  public int getTopMargin() {   LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();   return lp.topMargin;  }  public void setHeight(int height){   if (mContentView==null) return ;   LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();   lp.height = height;   mContentView.setLayoutParams(lp);  }  private int realHeight;  /**   * 得到這個headerView真實的高度,而且這個高度是自己定的   * @return   */  public int getRealHeight(){   return realHeight;  }  private void initView(Context context) {   mContext = context;   this.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));//recyclerView里不加這句話的話寬度就會比較窄   LinearLayout moreView = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.xlistview_header, null);   addView(moreView);   moreView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));   mContentView = moreView.findViewById(R.id.xlistview_header_content);   LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();   Log.i("Alex", "初始height是" + mContentView.getHeight());   lp.height = 150;//手動設置高度,如果要手動加載更多的時候才設置   screenDensity = getContext().getResources().getDisplayMetrics().density;//設置屏幕密度,用來px向dp轉化   lp.height = dp2px(screenDensity,HEADER_HEIGHT);//頭部高度75dp   realHeight = lp.height;   lp.topMargin = -lp.height;   mContentView.setLayoutParams(lp);   mArrowImageView = (ImageView) findViewById(R.id.xlistview_header_arrow);   mHintTextView = (TextView) findViewById(R.id.xlistview_header_hint_textview);   mHintTextView.setPadding(0,dp2px(screenDensity,3),0,0);//不知道為什么這個文字總會向上偏一下,所以要補回來   mProgressBar = findViewById(R.id.xlistview_header_progressbar);   mRotateUpAnim = new RotateAnimation(0.0f, -180.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);   mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);   mRotateUpAnim.setFillAfter(true);   mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);   mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);   mRotateDownAnim.setFillAfter(true);  } } public static int dp2px(float density, int dp) {  if (dp == 0) {   return 0;  }  return (int) (dp * density + 0.5f); } public static class CustomDragRecyclerFooterView extends LinearLayout {  public final static int STATE_NORMAL = 0;  public final static int STATE_READY = 1;  public final static int STATE_LOADING = 2;  public final static int STATE_ERROR = 3;  private Context mContext;  private View mContentView;  private View mProgressBar;  private TextView mHintView;  public CustomDragRecyclerFooterView(Context context) {   super(context);   initView(context);  }  public CustomDragRecyclerFooterView(Context context, AttributeSet attrs) {   super(context, attrs);   initView(context);  }  public void setState(int state) {   mProgressBar.setVisibility(View.INVISIBLE);//   mHintView.setVisibility(View.INVISIBLE);   if (state == STATE_READY) {    mHintView.setVisibility(View.VISIBLE);    mHintView.setText("松手加載更多");   } else if (state == STATE_LOADING) {    mProgressBar.setVisibility(View.VISIBLE);    mHintView.setVisibility(INVISIBLE);   } else if(state == STATE_ERROR){    mProgressBar.setVisibility(GONE);    mHintView.setVisibility(VISIBLE);    mHintView.setText(R.string.xlistview_footer_hint_ready);   }   else {    mHintView.setVisibility(View.VISIBLE);    mHintView.setText(R.string.xlistview_footer_hint_normal);    mHintView.setText("Load more");   }  }  public void setBottomMargin(int height) {   if (height < 0) return ;   LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();   lp.bottomMargin = height;   mContentView.setLayoutParams(lp);  }  public int getBottomMargin() {   LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();   return lp.bottomMargin;  }  /**   * normal status   */  public void normal() {   mHintView.setVisibility(View.VISIBLE);   mProgressBar.setVisibility(View.GONE);  }  /**   * loading status   */  public void loading() {   mHintView.setVisibility(View.GONE);   mProgressBar.setVisibility(View.VISIBLE);  }  /**   * hide footer when disable pull load more   */  public void hide() {   LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();   lp.height = 1;//這里如果設為0那么layoutManger就會抓不到   mContentView.setLayoutParams(lp);   mContentView.setBackgroundColor(Color.BLACK);//這里的顏色要和自己的背景色一致  }  /**   * show footer   */  public void show() {   LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();   lp.height = LayoutParams.WRAP_CONTENT;   lp.width = LayoutParams.MATCH_PARENT;   mContentView.setLayoutParams(lp);   mContentView.setBackgroundColor(Color.WHITE);//這里的顏色要和自己的背景色一致  }  private void initView(Context context) {   mContext = context;   this.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));   LinearLayout moreView = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.layout_customdragfooterview, null);   addView(moreView);   moreView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));   mContentView = moreView.findViewById(R.id.rlContentView);   mProgressBar = moreView.findViewById(R.id.pbContentView);   mHintView = (TextView)moreView.findViewById(R.id.ctvContentView);   mHintView.setText("load more");//   mProgressBar.setVisibility(VISIBLE);//一直會顯示轉圈,自動加載更多時使用  } } /**  * 為了防止代碼上的混亂,使用這個recyclerView自己內置的一個adapter  * @param <T>  */ public static abstract class AlxDragRecyclerViewAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>{  protected static final int TYPE_HEADER = 436874;  protected static final int TYPE_ITEM = 256478;  protected static final int TYPE_FOOTER = 9621147;  private int ITEM;  private ViewHolder vhItem;  protected boolean loadMore;  private List<T> dataList;  public List<T> getDataList() {   return dataList;  }  public void setDataList(List<T> dataList) {   this.dataList = dataList;  }  public AlxDragRecyclerViewAdapter(List<T> dataList,int itemLayout,boolean pullEnable){   this.dataList = dataList;   this.ITEM = itemLayout;   this.loadMore = pullEnable;  }  public abstract ViewHolder setItemViewHolder(View itemView);  private T getObject(int position){   if(dataList!=null && dataList.size()>=position)return dataList.get(position-1);//如果有header   return null;  }  @Override  public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {   if (viewType == TYPE_ITEM) {    //inflate your layout and pass it to view holder    View itemView = LayoutInflater.from(parent.getContext()).inflate(ITEM,null);    Log.i("Alex","itemView是"+itemView);    this.vhItem = setItemViewHolder(itemView);    Log.i("Alex","vhItem是"+vhItem);    return vhItem;   } else if (viewType == TYPE_HEADER) {    //inflate your layout and pass it to view holder    View headerView = new CustomDragHeaderView(parent.getContext());    return new VHHeader(headerView);   } else if(viewType==TYPE_FOOTER){    CustomDragRecyclerFooterView footerView = new CustomDragRecyclerFooterView(parent.getContext());    return new VHFooter(footerView);   }   throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");  }  public void setPullLoadMoreEnable(boolean enable){   this.loadMore = enable;  }  public boolean getPullLoadMoreEnable(){return loadMore;}  @Override  public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {//相當于getView   Log.i("Alex","正在綁定"+position+" "+holder.getClass());   if (vhItem!=null && holder.getClass() == vhItem.getClass()) {    //cast holder to VHItem and set data    initItemView(holder,position,getObject(position));   }else if (holder instanceof AlxDragRecyclerViewAdapter.VHHeader) {    //cast holder to VHHeader and set data for header.   }else if(holder instanceof AlxDragRecyclerViewAdapter.VHFooter){    if(!loadMore)((VHFooter)holder).footerView.hide();//第一次初始化顯示的時候要不要顯示footerView   }  }  @Override  public int getItemCount() {   return (dataList==null ||dataList.size()==0)?1:dataList.size() + 2;//如果有header,若list不存在或大小為0就沒有footView,反之則有  }//這里要考慮到頭尾部,多以要加2  /**   * 根據位置判斷這里該用哪個ViewHolder   * @param position   * @return   */  @Override  public int getItemViewType(int position) {   if (position == 0)return TYPE_HEADER;   else if(isPositonFooter(position))return TYPE_FOOTER;   return TYPE_ITEM;  }  protected boolean isPositonFooter(int position){//這里的position從0算起    if (dataList == null && position == 1) return true;//如果沒有item    return position == dataList.size() + 1;//如果有item(也許為0)  }//  class VHItem extends RecyclerView.ViewHolder {//   public VHItem(View itemView) {//    super(itemView);//   }//   public View getItemView(){return itemView;}//  }//  protected class VHHeader extends RecyclerView.ViewHolder {   public VHHeader(View headerView) {    super(headerView);   }  }  protected class VHFooter extends RecyclerView.ViewHolder {   public CustomDragRecyclerFooterView footerView;   public VHFooter(View itemView) {    super(itemView);    footerView = (CustomDragRecyclerFooterView)itemView;   }  }  public abstract void initItemView(ViewHolder itemHolder,int posion,T entity); }}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 和田县| 墨江| 淳安县| 大冶市| 德惠市| 潞西市| 焉耆| 清流县| 冕宁县| 布尔津县| 广灵县| 巴彦淖尔市| 巴塘县| 渝北区| 固始县| 泰宁县| 大关县| 通榆县| 犍为县| 固始县| 红河县| 苏尼特左旗| 吉木萨尔县| 黄梅县| 祁连县| 如皋市| 台北县| 苗栗市| 额尔古纳市| 修水县| 文登市| 烟台市| 安庆市| 汉中市| 会泽县| 蓬莱市| 桃江县| 张家港市| 临城县| 临泽县| 长泰县|