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

首頁 > 系統 > Android > 正文

Android項目實戰之仿網易新聞的頁面(RecyclerView )

2020-04-11 10:57:08
字體:
來源:轉載
供稿:網友

本文實例實現一個仿網易新聞的頁面,上面是輪播的圖片,下面是 RecyclerView 顯示新聞列表,具體內容如下

錯誤方法

<?xml version="1.0" encoding="utf-8"?><LinearLayout ...> <ViewPager ... /> <android.support.v7.widget.RecyclerView .../></LinearLayout>

這樣布局 ViewPager 在 RecyclerView 的上面,如果不做特殊處理,當下滑 RecyclerView 加載更多內容的時候,ViewPager會固定不動。

正確的效果是下滑加載更多的時候,ViewPager 會滑出頁面,釋放空間供其他內容展示。
一、解決思路

方法有兩種

  • ViewPager作為 RecyclerView 的第0項,也就是 Header(本文采用該方法)
  • 利用ScrollView,重寫一些方法解決滑動沖突

總xml布局

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.RecyclerView  android:id="@+id/rcv_article_latest"  android:layout_width="match_parent"  android:layout_height="0dp"  android:layout_weight="1" /></LinearLayout>

很簡單,一個RecyclerView就行了

頭部 ViewPager 的viewholder_article_header.xml布局

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!--ViewPager 熱門文章圖片展示--> <FrameLayout  android:layout_width="match_parent"  android:layout_height="200dp"  android:background="@color/gray_light">  <android.support.v4.view.ViewPager   android:id="@+id/vp_hottest"   android:layout_width="match_parent"   android:layout_height="match_parent"   android:background="@color/colorPrimary" />  <LinearLayout   android:id="@+id/ll_hottest_indicator"   android:layout_width="wrap_content"   android:layout_height="20dp"   android:layout_gravity="bottom|right"   android:layout_marginBottom="5dp"   android:layout_marginRight="10dp"   android:layout_marginTop="5dp"   android:gravity="center"   android:orientation="horizontal" /> </FrameLayout></LinearLayout>

FrameLayout里面的ViewPager和LinearLayout是覆蓋顯示的,實現在圖片的下方有個小圓點標記滑動到了第一張圖片。

新聞項 viewholder_article_item.xml 布局

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:fresco="http://schemas.android.com/apk/res-auto" android:id="@+id/cv_item" android:layout_width="match_parent" android:layout_height="wrap_content" app:cardCornerRadius="5dp" app:cardElevation="5dp" app:contentPadding="2dp"> <LinearLayout  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:orientation="horizontal">  <com.facebook.drawee.view.SimpleDraweeView   android:id="@+id/rcv_article_photo"   android:layout_width="100dp"   android:layout_height="100dp"   fresco:actualImageScaleType="centerInside"   fresco:roundAsCircle="true"   fresco:roundingBorderColor="@color/lightslategray"   fresco:roundingBorderWidth="1dp" />  <LinearLayout   android:layout_width="0dp"   android:layout_height="match_parent"   android:layout_weight="1"   android:orientation="vertical">   <TextView    android:id="@+id/rcv_article_title"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_marginLeft="10dp"    android:layout_marginTop="2dp"    android:gravity="center"    android:text="關于舉辦《經典音樂作品欣賞與人文審美》講座的通知"    android:textColor="@color/primary_text" />   <!-- 新聞 發布時間 來源 閱讀次數-->   <LinearLayout    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_marginTop="5dp"    android:gravity="center"    android:orientation="horizontal">    <TextView     android:id="@+id/rcv_article_date"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:layout_marginLeft="10dp"     android:layout_marginRight="2dp"     android:text="2015-01-09" />    <TextView     android:id="@+id/rcv_article_source"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:layout_marginLeft="2dp"     android:layout_marginRight="2dp"     android:text="科學研究院" />    <TextView     android:id="@+id/rcv_article_readtimes"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:layout_marginLeft="2dp"     android:layout_marginRight="2dp"     android:text="1129次" />   </LinearLayout>   <TextView    android:id="@+id/rcv_article_preview"    android:layout_width="wrap_content"    android:layout_height="0dp"    android:layout_weight="1"    android:layout_marginLeft="10dp"    android:layout_marginTop="5dp"    android:ellipsize="end"    android:maxLines="2"    android:text="講座主要內容:以中、西方音樂歷史中經典音樂作品為基礎,通過作曲家及作品創作背景、相關音樂文化史知識及音樂欣賞常識..." />  </LinearLayout> </LinearLayout></android.support.v7.widget.CardView>

這篇文章 Android Material Design學習之RecyclerView代替 ListView sscc實現了不加 ViewPager,利用 RecyclerView 展示新聞列表的功能。

RecyclerView 的適配器

/** * 新聞列表的適配器 * 01-14 頭部是 ViewPager,下面是列表新聞 * Created by tomchen on 1/11/16. */public class ArticleAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private static final int TYPE_HEADER = 0; private static final int TYPE_ITEM = 1; //頭部固定為 張圖片 private static final int NUM_IMAGE = 4; //Handler 用到的參數值 private static final int UPTATE_VIEWPAGER = 0; //新聞列表 private List<ItemArticle> articleList; //設置當前 第幾個圖片 被選中 private int currentIndex = 0; //context private Context context; private LayoutInflater mLayoutInflater; private ImageView[] mCircleImages;//底部只是當前頁面的小圓點 public ArticleAdapter(Context context, List<ItemArticle> articleList) {  this.context = context;  //頭部viewpager圖片固定是7張,剩下的是列表的數據  this.articleList = articleList;  mLayoutInflater = LayoutInflater.from(context); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  //理論上應該把最可能返回的 TYPE 放在前面  View view = null;  if (viewType == TYPE_ITEM) {   view = mLayoutInflater.inflate(     R.layout.viewholder_article_item, parent, false);   return new ItemArticleViewHolder(view);  }  //頭部返回 ViewPager 實現的輪播圖片  if (viewType == TYPE_HEADER) {   view = mLayoutInflater.inflate(     R.layout.viewholder_article_header, parent, false);   return new HeaderArticleViewHolder(view);  }  return null;//  //可以拋出異常,沒有對應的View類型//  throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly"); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {  if (holder instanceof ItemArticleViewHolder) {   //轉型   ItemArticleViewHolder newHolder = (ItemArticleViewHolder) holder;   //注意RecyclerView第0項是 ViewPager 占據了0 1 2 3圖片   //那么下面的列表展示是 RecyclerView 的第1項,從第4項開始   ItemArticle article = articleList.get(position + NUM_IMAGE - 1);   newHolder.rcvArticlePhoto.setImageURI(Uri.parse(article.getImageUrl()));   newHolder.rcvArticleTitle.setText(article.getTitle());   newHolder.rcvArticleDate.setText(article.getPublishDate());   newHolder.rcvArticleSource.setText(article.getSource());   //注意這個閱讀次數是 int 類型,需要轉化為 String 類型   newHolder.rcvArticleReadtimes.setText(article.getReadTimes() + "次");   newHolder.rcvArticlePreview.setText(article.getPreview());  } else if (holder instanceof HeaderArticleViewHolder) {   HeaderArticleViewHolder newHolder = (HeaderArticleViewHolder) holder;   List<ItemArticle> headers = articleList.subList(0, NUM_IMAGE );   HeaderImageAdapter imageAdapter = new HeaderImageAdapter(context, headers);   setUpViewPager(newHolder.vpHottest, newHolder.llHottestIndicator, headers);  } } private void setUpViewPager(final ViewPager vp, LinearLayout llBottom, final List<ItemArticle> headerArticles) {  HeaderImageAdapter imageAdapter = new HeaderImageAdapter(context, headerArticles);  //??這兒有些疑惑,Adapter 里面嵌套設置 Adapter 是否優雅?  vp.setAdapter(imageAdapter);  final Handler mHandler = new Handler() {   public void handleMessage(Message msg) {    switch (msg.what) {     case UPTATE_VIEWPAGER:      if (msg.arg1 != 0) {       vp.setCurrentItem(msg.arg1);      } else {       //false 當從末頁調到首頁是,不顯示翻頁動畫效果,       vp.setCurrentItem(msg.arg1, false);      }      break;    }   }  };  //下面是設置動畫切換的樣式  vp.setPageTransformer(true, new RotateUpTransformer());  //創建底部指示位置的導航欄  final ImageView[] mCircleImages = new ImageView[headerArticles.size()];  for (int i = 0; i < mCircleImages.length; i++) {   ImageView imageView = new ImageView(context);   LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(10, 10);   params.setMargins(5, 0, 5, 0);   imageView.setLayoutParams(params);   if (i == 0) {    imageView.setBackgroundResource(R.drawable.indicator_select);   } else {    imageView.setBackgroundResource(R.drawable.indicator_not_select);   }   mCircleImages[i] = imageView;   //把指示作用的原點圖片加入底部的視圖中   llBottom.addView(mCircleImages[i]);  }  vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {   //圖片左右滑動時候,將當前頁的圓點圖片設為選中狀態   @Override   public void onPageSelected(int position) {    // 一定幾個圖片,幾個圓點,但注意是從0開始的    int total = mCircleImages.length;    for (int j = 0; j < total; j++) {     if (j == position) {      mCircleImages[j].setBackgroundResource(R.drawable.indicator_select);     } else {      mCircleImages[j].setBackgroundResource(R.drawable.indicator_not_select);     }    }    //設置全局變量,currentIndex為選中圖標的 index    currentIndex = position;   }   @Override   public void onPageScrolled(int i, float v, int i1) {   }   @Override   public void onPageScrollStateChanged(int state) {    //實現切換到末尾后返回到第一張    switch (state) {     // 手勢滑動     case ViewPager.SCROLL_STATE_DRAGGING:      break;     // 界面切換中     case ViewPager.SCROLL_STATE_SETTLING:      break;     case ViewPager.SCROLL_STATE_IDLE:// 滑動結束,即切換完畢或者加載完畢      // 當前為最后一張,此時從右向左滑,則切換到第一張      if (vp.getCurrentItem() == vp.getAdapter()        .getCount() - 1) {       vp.setCurrentItem(0, false);      }      // 當前為第一張,此時從左向右滑,則切換到最后一張      else if (vp.getCurrentItem() == 0) {       vp.setCurrentItem(vp.getAdapter()         .getCount() - 1, false);      }      break;     default:      break;    }   }  });  //設置自動輪播圖片,5s后執行,周期是5s  Timer timer = new Timer();  timer.schedule(new TimerTask() {   @Override   public void run() {    Message message = new Message();    message.what = UPTATE_VIEWPAGER;    if (currentIndex == headerArticles.size() - 1) {     currentIndex = -1;    }    message.arg1 = currentIndex + 1;    mHandler.sendMessage(message);   }  }, 6000, 6000); } @Override public int getItemCount() {  //因為多了一個頭部,所以是+1,但是頭部 ViewPager 占了7個  //所以實際是少了6個  return articleList.size() + 1 - NUM_IMAGE; } @Override public int getItemViewType(int position) {  if (position == 0)   return TYPE_HEADER;  else   return TYPE_ITEM; } class HeaderArticleViewHolder extends RecyclerView.ViewHolder {  //輪播的最熱新聞圖片  @InjectView(R.id.vp_hottest)  ViewPager vpHottest;  //輪播圖片下面的小圓點  @InjectView(R.id.ll_hottest_indicator)  LinearLayout llHottestIndicator;  //學院廣播信息  @InjectView(R.id.tv_college_broadcast)  TextView tvCollegeBroadcast;  public HeaderArticleViewHolder(View itemView) {   super(itemView);   ButterKnife.inject(this, itemView);  } } class ItemArticleViewHolder extends RecyclerView.ViewHolder {  @InjectView(R.id.rcv_article_photo)  SimpleDraweeView rcvArticlePhoto;  @InjectView(R.id.rcv_article_title)  TextView rcvArticleTitle;  @InjectView(R.id.rcv_article_date)  TextView rcvArticleDate;  @InjectView(R.id.rcv_article_source)  TextView rcvArticleSource;  @InjectView(R.id.rcv_article_readtimes)  TextView rcvArticleReadtimes;  @InjectView(R.id.rcv_article_preview)  TextView rcvArticlePreview;  public ItemArticleViewHolder(View itemView) {   super(itemView);   ButterKnife.inject(this, itemView);  } }}

ItemArticleViewHolder是列表展示的新聞項的 ViewHolder,對應了上面的 viewholder_article_item.xml。

HeaderArticleViewHolder 是頭部 ViewPager 的 ViewHolder, 對應viewholder_article_header.xml

Note

  • 本文上面的 ViewPager 輪播4幅圖片,所以getItemCount()需要復寫
  • List headers = articleList.subList(0, NUM_IMAGE );得到頭部圖片的數據
  • ItemArticle article = articleList.get(position + NUM_IMAGE - 1);得到下面新聞項的數據
  • getItemViewType(int position)根據position判斷是不是頭部ViewPager
  • onCreateViewHolder(ViewGroup parent, int viewType)根據viewType生成頭部圖片或者下面新聞項的ViewHolder

二、疑惑及后續計劃

除了將 ViewPager 作為 RecyclerView 第一項,還有一張方法就是利用ScrollView,大家可以進行研究。

以上就是本文的全部內容,希望對大家的學習有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 揭东县| 胶南市| 定南县| 自贡市| 商城县| 宜黄县| 黎川县| 望谟县| 手游| 新民市| 浙江省| 依安县| 苗栗县| 山阴县| 武安市| 和林格尔县| 兴业县| 馆陶县| 南雄市| 宁蒗| 棋牌| 汝南县| 龙井市| 玉树县| 页游| 绿春县| 镇坪县| 德安县| 偃师市| 焉耆| 常宁市| 绩溪县| 定陶县| 榕江县| 资阳市| 泰和县| 彭泽县| 昌乐县| 万山特区| 南汇区| 防城港市|