前面我们讲到了使用OkHttp请求网络和FastJson解析数据了,接下来我们就开始把获取到的数据通过数据适配器展示在页面上了。Adapter是用来帮助填充数据的中间桥梁,简单点说就是:将各种数据以合适的形式显示到view上,提供给用户看!
商城首页的数据是使用RecyclerView进行展示的,下面我们来讲讲如何将获取到的数据通过RecyclerView展示。
首先看一下HomeFragment的布局代码,代码如下:
1 <?xml version="1.0" encoding="utf-8"?>
2 <RelativeLayout
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 android:layout_width="match_parent"
5 android:layout_height="match_parent">
6
7 <!--搜索框布局-->
8 <include
9 android:id="@+id/titlebar"
10 layout="@layout/titlebar"/>
11
12 <!--展示数据的RecyclerView-->
13 <android.support.v7.widget.RecyclerView
14 android:id="@+id/rv_home"
15 android:layout_width="match_parent"
16 android:layout_height="match_parent"
17 android:layout_below="@id/titlebar" />
18
19 <!--回到顶部图片按钮-->
20 <ImageButton
21 android:id="@+id/ib_top"
22 android:layout_width="40dp"
23 android:layout_height="40dp"
24 android:layout_alignParentBottom="true"
25 android:layout_alignParentRight="true"
26 android:layout_marginBottom="20dp"
27 android:layout_marginRight="20dp"
28 android:background="@mipmap/ic_launcher"
29 android:visibility="gone" />
30
31
32 </RelativeLayout>
布局代码很简单,整体是一个RelativeLayout布局,里面有一个RecyclerView,用于展示数据,接下来我们看一下HomeFragment的代码:
1 package com.nyl.shoppingmall.home.fragment;
2
3 import android.support.v7.widget.GridLayoutManager;
4 import android.support.v7.widget.RecyclerView;
5 import android.util.Log;
6 import android.view.View;
7 import android.widget.ImageView;
8 import android.widget.TextView;
9 import android.widget.Toast;
10
11 import com.alibaba.fastjson.JSON;
12 import com.nyl.shoppingmall.R;
13 import com.nyl.shoppingmall.base.BaseFragment;
14 import com.nyl.shoppingmall.home.adapter.HomeFragmentAdapter;
15 import com.nyl.shoppingmall.home.bean.ResultBeanData;
16 import com.nyl.shoppingmall.utils.Constants;
17 import com.zhy.http.okhttp.OkHttpUtils;
18 import com.zhy.http.okhttp.callback.StringCallback;
19
20 import okhttp3.Call;
21
22 /**
23 * 首页Fragment
24 */
25 public class HomeFragment extends BaseFragment implements View.OnClickListener {
26
27 private final static String TAG = HomeFragment.class.getSimpleName();
28
29 private TextView tv_search_home;
30 private TextView tv_message_home;
31 private RecyclerView rv_home;
32 private ImageView ib_top;
33 private HomeFragmentAdapter adapter;
34 //返回的数据
35 private ResultBeanData.ResultBean resultBean;
36
37 @Override
38 public View initView() {
39 Log.e(TAG,"主页面的Fragment的UI被初始化了");
40 View view = View.inflate(mContext,R.layout.fragment_home,null);
41 //初始化布局控件
42 tv_search_home = (TextView) view.findViewById(R.id.tv_search_home);
43 tv_message_home = (TextView) view.findViewById(R.id.tv_message_home);
44 rv_home = (RecyclerView) view.findViewById(R.id.rv_home);
45 ib_top = (ImageView) view.findViewById(R.id.ib_top);
46
47 //设置点击事件
48 ib_top.setOnClickListener(this);
49 tv_search_home.setOnClickListener(this);
50 tv_message_home.setOnClickListener(this);
51 return view;
52 }
53
54
55 @Override
56 public void initData() {
57 super.initData();
58 Log.e(TAG,"主页面的Fragment的数据被初始化了");
59
60 //联网请求首页数据
61 getDataFromNet();
62 }
63
64 private void getDataFromNet() {
65 // String url = Constants.HOME_URL;
66 OkHttpUtils
67 .get()
68 .url(Constants.HOME_URL)
69 .build()
70 .execute(new StringCallback()
71 {
72
73 /**
74 * 请求失败的时候回调
75 * @param call
76 * @param e
77 * @param id
78 */
79 @Override
80 public void onError(Call call, Exception e, int id) {
81
82 Log.e(TAG,"首页请求失败=="+e.getMessage());
83 }
84
85 /**
86 * 当联网成功的时候回调
87 * @param response 请求成功数据
88 * @param id
89 */
90 @Override
91 public void onResponse(String response, int id) {
92
93 Log.e(TAG,"首页请求成功=="+response);
94 //解析数据
95 processData(response);
96 }
97 });
98 }
99
100 /**
101 * 解析数据
102 * @param json
103 */
104 private void processData(String json) {
105 //使用FastJson去解析数据,将Json字符串转换成一个ResultBeanData对象
106 ResultBeanData resultBeanData = JSON.parseObject(json,ResultBeanData.class);
107 resultBean = resultBeanData.getResult();
108
109 if (resultBean != null){
110 //有数据就设置适配器
111 adapter = new HomeFragmentAdapter(mContext,resultBean);
112 rv_home.setAdapter(adapter);
113
114 GridLayoutManager manager = new GridLayoutManager(mContext,1);
115 //设置跨度大小监听
116 manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
117 @Override
118 public int getSpanSize(int position) {
119 if (position <= 3){
120 //隐藏
121 ib_top.setVisibility(View.GONE);
122 }else {
123 //显示
124 ib_top.setVisibility(View.VISIBLE);
125 }
126 //只能返回1
127 return 1;
128 }
129 });
130 //设置布局管理者
131 rv_home.setLayoutManager(manager);
132 }else {
133 //没有数据
134
135 }
136
137 Log.e(TAG,"解析成功=="+resultBean.getHot_info().get(0).getName());
138 }
139
140 @Override
141 public void onClick(View view) {
142 switch (view.getId()){
143 case R.id.ib_top: //置顶的监听
144 rv_home.scrollToPosition(0);
145 break;
146 case R.id.tv_search_home: //搜索的监听
147 Toast.makeText(mContext,"搜索",Toast.LENGTH_SHORT).show();
148 break;
149 case R.id.tv_message_home: //消息监听
150 Toast.makeText(mContext,"进入消息中心",Toast.LENGTH_SHORT).show();
151 break;
152 }
153 }
154 }
HomeFragmet的代码也很简单,首先是初始化视图,然后联网调用接口获取数据,通过FastJson解析数据,然后将数据传入到HomeFragmentAdapter进行展示,接下来我们看一下HomeFragmentAdapter,这个适配器是展示数据的具体实现:
HomeFragmentAdapter类代码如下所示:
1 package com.nyl.shoppingmall.home.adapter;
2
3 import android.content.Context;
4 import android.content.Intent;
5 import android.os.Handler;
6 import android.os.Message;
7 import android.support.v4.view.PagerAdapter;
8 import android.support.v4.view.ViewPager;
9 import android.support.v7.widget.LinearLayoutManager;
10 import android.support.v7.widget.RecyclerView;
11 import android.view.LayoutInflater;
12 import android.view.View;
13 import android.view.ViewGroup;
14 import android.widget.AdapterView;
15 import android.widget.GridView;
16 import android.widget.ImageView;
17 import android.widget.TextView;
18 import android.widget.Toast;
19
20 import com.bumptech.glide.Glide;
21 import com.nyl.shoppingmall.R;
22 import com.nyl.shoppingmall.app.activity.GoodsInfoActivity;
23 import com.nyl.shoppingmall.home.bean.ResultBeanData;
24 import com.nyl.shoppingmall.utils.Constants;
25 import com.youth.banner.Banner;
26 import com.youth.banner.BannerConfig;
27 import com.youth.banner.Transformer;
28 import com.youth.banner.listener.OnBannerClickListener;
29 import com.youth.banner.listener.OnLoadImageListener;
30 import com.zhy.magicviewpager.transformer.ScaleInTransformer;
31
32 import java.text.SimpleDateFormat;
33 import java.util.ArrayList;
34 import java.util.Date;
35 import java.util.List;
36
37 /**
38 * 首页适配器
39 */
40
41 public class HomeFragmentAdapter extends RecyclerView.Adapter{
42
43 /**
44 * 广告幅类型
45 */
46 public static final int BANNER = 0;
47
48 /**
49 * 频道类型
50 */
51 public static final int CHANNEL = 1;
52
53 /**
54 * 活动类型
55 */
56 public static final int ACT = 2;
57
58 /**
59 * 秒杀类型
60 */
61 public static final int SECKILL = 3;
62
63 /**
64 * 推荐类型
65 */
66 public static final int RECOMMEND = 4;
67
68 /**
69 * 热卖类型
70 */
71 public static final int HOT = 5;
72
73 /**
74 * 初始化布局
75 */
76 private LayoutInflater mLayoutInflater;
77
78 /**
79 * 数据
80 */
81 private ResultBeanData.ResultBean resultBean;
82
83
84 private Context mContext;
85
86 /**
87 * 当前类型
88 */
89 private int currenType = BANNER;
90
91 public HomeFragmentAdapter(Context mContext, ResultBeanData.ResultBean resultBean) {
92 this.mContext = mContext;
93 this.resultBean = resultBean;
94 mLayoutInflater = LayoutInflater.from(mContext);
95 }
96
97 /**
98 * 根据视图类型创建ViewHolder
99 * @param parent
100 * @param viewType 当前的视图类型
101 * @return RecyclerView.ViewHolder
102 */
103 @Override
104 public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
105 //广告福
106 if (viewType == BANNER){
107 //创建BannerViewHolder,Banner里面传布局文件
108 return new BannerViewHolder(mContext,mLayoutInflater.inflate(R.layout.banner_viewpager,null));
109 //频道
110 }else if (viewType == CHANNEL){
111 return new ChannelViewHolder(mContext,mLayoutInflater.inflate(R.layout.channel_item,null));
112 //活动
113 }else if (viewType == ACT){
114 return new ActViewHolder(mContext,mLayoutInflater.inflate(R.layout.act_item,null));
115 //秒杀
116 }else if (viewType == SECKILL){
117 return new SeckillViewHolder(mContext,mLayoutInflater.inflate(R.layout.seckkill_item,null));
118 //推荐
119 }else if (viewType == RECOMMEND){
120 return new RecommendViewHolder(mContext,mLayoutInflater.inflate(R.layout.recommend_item,null));
121 //热卖
122 }else if (viewType == HOT){
123 return new HotViewHolder(mContext,mLayoutInflater.inflate(R.layout.hot_item,null));
124 }
125 return null;
126 }
127
128 /**
129 * 绑定数据到ViewHolder
130 * @param holder
131 * @param position
132 */
133 @Override
134 public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
135 /**
136 * 轮循广告
137 */
138 if (getItemViewType(position) == BANNER){
139 BannerViewHolder bannerViewHolder = (BannerViewHolder) holder;
140 bannerViewHolder.setData(resultBean.getBanner_info());
141
142 }
143 /**
144 * 频道
145 */
146 else if (getItemViewType(position) == CHANNEL){
147 ChannelViewHolder channelViewHolder = (ChannelViewHolder) holder;
148 channelViewHolder.setData(resultBean.getChannel_info());
149
150 }
151 /**
152 * 活动
153 */
154 else if (getItemViewType(position) == ACT){
155 ActViewHolder actViewHolder = (ActViewHolder) holder;
156 actViewHolder.setData(resultBean.getAct_info());
157
158 }
159 /**
160 * 秒杀
161 */
162 else if (getItemViewType(position) == SECKILL){
163 SeckillViewHolder seckillViewHolder = (SeckillViewHolder) holder;
164 seckillViewHolder.setData(resultBean.getSeckill_info());
165
166 }
167 /**
168 * 推荐
169 */
170 else if (getItemViewType(position) == RECOMMEND){
171 RecommendViewHolder recommendViewHolder = (RecommendViewHolder) holder;
172 recommendViewHolder.setData(resultBean.getRecommend_info());
173
174 }
175 /**
176 * 热卖
177 */
178 else if (getItemViewType(position) == HOT){
179 HotViewHolder hotViewHolder = (HotViewHolder) holder;
180 hotViewHolder.setData(resultBean.getHot_info());
181 }
182 }
183
184 /**
185 * 广告幅
186 */
187 class BannerViewHolder extends RecyclerView.ViewHolder{
188
189 private Context mContext;
190 private Banner banner;
191
192 public BannerViewHolder(Context mContext, View itemView) {
193 super(itemView);
194 this.mContext = mContext;
195 this.banner = (Banner) itemView.findViewById(R.id.banner);
196 }
197
198 public void setData(List<ResultBeanData.ResultBean.BannerInfoEntity> banner_info) {
199 //得到图片集合地址
200 List<String> imagesUrl = new ArrayList<>();
201 for (int i = 0;i<banner_info.size();i++){
202 String imageUrl = banner_info.get(i).getImage();
203 imagesUrl.add(imageUrl);
204 }
205 //设置循环指示点
206 banner.setBannerStyle(BannerConfig.CIRCLE_INDICATOR);
207 //设置手风琴效果
208 banner.setBannerAnimation(Transformer.Accordion);
209 //设置Banner图片数据
210 banner.setImages(imagesUrl, new OnLoadImageListener() {
211 @Override
212 public void OnLoadImage(ImageView view, Object url) {
213 //联网请求图片-Glide
214 Glide.with(mContext).load(Constants.BASE_URL_IMAGE + url).into(view);
215 }
216 });
217 //设置点击事件
218 banner.setOnBannerClickListener(new OnBannerClickListener() {
219 @Override
220 public void OnBannerClick(int position) {
221 Toast.makeText(mContext,"position=="+position,Toast.LENGTH_SHORT).show();
222 //跳转到商品信息界面
223 startGoodsInfoActivity();
224 }
225
226 });
227 }
228 }
229
230 /**
231 * 频道
232 */
233 class ChannelViewHolder extends RecyclerView.ViewHolder{
234
235 private Context mContext;
236 private GridView gv_channel;
237 private ChannelAdapter adapter;
238
239 public ChannelViewHolder(Context mContext, View itemView) {
240 super(itemView);
241 this.mContext = mContext;
242 gv_channel = (GridView) itemView.findViewById(R.id.gv_channel);
243 }
244
245 public void setData(List<ResultBeanData.ResultBean.ChannelInfoBean> channel_info) {
246 //得到数据后,就设置GridView的适配器
247 adapter = new ChannelAdapter(mContext,channel_info);
248 gv_channel.setAdapter(adapter);
249
250 //设置item的点击事件
251 gv_channel.setOnItemClickListener(new AdapterView.OnItemClickListener() {
252 @Override
253 public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
254 Toast.makeText(mContext,"position"+position,Toast.LENGTH_SHORT).show();
255 }
256 });
257 }
258 }
259
260 /**
261 * 活动
262 */
263 class ActViewHolder extends RecyclerView.ViewHolder{
264
265 private Context mContext;
266 private ViewPager act_viewpager;
267
268 public ActViewHolder(Context mContext,View itemView) {
269 super(itemView);
270 this.mContext = mContext;
271 act_viewpager = (ViewPager) itemView.findViewById(R.id.act_viewpager);
272 }
273
274 public void setData(final List<ResultBeanData.ResultBean.ActInfoEntity> act_info) {
275 //设置间距
276 act_viewpager.setPageMargin(20);
277 act_viewpager.setOffscreenPageLimit(3);//>=3
278 //setPageTransformer 决定动画效果
279 act_viewpager.setPageTransformer(true, new ScaleInTransformer());
280 //有数据后,就设置数据适配器
281 act_viewpager.setAdapter(new PagerAdapter() {
282 @Override
283 public int getCount() {
284 return act_info.size();
285 }
286
287 /**
288 *
289 * @param view 页面
290 * @param object instantiateItem方法返回的值
291 * @return
292 */
293 @Override
294 public boolean isViewFromObject(View view, Object object) {
295 return view == object;
296 }
297
298 /**
299 *
300 * @param container ViewPager
301 * @param position 对应页面的位置
302 * @return
303 */
304 @Override
305 public Object instantiateItem(ViewGroup container, final int position) {
306 //实例化ImageView
307 ImageView imageView = new ImageView(mContext);
308 //设置ImageView的拉伸
309 imageView.setScaleType(ImageView.ScaleType.FIT_XY);
310 //根据Glide设置图片
311 Glide.with(mContext).load(Constants.BASE_URL_IMAGE+act_info.get(position).getIcon_url()).into(imageView);
312 //添加到容器中
313 container.addView(imageView);
314
315 //设置点击事件
316 imageView.setOnClickListener(new View.OnClickListener() {
317 @Override
318 public void onClick(View view) {
319 Toast.makeText(mContext,"position=="+position,Toast.LENGTH_SHORT).show();
320 }
321 });
322 return imageView;
323 }
324
325 @Override
326 public void destroyItem(ViewGroup container, int position, Object object) {
327 container.removeView((View) object);
328 }
329 });
330 }
331 }
332
333 /**
334 * 秒杀
335 */
336 class SeckillViewHolder extends RecyclerView.ViewHolder{
337
338 private Context mContext;
339 private TextView tv_time_seckill;
340 private TextView tv_more_seckill;
341 private RecyclerView rv_seckill;
342 private SeckillRecycleViewAdapter adapter;
343
344 /**
345 * 相差多少时间-毫秒
346 */
347 private long dt = 0;
348 //不断循环
349 private Handler handler = new Handler(){
350 @Override
351 public void handleMessage(Message msg) {
352 super.handleMessage(msg);
353 dt = dt - 1000;
354 //设置具体的时间
355 SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm:ss");
356 String time = dateFormat.format(new Date(dt));
357 tv_time_seckill.setText(time);
358
359 handler.removeMessages(0);
360 //发送消息,不断减时间
361 handler.sendEmptyMessageDelayed(0,1000);
362 if (dt <= 0){
363 //把消息移除
364 handler.removeCallbacksAndMessages(null);
365 }
366 }
367 };
368
369 public SeckillViewHolder(Context mContext, View itemView) {
370 super(itemView);
371 this.mContext = mContext;
372 //初始化布局控件
373 tv_time_seckill = (TextView) itemView.findViewById(R.id.tv_time_seckill);
374 tv_more_seckill = (TextView) itemView.findViewById(R.id.tv_more_seckill);
375 rv_seckill = (RecyclerView) itemView.findViewById(R.id.rv_seckill);
376 }
377
378 public void setData(ResultBeanData.ResultBean.SeckillInfoEntity seckill_info) {
379 //得到数据后,就是设置数据(TextView和RecyclerView)的数据
380 adapter = new SeckillRecycleViewAdapter(mContext,seckill_info.getList());
381 rv_seckill.setAdapter(adapter);
382
383 //设置布局管理器
384 rv_seckill.setLayoutManager(new LinearLayoutManager(mContext,LinearLayoutManager.HORIZONTAL,false));
385 //设置item的点击事件
386 adapter.setOnSeckillRecyclerView(new SeckillRecycleViewAdapter.OnSeckillRecyclerView() {
387 @Override
388 public void onItemClick(int position) {
389 Toast.makeText(mContext,"秒杀"+position,Toast.LENGTH_SHORT).show();
390 startGoodsInfoActivity();
391 }
392 });
393 //秒杀倒计时-毫秒
394 dt = Integer.valueOf(seckill_info.getEnd_time()) - Integer.valueOf(seckill_info.getStart_time());
395 //进入后1秒钟就去发送这个消息
396 handler.sendEmptyMessageDelayed(0,1000);
397
398 }
399 }
400
401 /**
402 * 推荐
403 */
404 class RecommendViewHolder extends RecyclerView.ViewHolder{
405
406 private final Context mContext;
407 private TextView tv_more_recommend;
408 private GridView gv_recommend;
409 private RecommendGridViewAdapter adapter;
410
411 public RecommendViewHolder(final Context mContext, View itemView) {
412 super(itemView);
413 this.mContext = mContext;
414 tv_more_recommend = (TextView) itemView.findViewById(R.id.tv_more_recommend);
415 gv_recommend = (GridView) itemView.findViewById(R.id.gv_recommend);
416
417 //设置点击事件
418 gv_recommend.setOnItemClickListener(new AdapterView.OnItemClickListener() {
419 @Override
420 public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
421 Toast.makeText(mContext,"position=="+position,Toast.LENGTH_SHORT).show();
422 startGoodsInfoActivity();
423 }
424 });
425 }
426
427 public void setData(List<ResultBeanData.ResultBean.RecommendInfoBean> recommend_info) {
428 //有数据了之后,就设置适配器
429 adapter = new RecommendGridViewAdapter(mContext,recommend_info);
430 gv_recommend.setAdapter(adapter);
431
432 }
433 }
434
435 /**
436 * 热门
437 */
438 class HotViewHolder extends RecyclerView.ViewHolder{
439
440 private final Context mContext;
441 private TextView tv_more_hot;
442 private GridView gv_hot;
443 private HotGridViewAdapter adapter;
444
445 public HotViewHolder(final Context mContext, View itemView) {
446 super(itemView);
447 this.mContext = mContext;
448 tv_more_hot = (TextView) itemView.findViewById(R.id.tv_more_hot);
449 gv_hot = (GridView) itemView.findViewById(R.id.gv_hot);
450 //设置item的点击事件
451 gv_hot.setOnItemClickListener(new AdapterView.OnItemClickListener() {
452 @Override
453 public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
454 Toast.makeText(mContext,"position"+position,Toast.LENGTH_SHORT).show();
455 startGoodsInfoActivity();
456 }
457 });
458 }
459
460 public void setData(List<ResultBeanData.ResultBean.HotInfoBean> hot_info) {
461 //有数据后,就设置GridView的适配器
462 adapter = new HotGridViewAdapter(mContext,hot_info);
463 gv_hot.setAdapter(adapter);
464 }
465 }
466
467
468 /**
469 * 启动商品信息列表页面
470 */
471 private void startGoodsInfoActivity() {
472 Intent intent = new Intent(mContext, GoodsInfoActivity.class);
473 mContext.startActivity(intent);
474 }
475
476 /**
477 * 根据position得到不同的类型
478 * @param position
479 * @return
480 */
481 @Override
482 public int getItemViewType(int position) {
483 switch (position){
484 case BANNER: //广告幅
485 currenType = BANNER;
486 break;
487 case CHANNEL: //频道
488 currenType = CHANNEL;
489 break;
490 case ACT: //活动
491 currenType = ACT;
492 break;
493 case SECKILL: //秒杀
494 currenType = SECKILL;
495 break;
496 case RECOMMEND: //推荐
497 currenType = RECOMMEND;
498 break;
499 case HOT: //热卖
500 currenType = HOT;
501 break;
502 }
503 return currenType;
504 }
505
506 /**
507 * 总共有多少个item
508 * @return
509 */
510 @Override
511 public int getItemCount() {
512 return 6;
513 }
514
515
516 }
HomeFragmentAdapter的代码非常多,但思路是很清晰的,HomeFragmentAdapter是一个多布局item的RecyclerView.Adapter,里面定义了6种不同的item视图类型,在onCreateViewHolder方法中
根据viewType构建出每个item的布局(ViewHolder),然后在onBindViewHolder方法中将数据绑定到不同ViewHolder上。最终效果图如下:
关于使用RecyclerView展示首页数据的内容就介绍这么多。下一篇将具体介绍HomeFragmentAdapter中每一个item的布局实现