目錄

Android Java - 簡易今日頭條 - RecyclerView 渲染多種不同樣式的新聞卡片

前言

上篇文章中我講述了如何實現Tabs 頻道頁面切換,接下來我們進一步實現 Tab Channel 中的新聞卡片列表渲染

項目倉庫

簡易今日頭條 - Github

Display

具體實現

由於一種的渲染方法比較簡單,通常設計者是卡在顯示多種類型的 RecyclerView Item,在多種卡片 item 的設計這裡我只需要設計一種 DataModel ,然後在 DataModel 中添加 type 成員變量判斷是哪種類型的卡片。

以下我舉出實現的 Example,簡化的部份 Code,這裡的 Code 去掉: HTTP 請求的渲染、Pull To ReFresh、Load More。後面會再一一舉例。

layout/fragment_news_channel.xml

在需要渲染列表的地方加上 RecyclerView 組件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0" encoding="utf-8"?>

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment_news_channel"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".ui.page.newsChannel.NewsChannelFragment">

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:ignore="MissingClass,MissingConstraints">

        <TextView
            android:id="@+id/text_view_section_label"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="gone" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_view_card_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="5dp"
            android:nestedScrollingEnabled="true"
            android:scrollbars="vertical" />
    </LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

layout/no_image_card_item.xmllayout/one_image_card_item.xmlthree_images_card_item.xml

這是我們需要渲染的三種新聞卡片,我這裡就舉出第一種卡片 no_image_card_item,其他的可以自己去設計,不多贅述一一放出來。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<?xml version="1.0" encoding="utf-8"?>

<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    app:cardCornerRadius="10dp"
    app:cardElevation="2dp">

    <TextView
        android:id="@+id/text_view_source_url"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="8dp"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/image_view_card_avatar"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_marginEnd="10dp"
                tools:ignore="MissingConstraints"
                tools:srcCompat="@drawable/avatar_1"
                android:contentDescription="@string/avatar" />

            <TextView
                android:id="@+id/text_view_card_title"
                style="@style/TextAppearance.MaterialComponents.Headline6"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/title_goes_here"
                app:layout_constraintBottom_toTopOf="@+id/avatar"
                app:layout_constraintStart_toEndOf="@+id/avatar"
                app:layout_constraintTop_toBottomOf="@+id/avatar"
                tools:ignore="MissingConstraints" />

        </LinearLayout>

        <TextView
            android:id="@+id/text_view_card_subtitle"
            style="@style/TextAppearance.MaterialComponents.Caption"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="@string/subtitle_goes_here"
            app:layout_constraintStart_toStartOf="@+id/card_title"
            app:layout_constraintTop_toBottomOf="@+id/card_title" />

        <TextView
            android:id="@+id/text_view_card_bottom_text"
            style="@style/TextAppearance.MaterialComponents.Overline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="@string/comment"
            app:layout_constraintStart_toStartOf="@+id/card_subtitle"
            app:layout_constraintTop_toBottomOf="@+id/card_subtitle" />

    </LinearLayout>
</androidx.cardview.widget.CardView>

ui/card/newsCardList/NewsCardItemDataModel.java

我在 ui/card/newsCardList/ 創建了兩個文件:NewsCardItemDataModel.javaNewsCardAdapter.java,分別代表卡片的數據模型和 RecyclerView 適配器。

我這裡寫了三種構造類方法對應三種不同類型的卡片所需數據,並使用 mItemType 判斷卡片類型。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package com.example.toutiao.ui.card.newsCardList;

import java.util.ArrayList;
import java.util.Locale;

/**
 * CardItemDataModel class: the card item data model in New Channel Fragment
 */

public class NewsCardItemDataModel {
    public static final int NO_IMAGE_TYPE = 0;
    public static final int ONE_IMAGE_TYPE = 1;
    public static final int THREE_IMAGE_TYPE = 2;

    private int mItemType; // cart type
    private String mId; //id
    private String mAvatar; // avatar
    private ArrayList<String> mThreeImageDrawable; // three image
    private String mImageDrawable; // one image
    private String mTitle; // title
    private String mSubTitle; // subtitle
    private String mBottomText; // bottom text
    private String mDetailUrl; // detail text to jump

    // no image style constructor
    public NewsCardItemDataModel(int itemType,
                                 String id,
                                 String newsTitle,
                                 String newsAbstract,
                                 int newsCommentsCount,
                                 String newsSource,
                                 String newsMediaAvatarUrl,
                                 String newsSourceUrl
    ) {
        mItemType = itemType;
        mId = id;
        mAvatar = newsMediaAvatarUrl;
        mTitle = String.format(Locale.CHINESE, "%s", newsTitle);
        mSubTitle = String.format(Locale.CHINESE, "%s", newsAbstract);
        mBottomText = String.format(Locale.CHINESE, "%s  %d 评论", newsSource, newsCommentsCount);
        mDetailUrl = newsSourceUrl;
    }

    // one image style constructor
    public NewsCardItemDataModel(int itemType,
                                 String id,
                                 String newsTitle,
                                 String newsAbstract,
                                 int newsCommentsCount,
                                 String newsSource,
                                 String newsMediaAvatarUrl,
                                 String newsSourceUrl,
                                 String imageDrawable
    ) {
        mItemType = itemType;
        mId = id;
        mAvatar = newsMediaAvatarUrl;
        mTitle = String.format(Locale.CHINESE, "%s", newsTitle);
        mSubTitle = String.format(Locale.CHINESE, "%s", newsAbstract);
        mBottomText = String.format(Locale.CHINESE, "%s  %d 评论", newsSource, newsCommentsCount);
        mDetailUrl = newsSourceUrl;
        // one
        mImageDrawable = imageDrawable;
    }

    // three image style constructor
    public NewsCardItemDataModel(int itemType,
                                 String id,
                                 String newsTitle,
                                 String newsAbstract,
                                 int newsCommentsCount,
                                 String newsSource,
                                 String newsMediaAvatarUrl,
                                 String newsSourceUrl,
                                 ArrayList<String> threeImageDrawable
    ) {
        mItemType = itemType;
        mId = id;
        mAvatar = newsMediaAvatarUrl;
        mTitle = String.format(Locale.CHINESE, "%s", newsTitle);
        mSubTitle = String.format(Locale.CHINESE, "%s", newsAbstract);
        mBottomText = String.format(Locale.CHINESE, "%s  %d 评论", newsSource, newsCommentsCount);
        mDetailUrl = newsSourceUrl;
        // three
        mThreeImageDrawable = threeImageDrawable;
    }

    public int getItemType() {
        return mItemType;
    }

    public void setItemType(int itemType) {
        mItemType = itemType;
    }

    public String getId() {
        return mId;
    }

    public void setId(String id) {
        mId = id;
    }

    public String getAvatar() {
        return mAvatar;
    }

    public void setAvatar(String avatar) {
        mAvatar = avatar;
    }

    public String getBottomText() {
        return mBottomText;
    }

    public void setBottomText(String bottomText) {
        mBottomText = bottomText;
    }

    public String getTitle() {
        return mTitle;
    }

    public void setTitle(String title) {
        mTitle = title;
    }

    public String getSubTitle() {
        return mSubTitle;
    }

    public void setSubTitle(String subTitle) {
        mSubTitle = subTitle;
    }

    public ArrayList<String> getThreeImageDrawable() {
        return mThreeImageDrawable;
    }

    public void setThreeImageDrawable(ArrayList<String> threeImageDrawable) {
        mThreeImageDrawable = threeImageDrawable;
    }

    public String getImageDrawable() {
        return mImageDrawable;
    }

    public void setImageDrawable(String imageDrawable) {
        mImageDrawable = imageDrawable;
    }

    public String getDetailUrl() {
        return mDetailUrl;
    }

    public void setDetailUrl(String detailUrl) {
        mDetailUrl = detailUrl;
    }
}

ui/card/newsCardList/NewsCardAdapter.java

這是渲染卡片的 RecyclerView 適配器類,三種卡片類型就會有三種 ViewHolder 子類

onCreateViewHolder 綁定 UI 文件,onBindViewHolder 綁定數據。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
package com.example.toutiao.ui.card.newsCardList;

// ...

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.toutiao.R;
import com.example.toutiao.activity.NewsDetailActivity;
import com.squareup.picasso.Picasso;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

/**
 * A card adapter to help perform to control card item's render in news channel fragment
 */

public class NewsCardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private final List<NewsCardItemDataModel> mDataModelList;
    private final Context mContext;

    public NewsCardAdapter(List<NewsCardItemDataModel> modelList, Context context) {
        mDataModelList = modelList;
        mContext = context;
    }
    @Override
    public int getItemViewType(final int position) {
        switch (mDataModelList.get(position).getItemType()) {
            case NewsCardItemDataModel.NO_IMAGE_TYPE:
                return NewsCardItemDataModel.NO_IMAGE_TYPE;
            case NewsCardItemDataModel.ONE_IMAGE_TYPE:
                return NewsCardItemDataModel.ONE_IMAGE_TYPE;
            case NewsCardItemDataModel.THREE_IMAGE_TYPE:
                return NewsCardItemDataModel.THREE_IMAGE_TYPE;
            default:
                return -1;
        }
    }

    /**
     * load more news and add to mDataModelList
     *
     * @param modelList
     */
    public void setDataModelList(List<NewsCardItemDataModel> modelList) {
        mDataModelList.addAll(modelList);
    }

    @Override
    public int getItemCount() {
        return mDataModelList.size();
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        switch (viewType) {
            case NewsCardItemDataModel.NO_IMAGE_TYPE:
                view = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.no_image_card_item, parent, false);
                return new NoImageCardViewHolder(view);
            case NewsCardItemDataModel.ONE_IMAGE_TYPE:
                view = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.one_image_card_item, parent, false);
                return new OneImageCardViewHolder(view);
            case NewsCardItemDataModel.THREE_IMAGE_TYPE:
                view = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.three_images_card_item, parent, false);
                return new ThreeImageCardViewHolder(view);
            default:
                return null;
        }
    }

    @Override
    public void onBindViewHolder(@NotNull final RecyclerView.ViewHolder holder, final int position) {
        NewsCardItemDataModel object = mDataModelList.get(position);

        if (object != null) {
            switch (object.getItemType()) {
                case NewsCardItemDataModel.NO_IMAGE_TYPE:
                    NoImageCardViewHolder holder1 = (NoImageCardViewHolder) holder;
                    holder1.bindData(object, mContext);
                    break;

                case NewsCardItemDataModel.ONE_IMAGE_TYPE:
                    OneImageCardViewHolder holder2 = (OneImageCardViewHolder) holder;
                    holder2.bindData(object, mContext);
                    break;
                case NewsCardItemDataModel.THREE_IMAGE_TYPE:
                    ThreeImageCardViewHolder holder3 = (ThreeImageCardViewHolder) holder;
                    holder3.bindData(object, mContext);
                    break;
                default:
                    break;
            }
        }
    }

    // No image style card view holder
    class NoImageCardViewHolder extends RecyclerView.ViewHolder {
        private final ImageView mAvatarView;
        private final TextView mTitleTextView;
        private final TextView mSubTitleTextView;
        private final TextView mBottomTextView;
        private final TextView mSourceUrlTextView;

        public NoImageCardViewHolder(@NonNull View itemView) {
            super(itemView);
            mAvatarView = itemView.findViewById(R.id.image_view_card_avatar);
            mTitleTextView = itemView.findViewById(R.id.text_view_card_title);
            mSubTitleTextView = itemView.findViewById(R.id.text_view_card_subtitle);
            mBottomTextView = itemView.findViewById(R.id.text_view_card_bottom_text);
            mSourceUrlTextView = itemView.findViewById(R.id.text_view_source_url);
        }

        public void bindData(NewsCardItemDataModel dataModel, Context context) {
            Picasso.get().load(dataModel.getAvatar()).into(mAvatarView);
            // deal with title's length and subtitle's length
            String title = dataModel.getTitle();
            if (title.length() > 15) {
                title = title.substring(0, 16);
                title += "...";
            }
            mTitleTextView.setText(title);
            String subTitle = dataModel.getSubTitle();
            if (subTitle.length() > 70) {
                subTitle = subTitle.substring(0, 69);
                subTitle += "...";
            }
            mSubTitleTextView.setText(subTitle);
            mBottomTextView.setText(dataModel.getBottomText());
            mSourceUrlTextView.setText(dataModel.getDetailUrl());
        }
    }

    // One image style card view holder
    class OneImageCardViewHolder extends RecyclerView.ViewHolder {
        private final ImageView mAvatarView;
        private final TextView mTitleTextView;
        private final TextView mSubTitleTextView;
        private final TextView mBottomTextView;
        private final TextView mSourceUrlTextView;
        private final ImageView mCardImageView;

        public OneImageCardViewHolder(@NonNull View itemView) {
            super(itemView);
            mAvatarView = itemView.findViewById(R.id.image_view_card_avatar);
            mTitleTextView = itemView.findViewById(R.id.text_view_card_title);
            mSubTitleTextView = itemView.findViewById(R.id.text_view_card_subtitle);
            mBottomTextView = itemView.findViewById(R.id.text_view_card_bottom_text);
            mSourceUrlTextView = itemView.findViewById(R.id.text_view_source_url);
            mCardImageView = itemView.findViewById(R.id.image_view_card_image);
        }

        public void bindData(NewsCardItemDataModel dataModel, Context context) {
            Picasso.get().load(dataModel.getAvatar()).into(mAvatarView);
            Picasso.get().load(dataModel.getImageDrawable()).into(mCardImageView);
            String title = dataModel.getTitle();
            // deal with title's length and subtitle's length
            if (title.length() > 15) {
                title = title.substring(0, 14);
                title += "...";
            }
            mTitleTextView.setText(title);
            String subTitle = dataModel.getSubTitle();
            if (subTitle.length() > 70) {
                subTitle = subTitle.substring(0, 69);
                subTitle += "...";
            }
            mSubTitleTextView.setText(subTitle);
            mBottomTextView.setText(dataModel.getBottomText());
            mSourceUrlTextView.setText(dataModel.getDetailUrl());
        }
    }

    // Three image style card view holder
    class ThreeImageCardViewHolder extends RecyclerView.ViewHolder {
        private final ImageView mAvatarView;
        private final TextView mTitleTextView;
        private final TextView mSubTitleTextView;
        private final TextView mBottomTextView;
        private final TextView mSourceUrlTextView;
        private final ImageView mCardImageView1;
        private final ImageView mCardImageView2;
        private final ImageView mCardImageView3;

        public ThreeImageCardViewHolder(@NonNull View itemView) {
            super(itemView);
            mAvatarView = itemView.findViewById(R.id.image_view_card_avatar);
            mTitleTextView = itemView.findViewById(R.id.text_view_card_title);
            mSubTitleTextView = itemView.findViewById(R.id.text_view_card_subtitle);
            mBottomTextView = itemView.findViewById(R.id.text_view_card_bottom_text);
            mSourceUrlTextView = itemView.findViewById(R.id.text_view_source_url);
            mCardImageView1 = itemView.findViewById(R.id.image_view_image_1);
            mCardImageView2 = itemView.findViewById(R.id.image_view_image_2);
            mCardImageView3 = itemView.findViewById(R.id.image_view_image_3);
        }

        public void bindData(NewsCardItemDataModel dataModel, Context context) {
            Picasso.get().load(dataModel.getAvatar()).into(mAvatarView);
            ArrayList<String> images = dataModel.getThreeImageDrawable();
            Picasso.get().load(images.get(0)).into(mCardImageView1);
            Picasso.get().load(images.get(1)).into(mCardImageView2);
            Picasso.get().load(images.get(2)).into(mCardImageView3);
            // deal with title's length and subtitle's length
            String title = dataModel.getTitle();
            if (title.length() > 15) {
                title = title.substring(0, 16);
                title += "...";
            }
            mTitleTextView.setText(title);
            String subTitle = dataModel.getSubTitle();
            if (subTitle.length() > 70) {
                subTitle = subTitle.substring(0, 69);
                subTitle += "...";
            }
            mSubTitleTextView.setText(subTitle);
            mBottomTextView.setText(dataModel.getBottomText());
            mSourceUrlTextView.setText(dataModel.getDetailUrl());
        }
    }
}

ui/page/newsChannel/newsChannelFragment.java

在需要渲染的 Fragment,添加渲染 Code。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package com.example.toutiao.ui.page.newsChannel;

// ...

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.toutiao.R;
import com.example.toutiao.ui.card.newsCardList.NewsCardAdapter;
import com.example.toutiao.ui.card.newsCardList.NewsCardItemDataModel;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link NewsChannelFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class NewsChannelFragment extends Fragment {
    private String mCategory;
    private int mIndex;
    
    private RecyclerView mCardListRecyclerView;
    private NewsCardAdapter mCardListAdapter;
    private RecyclerView.LayoutManager mCardListLayoutManager;
    private final List<NewsCardItemDataModel> mCardDataModelList = new ArrayList<>();

    public NewsChannelFragment() {
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     */
    public static NewsChannelFragment newInstance(String category, int index) {
        NewsChannelFragment fragment = new NewsChannelFragment();
        Bundle bundle = new Bundle();
        bundle.putString("category", category);
        bundle.putInt("index", index);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // ...
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_news_channel, container, false);
        // ...
        
        for (int i = 0; i < 10; i++) {
            int type = i % 3;
            String newsId = i;
            String newsTitle = "你好";
            String newsAbstract = "我是卡片";
            int newsCommentsCount = 100;
            String newsSource = "https://example.com/e.png";
            String newsMediaAvatarUrl = "https://example.com/e.png";
            String newsSourceUrl = "www.google.com";

            if (type == NO_IMAGE_TYPE) {
                mCardDataModelList.add(new NewsCardItemDataModel(
                        NO_IMAGE_TYPE,
                        newsId,
                        newsTitle,
                        newsAbstract,
                        newsCommentsCount,
                        newsSource,
                        newsMediaAvatarUrl,
                        newsSourceUrl
                ));
            } else if (type == ONE_IMAGE_TYPE) {
                String middleImage = "https://example.com/e.png";
                mCardDataModelList.add(new NewsCardItemDataModel(
                        ONE_IMAGE_TYPE,
                        newsId,
                        newsTitle,
                        newsAbstract,
                        newsCommentsCount,
                        newsSource,
                        newsMediaAvatarUrl,
                        newsSourceUrl,
                        middleImage
                ));

            } else if (type == THREE_IMAGE_TYPE) {
                ArrayList<String> newsThreeImage = new ArrayList()<>;
                newsThreeImage.add("https://example.com/e.png");
                newsThreeImage.add("https://example.com/e.png");
                newsThreeImage.add("https://example.com/e.png");
                mCardDataModelList.add(new NewsCardItemDataModel(
                        THREE_IMAGE_TYPE,
                        newsId,
                        newsTitle,
                        newsAbstract,
                        newsCommentsCount,
                        newsSource,
                        newsMediaAvatarUrl,
                        newsSourceUrl,
                        newsThreeImage
                ));
            }
        }
        // cardList
        mCardListRecyclerView = view.findViewById(R.id.recycler_view_card_list);

        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        mCardListRecyclerView.setHasFixedSize(true);

        // use a linear layout manager
        mCardListLayoutManager = new LinearLayoutManager(getContext());
        mCardListRecyclerView.setLayoutManager(mCardListLayoutManager);

        // specify an adapter and pass in our data model list
        mCardListAdapter = new NewsCardAdapter(mCardDataModelList, getContext());
        mCardListRecyclerView.setAdapter(mCardListAdapter);
        return view;
    }
}

Reference