文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

学习Android Material Design(RecyclerView代替ListView)

2022-06-06 09:07

关注

本文实例实现一下 RecyclerView,代码比较简单,适合初学者,如有错误,欢迎指出。

复习 ListView

可以查看这篇文章深入浅出学习Android ListView基础,了解关于ListView 的基础知识。

实现过程中需要复写BaseAdapter,主要是这4个方法

public int getCount() :适配器中数据集中 数据的个数,即ListView需要显示的数据个数 public Object getItem(int position) : 获取数据集中与指定索引对应的数据项 public long getItemId(int position) : 获取指定行对应的ID public View getView(int position, View convertView, ViewGroup parent) :获取每一个Item的显示内容

一般 ListView 每一项都是相同的布局,若想各个项实现不同的布局,可复写 getItemViewType和getViewTypeCount实现
RecyclerView 实现

1、xml 布局

下面是RecyclerView中每一项的布局 layout下面的item_article_type_1.xml


<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:card_view="http://schemas.android.com/apk/res-auto"
 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"
 android:foreground="?android:attr/selectableItemBackground"
 app:cardCornerRadius="5dp"
 app:cardElevation="5dp"
 app:contentPadding="2dp">
 <LinearLayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content">
  <com.facebook.drawee.view.SimpleDraweeView
   android:id="@+id/rcv_article_photo"
   android:layout_width="100dp"
   android:layout_height="100dp"
   android:layout_centerVertical="true"
   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="wrap_content"
    android:layout_marginLeft="10dp"
    android:layout_marginTop="5dp"
    android:ellipsize="end"
    android:maxLines="2"
    android:text="讲座主要内容:以中、西方音乐历史中经典音乐作品为基础,通过作曲家及作品创作背景、相关音乐文化史知识及音乐欣赏常识..." />
  </LinearLayout>
 </LinearLayout>
</android.support.v7.widget.CardView> 

布局思路就是 CardView里面嵌入了一个LinearLayout。图片部分用固定宽度100dp,文字部分利用android:layout_weight=”1”占据了其他部分。

TextView利用android:gravity=”center”使得标题的文字居中。

LinearLayout里面利用android:gravity=”center”使得“2015-01-09 科学研究院 1129次”居中,

新闻详情内容的TextView利用


android:maxLines="2"
android:ellipsize="end"

将文章内容限定为2行,超出部分用省略号显示。

使用fresco这儿有个坑需要注意,请移步这篇文章

Android 之 Fresco 显示圆形图片 之坑

预览效果

新闻列表的 xml 文件,layout 文件夹下面的fragment_article.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"
  android:layout_width="match_parent"
  android:layout_height="0dp"
  android:layout_weight="1" />
</LinearLayout>

2、Adapter 实现

主要步骤是:

根据上面的 item_article_type_1.xml实现一个 class ImageItemArticleViewHolder extends RecyclerView.ViewHolder
继承RecyclerView.Adapter ,class ItemArticleListAdapter extends RecyclerView.Adapter <...>
重写三个方法

public int getItemCount() public TestAdapter.ImageItemArticleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) public void onBindViewHolder(ImageItemArticleViewHolder holder, int position)

public class ItemArticleAdapter extends RecyclerView.Adapter<ItemArticleAdapter.ImageItemArticleViewHolder> {
 //新闻列表
 private List<ItemArticle> articleList;
 //context
 private Context context;
 private LayoutInflater mLayoutInflater;
 public ItemArticleAdapter(Context context,List<ItemArticle> articleList) {
  this.context = context;
  this.articleList = articleList;
  mLayoutInflater = LayoutInflater.from(context);
 }
 @Override
 public ItemArticleAdapter.ImageItemArticleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  View view = mLayoutInflater.inflate(
    R.layout.item_article_type_1, parent, false);
  return new ImageItemArticleViewHolder(view);
 }
 @Override
 public void onBindViewHolder(ImageItemArticleViewHolder holder, int position) {
  ItemArticle article = articleList.get(position);
  holder.rcvArticlePhoto.setImageURI(Uri.parse(article.getImageUrl()));
  holder.rcvArticleTitle.setText(article.getTitle());
  holder.rcvArticleDate.setText(article.getPublishDate());
  holder.rcvArticleSource.setText(article.getSource());
  //注意这个阅读次数是 int 类型,需要转化为 String 类型
  holder.rcvArticleReadtimes.setText(article.getReadTimes()+"次");
  holder.rcvArticlePreview.setText(article.getPreview());
 }
 @Override
 public int getItemCount() {
  return articleList.size();
 }
 class ImageItemArticleViewHolder 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 ImageItemArticleViewHolder(View itemView) {
   super(itemView);
   ButterKnife.inject(this, itemView);
  }
 }
}

3、新闻实体类 javabean

有新闻的 index,图片 url,标题,发布时间,来源,阅读次数,新闻内容预览



public class ItemArticle {
 private int index;
 private String imageUrl;
 private String title;
 private String publishDate;
 private String source;
 private int readTimes;
 private String preview;
 public ItemArticle(int index, String imageUrl, String title, String publishDate, String source, int readTimes, String preview) {
  this.index = index;
  this.imageUrl = imageUrl;
  this.title = title;
  this.publishDate = publishDate;
  this.source = source;
  this.readTimes = readTimes;
  this.preview = preview;
 }
 public int getIndex() {
  return index;
 }
 public void setIndex(int index) {
  this.index = index;
 }
 public String getImageUrl() {
  return imageUrl;
 }
 public void setImageUrl(String imageUrl) {
  this.imageUrl = imageUrl;
 }
 public String getTitle() {
  return title;
 }
 public void setTitle(String title) {
  this.title = title;
 }
 public String getPublishDate() {
  return publishDate;
 }
 public void setPublishDate(String publishDate) {
  this.publishDate = publishDate;
 }
 public String getSource() {
  return source;
 }
 public void setSource(String source) {
  this.source = source;
 }
 public int getReadTimes() {
  return readTimes;
 }
 public void setReadTimes(int readTimes) {
  this.readTimes = readTimes;
 }
 public String getPreview() {
  return preview;
 }
 public void setPreview(String preview) {
  this.preview = preview;
 }
}

4、fragment 里面使用 RecyclerView

思路就是开启一个异步线程,读取多条新闻,加入List itemArticleList,由这个itemArticleList构造ItemArticleAdapter,最后利用setAdapter()方法给RecyclerView加上适配器。


public class ArticleFragment extends Fragment {
 private static final String STORE_PARAM = "param";
 @InjectView(R.id.rcv_article)
 RecyclerView rcvArticle;
 private String mParam;
 //新闻列表数据
 private List<ItemArticle> itemArticleList = new ArrayList<ItemArticle>();
 //获取 fragment 依赖的 Activity,方便使用 Context
 private Activity mAct;
 public static Fragment newInstance(String param) {
  ArticleFragment fragment = new ArticleFragment();
  Bundle args = new Bundle();
  args.putString(STORE_PARAM, param);
  fragment.setArguments(args);
  return fragment;
 }
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  if (getArguments() != null) {
   mParam = getArguments().getString(STORE_PARAM);
  }
 }
 @Nullable
 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  View view = inflater.inflate(R.layout.fragment_article, null);
  Log.i(STORE_PARAM, "in StoreFragment");
  mAct = getActivity();
  ButterKnife.inject(this, view);
  return view;
 }
 @Override
 public void onActivityCreated(@Nullable Bundle savedInstanceState) {
  super.onActivityCreated(savedInstanceState);
  rcvArticle.setLayoutManager(new LinearLayoutManager(mAct));//这里用线性显示 类似于listview
//  rcvArticle.setLayoutManager(new GridLayoutManager(mAct, 2));//这里用线性宫格显示 类似于grid view
//  rcvArticle.setLayoutManager(new StaggeredGridLayoutManager(2, OrientationHelper.VERTICAL));//这里用线性宫格显示 类似于瀑布流
  new LatestArticleTask().execute();
 }
 @Override
 public void onDestroyView() {
  super.onDestroyView();
  ButterKnife.reset(this);
 }
 class LatestArticleTask extends AsyncTask<String, Void, List<ItemArticle>> {
  @Override
  protected void onPreExecute() {
   super.onPreExecute();
  }
  @Override
  protected List<ItemArticle> doInBackground(String... params) {
   ItemArticle storeInfo1 =
     new ItemArticle(20123, "http://i2.sinaimg.cn/ent/j/2012-05-20/U5912P28T3D3634984F328DT20120520152700.JPG", "关于举办《经典音乐作品欣赏与人文审美》讲座的通知", "2015-01-09", "科学研究院", 1129,
       "讲座主要内容:以中、西方音乐历史中经典音乐作品为基础,通过作曲家及作品创作背景、相关音乐文化史知识及音乐欣赏常识...");
   ItemArticle storeInfo2 =
     new ItemArticle(20123, "http://i2.sinaimg.cn/ent/j/2012-05-20/U5912P28T3D3634984F328DT20120520152700.JPG", "关于举办《经典音乐作品欣赏与人文审美》讲座的通知", "2015-01-09", "科学研究院", 1129,
       "讲座主要内容:以中、西方音乐历史中经典音乐作品为基础,通过作曲家及作品创作背景、相关音乐文化史知识及音乐欣赏常识...");
   ItemArticle storeInfo3 =
     new ItemArticle(20123, "http://i2.sinaimg.cn/ent/j/2012-05-20/U5912P28T3D3634984F328DT20120520152700.JPG", "关于举办《经典音乐作品欣赏与人文审美》讲座的通知", "2015-01-09", "科学研究院", 1129,
       "讲座主要内容:以中、西方音乐历史中经典音乐作品为基础,通过作曲家及作品创作背景、相关音乐文化史知识及音乐欣赏常识...");
   ItemArticle storeInfo4 =
     new ItemArticle(20123, "http://i2.sinaimg.cn/ent/j/2012-05-20/U5912P28T3D3634984F328DT20120520152700.JPG", "关于举办《经典音乐作品欣赏与人文审美》讲座的通知", "2015-01-09", "科学研究院", 1129,
       "讲座主要内容:以中、西方音乐历史中经典音乐作品为基础,通过作曲家及作品创作背景、相关音乐文化史知识及音乐欣赏常识...");
   ItemArticle storeInfo5 =
     new ItemArticle(20123, "http://i2.sinaimg.cn/ent/j/2012-05-20/U5912P28T3D3634984F328DT20120520152700.JPG", "关于举办《经典音乐作品欣赏与人文审美》讲座的通知", "2015-01-09", "科学研究院", 1129,
       "讲座主要内容:以中、西方音乐历史中经典音乐作品为基础,通过作曲家及作品创作背景、相关音乐文化史知识及音乐欣赏常识...");
   ItemArticle storeInfo6 =
     new ItemArticle(20123, "http://i2.sinaimg.cn/ent/j/2012-05-20/U5912P28T3D3634984F328DT20120520152700.JPG", "关于举办《经典音乐作品欣赏与人文审美》讲座的通知", "2015-01-09", "科学研究院", 1129,
       "讲座主要内容:以中、西方音乐历史中经典音乐作品为基础,通过作曲家及作品创作背景、相关音乐文化史知识及音乐欣赏常识...");
   itemArticleList.add(storeInfo1);
   itemArticleList.add(storeInfo2);
   itemArticleList.add(storeInfo3);
   itemArticleList.add(storeInfo4);
   itemArticleList.add(storeInfo5);
   itemArticleList.add(storeInfo6);
   return itemArticleList;
  }
  @Override
  protected void onPostExecute(List<ItemArticle> data) {
   super.onPostExecute(data);
   ItemArticleAdapter adapter = new ItemArticleAdapter(mAct, data);
   rcvArticle.setAdapter(adapter);
  }
 }
}

效果图

利用修改布局,线性显示或者宫格显示。(以前宫格显示很麻烦,现在一条命令就好了,google 搞得这么简单,我们Android 工程师要失业的好伐?!!)


rcvArticle.setLayoutManager(new LinearLayoutManager(mAct));//这里用线性显示 类似于listview
//  rcvArticle.setLayoutManager(new GridLayoutManager(mAct, 2));//这里用线性宫格显示 类似于grid view
//  rcvArticle.setLayoutManager(new StaggeredGridLayoutManager(2, OrientationHelper.VERTICAL));//这里用线性宫格显示 类似于瀑布流

知识点

TextView需要有setText(int resid) 方法,但是这儿 int 表示 resourceId,如果我想把阅读次数(int 1123)赋给这个 TextView,不能使用这个方法。
需要把 int 转化为 String


int 转 String 有三种方法
int i =8;
String s =Integer.toString(i);
String g =String.valueOf(i);
String h =i+"";
holder.rcvArticleReadtimes.setText(String.valueOf(article.getReadTimes())); 

总结 Todo List

Picasso 图片缓存库的学习 实现 RecyclerView 每个项各自的布局

遇到的坑

rcvArticle.setLayoutManager()需要在onActivityCreated()方法里调用,如果在onCreateView()调用会抛出空指针异常。


 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  View view = inflater.inflate(R.layout.fragment_one_latest, container, false);
  mAct = getActivity();
  //错误,需要在onActivityCreated里面调用
  rcvArticle.setLayoutManager(new LinearLayoutManager(mAct));//这里用线性显示 类似于listview
  ButterKnife.inject(this, view);
  return view;
 }

java.lang.NullPointerException
at com.example.administrator.seenews.ui.fragment.common.ArticleFragment.onCreateView(ArticleFragment.java:111)

您可能感兴趣的文章:浅谈RecyclerView(完美替代ListView,GridView)Android中实现淘宝购物车RecyclerView或LIstView的嵌套选择的逻辑Android添加图片到ListView或者RecyclerView显示Android RecyclerView详解之实现 ListView GridView瀑布流效果将替代ListView的RecyclerView 的使用详解(一)Android App开发中使用RecyclerView替代ListView的实践Android仿XListView支持下拉刷新和上划加载更多的自定义RecyclerViewRecyclerView使用详解(代替ListView)


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯