編輯:關於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: lx_sunwei@163.com.
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: lx_sunwei@163.com.
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
推送:騰迅信鴿 VS Bmob,信鴿bmob最近幾天了解市場上主流的推送SDK。 騰迅信鴿 所需SDK,去官網自行下載。去下載 完整的清單文件如下: 1
Android Git 客戶端,androidgit客戶端
Android Git 客戶端,androidgit客戶端1、tortoisegit Git下載地址: https://tortoisegit.org/do
安卓開發與分析者的利器--安卓右鍵工具
安卓開發與分析者的利器--安卓右鍵工具 安卓右鍵工具,集成dex轉jar,二進制xml查看,apk相關信息查詢,apk圖標提取,apk優化,手機屏幕截圖,安裝卸載,簽