編輯:關於android開發
android.support.v7 包提供了一個新的組件:RecycleView,用以提供一個靈活的列表試圖、顯示大型數據集,它支持局部刷新、顯示動畫等功能,可以用來取代ListView與GridView.
然而在使用的過程中卻遇到一些問題,基本現在手機頁面都會有滑動到底部加載更多的功能,而RecycleView 並沒有提供像ListView的addFooter等方法,所以實現起來還是有點麻煩。經過一段時間的摸索,終於找到實現RecycleView加載更多的方法。
本文主要通過RecycleView 的 ItemViewType 來實現RecycleView活動到底部加載更多功能,支持 列表、網格、瀑布流等布局。
根據ItemViewType創建兩種布局,一個用於顯示正常內容的布局,一個用於加載布局,然後監聽RecycleView的滾動事件,當滑動到底部時添加加載布局,對於列表布局來說很簡單,不再熬述,然而對於網格布局與瀑布流布局來說,要解決"加載布局只占用一列"的問題,
1.對於網格布局,GridLayoutManager 提供了一個 setSpanSizeLookup() 的方法,用來設置每個條目可以占用的列數,默認為1.
2.對於瀑布流,StaggeredGridLayoutManager 提供了一個 StaggeredGridLayoutManager.LayoutParams 內部靜態類,此類中有一個setFullSpan() 方法,用來設置條目跨越全列。
3.基類的實現方式如下:子類只需要重寫以下方法:
onCreateNormalViewHolder(ViewGroup parent);
onBindNormalViewHolder(RecyclerView.ViewHolder holder, int position);
1 /** 2 * Created by sunwei on 2015/12/4. 3 * Email: [email protected]. 4 * Description: recycleView 滑動到底部加載更多 5 */ 6 public abstract class BaseLoadingAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 7 8 private static final String TAG = "BaseLoadingAdapter"; 9 10 //是否正在加載 11 private boolean mIsLoading = false; 12 //正常條目 13 private static final int TYPE_NORMAL_ITEM = 0; 14 //加載條目 15 private static final int TYPE_LOADING_ITEM = 1; 16 //加載viewHolder 17 private LoadingViewHolder mLoadingViewHolder; 18 private StaggeredGridLayoutManager mStaggeredGridLayoutManager; 19 //數據集 20 private CircularArray<T> mTs; 21 22 public BaseLoadingAdapter(RecyclerView recyclerView, CircularArray<T> ts) { 23 mTs = ts; 24 25 setSpanCount(recyclerView); 26 27 setScrollListener(recyclerView); 28 } 29 30 private OnLoadingListener mOnLoadingListener; 31 32 /** 33 * 加載更多接口 34 */ 35 public interface OnLoadingListener { 36 void loading(); 37 } 38 39 /** 40 * 設置監聽接口 41 * 42 * @param onLoadingListener onLoadingListener 43 */ 44 public void setOnLoadingListener(OnLoadingListener onLoadingListener) { 45 mOnLoadingListener = onLoadingListener; 46 } 47 48 /** 49 * 加載完成 50 */ 51 public void setLoadingComplete() { 52 mIsLoading = false; 53 mTs.removeFromEnd(1); 54 notifyItemRemoved(mTs.size() - 1); 55 } 56 57 /** 58 * 沒有更多數據 59 */ 60 public void setLoadingNoMore() { 61 mLoadingViewHolder.progressBar.setVisibility(View.GONE); 62 mLoadingViewHolder.tvLoading.setText("數據已加載完!"); 63 } 64 65 /** 66 * 加載失敗 67 */ 68 public void setLoadingError() { 69 if (mLoadingViewHolder != null) { 70 mLoadingViewHolder.progressBar.setVisibility(View.GONE); 71 mLoadingViewHolder.tvLoading.setText("加載失敗,點擊重新加載!"); 72 73 mLoadingViewHolder.tvLoading.setOnClickListener(new View.OnClickListener() { 74 @Override 75 public void onClick(View v) { 76 if (mOnLoadingListener != null) { 77 mLoadingViewHolder.progressBar.setVisibility(View.VISIBLE); 78 mLoadingViewHolder.tvLoading.setText("正在加載"); 79 80 mOnLoadingListener.loading(); 81 } 82 } 83 }); 84 } 85 } 86 87 /** 88 * @return Whether it is possible for the child view of this layout to 89 * scroll up. Override this if the child view is a custom view. 90 */ 91 private boolean canScrollDown(RecyclerView recyclerView) { 92 return ViewCompat.canScrollVertically(recyclerView, 1); 93 } 94 95 /** 96 * 設置每個條目占用的列數 97 * 98 * @param recyclerView recycleView 99 */ 100 private void setSpanCount(RecyclerView recyclerView) { 101 RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); 102 if (layoutManager instanceof GridLayoutManager) { 103 final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager; 104 gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { 105 @Override 106 public int getSpanSize(int position) { 107 int type = getItemViewType(position); 108 if (type == TYPE_NORMAL_ITEM) { 109 return 1; 110 } else { 111 return gridLayoutManager.getSpanCount(); 112 } 113 } 114 }); 115 } 116 117 if (layoutManager instanceof StaggeredGridLayoutManager) { 118 mStaggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager; 119 } 120 } 121 122 /** 123 * 監聽滾動事件 124 * 125 * @param recyclerView recycleView 126 */ 127 private void setScrollListener(RecyclerView recyclerView) { 128 recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { 129 @Override 130 public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 131 super.onScrollStateChanged(recyclerView, newState); 132 } 133 134 @Override 135 public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 136 super.onScrolled(recyclerView, dx, dy); 137 138 if (!canScrollDown(recyclerView)) { 139 if (!mIsLoading) { 140 mIsLoading = true; 141 mTs.addLast(null); 142 notifyItemInserted(mTs.size() - 1); 143 if (mOnLoadingListener != null) { 144 mOnLoadingListener.loading(); 145 } 146 } 147 } 148 } 149 }); 150 } 151 152 /** 153 * 創建viewHolder 154 * 155 * @param parent viewGroup 156 * @return viewHolder 157 */ 158 public abstract RecyclerView.ViewHolder onCreateNormalViewHolder(ViewGroup parent); 159 160 /** 161 * 綁定viewHolder 162 * 163 * @param holder viewHolder 164 * @param position position 165 */ 166 public abstract void onBindNormalViewHolder(RecyclerView.ViewHolder holder, int position); 167 168 /** 169 * 加載布局 170 */ 171 private class LoadingViewHolder extends RecyclerView.ViewHolder { 172 public ProgressBar progressBar; 173 public TextView tvLoading; 174 public LinearLayout llyLoading; 175 176 public LoadingViewHolder(View view) { 177 super(view); 178 179 progressBar = (ProgressBar) view.findViewById(R.id.progress_loading); 180 tvLoading = (TextView) view.findViewById(R.id.tv_loading); 181 llyLoading = (LinearLayout) view.findViewById(R.id.lly_loading); 182 } 183 } 184 185 @Override 186 public int getItemViewType(int position) { 187 T t = mTs.get(position); 188 if (t == null) { 189 return TYPE_LOADING_ITEM; 190 } else { 191 return TYPE_NORMAL_ITEM; 192 } 193 } 194 195 @Override 196 public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 197 if (viewType == TYPE_NORMAL_ITEM) { 198 return onCreateNormalViewHolder(parent); 199 } else { 200 View view = LayoutInflater.from(parent.getContext()).inflate( 201 R.layout.loading_view, parent, false); 202 mLoadingViewHolder = new LoadingViewHolder(view); 203 return mLoadingViewHolder; 204 } 205 } 206 207 @Override 208 public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 209 int type = getItemViewType(position); 210 if (type == TYPE_NORMAL_ITEM) { 211 onBindNormalViewHolder(holder, position); 212 } else { 213 if (mStaggeredGridLayoutManager != null) { 214 StaggeredGridLayoutManager.LayoutParams layoutParams = 215 new StaggeredGridLayoutManager.LayoutParams( 216 ViewGroup.LayoutParams.MATCH_PARENT, 217 ViewGroup.LayoutParams.WRAP_CONTENT); 218 layoutParams.setFullSpan(true); 219 220 mLoadingViewHolder.llyLoading.setLayoutParams(layoutParams); 221 } 222 } 223 } 224 225 @Override 226 public int getItemCount() { 227 return mTs.size(); 228 } 229 }
4.一個簡單的列子
1 /** 2 * Created by sunwei on 2015/12/4. 3 * Email: [email protected]. 4 * Description: 加載更多 5 */ 6 public class DesignLoaderMoreAdapter extends BaseLoadingAdapter<DesignItem> { 7 8 private CircularArray<DesignItem> mDesignItems; 9 10 public DesignLoaderMoreAdapter(RecyclerView recyclerView, CircularArray<DesignItem> datas) { 11 super(recyclerView, datas); 12 13 mDesignItems = datas; 14 } 15 16 //正常條目 17 public class DesignViewHolder extends RecyclerView.ViewHolder { 18 public TextView textView; 19 public CardView cardView; 20 public DesignViewHolder(View view) { 21 super(view); 22 textView = (TextView) view.findViewById(R.id.tv_design); 23 cardView = (CardView) view.findViewById(R.id.cardView_designer); 24 25 } 26 } 27 28 @Override 29 public RecyclerView.ViewHolder onCreateNormalViewHolder(ViewGroup parent) { 30 View view = LayoutInflater.from(parent.getContext()).inflate( 31 R.layout.list_item_design, parent, false); 32 return new DesignViewHolder(view); 33 } 34 35 @Override 36 public void onBindNormalViewHolder(RecyclerView.ViewHolder holder, int position) { 37 DesignViewHolder viewHolder = (DesignViewHolder)holder; 38 DesignItem designItem = mDesignItems.get(position); 39 if (position == 10) { 40 //設置瀑布流的條目大小 41 LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(260, 360); 42 lp.setMargins(10, 40, 10, 80); 43 viewHolder.cardView.setLayoutParams(lp); 44 } 45 46 viewHolder.textView.setText(designItem.name); 47 } 48 }
項目地址:https://github.com/lxsunwei/MaterialDesignDemo
一款面試復習應用源碼,面試復習源碼為了更好地准備面試android開發這一職位,於是就到應用市場查找相關的復習App,結果發現只有寥寥無幾的幾款,而且很不好用,Andro
推送:騰迅信鴿 VS Bmob,信鴿bmob最近幾天了解市場上主流的推送SDK。 騰迅信鴿 所需SDK,去官網自行下載。去下載 完整的清單文件如下: 1
Android Git 客戶端,androidgit客戶端1、tortoisegit Git下載地址: https://tortoisegit.org/do
安卓開發與分析者的利器--安卓右鍵工具 安卓右鍵工具,集成dex轉jar,二進制xml查看,apk相關信息查詢,apk圖標提取,apk優化,手機屏幕截圖,安裝卸載,簽