前面咱們講到了使用OkHttp請求網絡和FastJson解析數據了,接下來咱們就開始把獲取到的數據經過數據適配器展現在頁面上了。Adapter是用來幫助填充數據的中間橋樑,簡單點說就是:將各類數據以合適的形式顯示到view上,提供給用戶看!java
商城首頁的數據是使用RecyclerView進行展現的,下面咱們來說講如何將獲取到的數據經過RecyclerView展現。android
首先看一下HomeFragment的佈局代碼,代碼以下:json
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,這個適配器是展現數據的具體實現:app
HomeFragmentAdapter類代碼以下所示:ide
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的佈局實現佈局