如何以编程方式将 CardView 添加到回收器视图中的 LinearLayout



是否可以以编程方式将CardView添加到RecyclerView内的LinearLayout。目前,所有CardView都被添加到RecyclerView,但我希望将屏幕截图中的那些添加到LinearLayout中。

片段类

public class TabFragmentRV extends android.support.v4.app.Fragment {
RecyclerView mRecyclerView;
public TabFragmentRV() {}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_rv, container, false);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
View v = getView();
assert v != null;
mRecyclerView = v.findViewById(R.id.my_recyclerview);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
super.onActivityCreated(savedInstanceState);
initRVAdapter();
}
private void initRVAdapter(){
List<Object> itemsList = new ArrayList<>();
RVItemsAapter itemsListAdapter = new RVItemsAapter(getContext());
mRecyclerView.setAdapter(itemsListAdapter);
itemsList.add(new RVLineSeparator());
itemsList.add(new SectionHeader("Section E"));
itemsList.add(new SMSmessage("Item E1","Item E1 description"));
itemsList.add(new SMSmessage("Item E2","Item E2 description"));
itemsList.add(new SMSmessage("Item E3","Item E3 description"));
itemsList.add(new SMSmessage("Item E4","Item E4 description"));
itemsList.add(new RVLineSeparator());
itemsListAdapter.setCallSMSFeed(itemsList);
itemsListAdapter.notifyDataSetChanged();
}
}

适配器类

public class RVItemsAapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final static int TYPE_MAINHEADER = 1, TYPE_EXPANDABLE = 2, TYPE_NONEXPANDABLE = 3, TYPE_SECTIONHEADER = 4, TYPE_TABLE = 5, TYPE_SEPARATOR = 6;
private ArrayList callSMSFeed = new ArrayList();
private Context context;

public RVItemsAapter(Context context){this.context=context;}
public void setCallSMSFeed(List<Object> callSMSFeed){
this.callSMSFeed = (ArrayList) callSMSFeed;
}
@Override
public int getItemViewType(int position) {
if (callSMSFeed.get(position) instanceof MainHeader) {
return TYPE_MAINHEADER;
} else if (callSMSFeed.get(position) instanceof Phonecall) {
return TYPE_EXPANDABLE;
} else if (callSMSFeed.get(position) instanceof SMSmessage) {
return TYPE_NONEXPANDABLE;
} else if (callSMSFeed.get(position) instanceof SectionHeader) {
return TYPE_SECTIONHEADER;
} else if (callSMSFeed.get(position) instanceof MyTable) {
return TYPE_TABLE;
} else if (callSMSFeed.get(position) instanceof RVLineSeparator) {
return TYPE_SEPARATOR;
}
throw new IllegalArgumentException("Item at position " + position + " is not an instance of either Phonecall or SMSmessage");
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
int viewType=holder.getItemViewType();
switch (viewType){
case TYPE_MAINHEADER:
MainHeader mainHeader = (MainHeader) callSMSFeed.get(position);
((MHeaderViewHolder)holder).showMHeaderDetails(mainHeader);
break;
case TYPE_EXPANDABLE:
Phonecall call = (Phonecall) callSMSFeed.get(position);
((CallViewHolder)holder).showCallDetails(call);
break;
case TYPE_NONEXPANDABLE:
SMSmessage sms = (SMSmessage) callSMSFeed.get(position);
((SMSViewHolder)holder).showSmsDetails(sms);
break;
case TYPE_SECTIONHEADER:
SectionHeader sectionHeader = (SectionHeader) callSMSFeed.get(position);
((SectionViewHolder)holder).showSectionDetails(sectionHeader);
break;
case TYPE_TABLE:
TableToilets tblToilets = (TableToilets) callSMSFeed.get(position);
((TblViewHolder)holder).showTblDetails(tblToilets);
break;
case TYPE_SEPARATOR:
((SeparatorViewHolder)holder).showSeparatorDetails();
break;
default:
throw new IllegalArgumentException("unexpected viewType: " + viewType);
}
}
@Override
public int getItemCount(){return callSMSFeed.size();}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

int layout;
RecyclerView.ViewHolder viewHolder;
switch (viewType){
case TYPE_MAINHEADER:
layout = R.layout.rv_header;
View mainheaderView = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
viewHolder = new MHeaderViewHolder(mainheaderView);
break;
case TYPE_EXPANDABLE:
layout = R.layout.cardview_dualline_withexpandability;
View callsView = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
viewHolder = new CallViewHolder(callsView);
break;
case TYPE_NONEXPANDABLE:
layout = R.layout.cardview_dualline_sansexpandability;
View smsView = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
viewHolder = new SMSViewHolder(smsView);
break;
case TYPE_SECTIONHEADER:
layout = R.layout.sectionheaderforrecyclerview;
View sectionheaderView = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
viewHolder = new SectionViewHolder(sectionheaderView);
break;
case TYPE_TABLE:
layout = R.layout.cardview_tableview_withexpandability;
View tblView = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
viewHolder = new TblViewHolder(tblView);
break;
case TYPE_SEPARATOR:
layout = R.layout.lineseparatorforrecyclerview;
View separatorView = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
viewHolder = new SeparatorViewHolder(separatorView);
break;
default:
throw new IllegalArgumentException("unexpected viewType: " + viewType);
}
return viewHolder;
}
// First ViewHolder of object type Call
// Reference to the views for each call items to display desired information
public class CallViewHolder extends RecyclerView.ViewHolder {
final Typeface iconFont = FontManager.getTypeface(context, FontManager.FONTAWESOME);
private TextView arrowexpandcollapseTextView, callerNameTextView, callTimeTextView;
private LinearLayout llFacilityInformation;
CallViewHolder(View itemView) {
super(itemView);
// Initiate view
arrowexpandcollapseTextView = itemView.findViewById(R.id.tv_cvwithexpandability_arrowexpandcollapse);
callerNameTextView = itemView.findViewById(R.id.tv_cvwithexpandability_title);
callTimeTextView = itemView.findViewById(R.id.tv_cvwithexpandability_subtitle);
llFacilityInformation = itemView.findViewById(R.id.ll_cvwithexpandability_subtitle);
arrowexpandcollapseTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (llFacilityInformation.getVisibility() == View.GONE) {
expandLL(llFacilityInformation, arrowexpandcollapseTextView);
} else {
collapseLL(llFacilityInformation, arrowexpandcollapseTextView);
}
}
});
callerNameTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (llFacilityInformation.getVisibility() == View.GONE) {
expandLL(llFacilityInformation, arrowexpandcollapseTextView);
} else {
collapseLL(llFacilityInformation, arrowexpandcollapseTextView);
}
}
});
llFacilityInformation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (llFacilityInformation.getVisibility() == View.GONE) {
expandLL(llFacilityInformation, arrowexpandcollapseTextView);
} else {
collapseLL(llFacilityInformation, arrowexpandcollapseTextView);
}
}
});
}
void showCallDetails(Phonecall call){
// Attach values for each item
arrowexpandcollapseTextView.setText(R.string.fa_icon_chevron_down);
arrowexpandcollapseTextView.setTypeface(iconFont);
llFacilityInformation.setVisibility(View.GONE);
String callerName = call.getCallerName();
String callTime = call.getCallTime();
callerNameTextView.setText(callerName);
callTimeTextView.setText(callTime);
}
}
// Third ViewHolder of object type SectionHeader
// Reference to the views for each call items to display desired information
public class SectionViewHolder extends RecyclerView.ViewHolder {
final Typeface iconFont = FontManager.getTypeface(context, FontManager.FONTAWESOME);
private LinearLayout llSectionWithCards;
private TextView arrowexpandcollapseTextView, sectionNameTextView;
SectionViewHolder(View itemView) {
super(itemView);
// Initiate view
arrowexpandcollapseTextView = itemView.findViewById(R.id.tv_sectionheaderforrv_expandcollapsearrow);
sectionNameTextView = itemView.findViewById(R.id.tv_sectionheaderforrv_title);
arrowexpandcollapseTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (llSectionWithCards.getVisibility() == View.GONE) {
expandLL(llSectionWithCards, arrowexpandcollapseTextView);
} else {
collapseLL(llSectionWithCards, arrowexpandcollapseTextView);
}
}
});
}
void showSectionDetails(SectionHeader section){
// Attach values for each item
arrowexpandcollapseTextView.setText(R.string.fa_icon_chevron_down);
arrowexpandcollapseTextView.setTypeface(iconFont);
String sectionName = section.getSectionName();
sectionNameTextView.setText(sectionName);
}
}

// Fifth ViewHolder of object type RVLineSeparator
// Reference to the views for each call items to display desired information
public class SeparatorViewHolder extends RecyclerView.ViewHolder {
private View lSeparator;
SeparatorViewHolder(View itemView) {
super(itemView);
lSeparator = itemView.findViewById(R.id.rv_lineseparator);
}
void showSeparatorDetails(){
TypedValue tValueD = new TypedValue();
context.getTheme().resolveAttribute(R.attr.dividerColor, tValueD, true);
lSeparator.setBackgroundResource(tValueD.resourceId);
}
}
private void expandGroup(final TextView arrowexpandcollapseTextView) {
?
}
private void collapseGroup(final TextView arrowexpandcollapseTextView) {
?
}
private void expandLL(final LinearLayout llFacilityInformation, final TextView arrowexpandcollapseTextView) {
llFacilityInformation.setVisibility(View.VISIBLE);
arrowexpandcollapseTextView.setText(R.string.fa_icon_chevron_up);
}
private void collapseLL(final LinearLayout llFacilityInformation, final TextView arrowexpandcollapseTextView) {
llFacilityInformation.setVisibility(View.GONE);
arrowexpandcollapseTextView.setText(R.string.fa_icon_chevron_down);
}
}

节标题布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_sectionwithexpandability_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_sectionheader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:weightSum="100">
<TextView
android:id="@+id/tv_sectionheader_expandcollapsearrow"
android:clickable="true"
android:focusable="true"
android:layout_weight="10"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:textColor="?android:attr/textColorPrimary"
style="@android:style/TextAppearance.Large" />
<TextView
android:id="@+id/tv_sectionheader_title"
android:layout_weight="90"
android:layout_width="0dp"
android:layout_height="wrap_content"
style="@android:style/TextAppearance.Large" />
</LinearLayout>
<!-- I WANT ALL THE CARD VIEWS TO BE ADDED INSIDE THIS LINEARLAYOUT (ll_section_cards) -->
<LinearLayout
android:id="@+id/ll_section_cards"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

回收器视图布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linearLayout_recyclerView"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/my_recyclerview"
android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</LinearLayout>

短信类

public class SMSmessage {
private String senderName, smsContent;
public SMSmessage(String senderName, String smsContent) {
this.senderName = senderName;
this.smsContent = smsContent;
}
public String getSenderName() {
return senderName;
}
public String getSmsContent() {
return smsContent;
}
}
  • 首先使用一个线性布局的父布局,然后在创建包含任何布局(如线性或相对布局(的子布局中,然后创建第二个模块的子布局,在子布局中,您将使用卡片视图和其他组件,如文本视图或编辑卡片视图中的文本

否则约束布局最好开发此布局

例如

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_sectionwithexpandability_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_sectionheader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:weightSum="100">
<TextView
android:id="@+id/tv_sectionheader_expandcollapsearrow"
android:clickable="true"
android:focusable="true"
android:layout_weight="10"
android:text="Testing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:textColor="?android:attr/textColorPrimary"
style="@android:style/TextAppearance.Large" />
<TextView
android:id="@+id/tv_sectionheader_title"
android:layout_weight="90"
android:layout_width="0dp"
android:text="testing"
android:layout_height="wrap_content"
style="@android:style/TextAppearance.Large" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
<!-- I WANT ALL THE CARD VIEWS TO BE ADDED INSIDE THIS LINEARLAYOUT (ll_section_cards) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/ll_section_cards"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/te"
android:layout_weight="90"
android:layout_width="wrap_content"
android:text="testing"
android:layout_height="wrap_content"
style="@android:style/TextAppearance.Large" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</LinearLayout>

编辑:您的问题属于XY问题:在此处输入链接描述

您的整个架构/模式似乎不适合。

您可以调整代码,因此在"OnBind"方法中,您可以检查下一个 n+1 对象是否是 SMSMessage 并将批次添加到线性布局中......并且以某种方式有记录表明他们已经被"绑定"以避免双重绑定......但是,您还需要检测该视图持有人何时未绑定...这一切似乎都在与框架希望你做事的方式作斗争。

我建议让API(或"本地服务"(将API数据(最好使用像JacksonMapper这样的ObjectMapper(转换为

看起来像:
import java.util.List;
public class SMSMessageCollection {
private List<SMSMessage> smsMessages;
private String headerText;
private boolean hasStartingRVLine;
private boolean hasEndingRVLine;
public SMSMessageCollection(String headerText, boolean hasStartingRVLine, boolean hasEndingRVLine) {
this.headerText = headerText;
this.hasStartingRVLine = hasStartingRVLine;
this.hasEndingRVLine = hasEndingRVLine;
}
//CUSTOM "ADDER":
public void addSMSMessagesToCollection(List<SMSMessage> smsMessagesToAdd){
this.smsMessages.addAll(smsMessagesToAdd);
}
//GETTER AND SETTER HERE -> OR USE LOMBOK...
}

此类包含一个List<SMSMessages>因此,当对象绑定到回收器适配器中时,可以循环访问列表并将它们添加到线性布局中。

所以这是我的活动的样子...获取 API 数据并制作 SMSMessageCollection(s( 的列表,然后可以使用一个 ViewHolder 将其传递给适配器...

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.json.JSONArray;
import java.io.IOException;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//This would be fetched using say Volley...and the structure should MATCH the class we have made...
//Otherwise...make a "service class" to convert the API response to the SMSMessageCollection
JSONArray apiDataModels = new JSONArray();
// Jackson ObjectMapper will turn the API data in to a List or POJOs...in like two lines.
try {
List<SMSMessageCollection> smsMessageCollections = new ObjectMapper()
.readValue(apiDataModels.toString(),new TypeReference<List<SMSMessageCollection>>(){});
} catch (IOException e) {
e.printStackTrace();
}
}
}

因此,在adpater的OnBindViewHolder方法中,您可以获取该部分的列表,并以编程方式将它们添加到正在注入的ViewHolder的LienarLayout中。

最新更新