如何在已重复的View中再次重复View?安卓ListView嵌套实现求助
Hey there! Let's tackle this nested list display issue you're facing with your Android app and the SwipeLayout library. The core idea is to embed a sub-list container within each ListView item, then bind your ArrayList<SubItem> data to it. Here's a step-by-step, practical solution:
First, create the layout for your main ListView item (including the SwipeLayout and a container for sub-items). We'll use RecyclerView for sub-items (it's more efficient than nesting ListView and avoids height calculation issues):
<!-- item_main.xml: Main ListView item layout with SwipeLayout --> <com.daimajia.swipe.SwipeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <!-- Right swipe menu (customize as needed) --> <LinearLayout android:id="@+id/right_swipe_menu" android:layout_width="wrap_content" android:layout_height="match_parent" android:background="#E53935" android:orientation="horizontal"> <Button android:layout_width="80dp" android:layout_height="match_parent" android:text="Delete" android:textColor="#FFFFFF"/> </LinearLayout> <!-- Main content area --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!-- Main item info --> <TextView android:id="@+id/tv_main_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:textSize="18sp" android:textStyle="bold"/> <!-- Container for SubItems (RecyclerView) --> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv_sub_items" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingStart="24dp"/> </LinearLayout> </com.daimajia.swipe.SwipeLayout>
Then create a simple layout for individual SubItems:
<!-- item_sub.xml: SubItem layout --> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tv_sub_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:textSize="14sp" android:textColor="#424242"/>
Create a dedicated RecyclerView.Adapter to bind your SubItem data:
public class SubItemAdapter extends RecyclerView.Adapter<SubItemAdapter.SubViewHolder> { private List<SubItem> mSubItemList; public SubItemAdapter(List<SubItem> subItemList) { mSubItemList = subItemList; } @NonNull @Override public SubViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_sub, parent, false); return new SubViewHolder(view); } @Override public void onBindViewHolder(@NonNull SubViewHolder holder, int position) { SubItem currentSubItem = mSubItemList.get(position); holder.tvSubContent.setText(currentSubItem.getContent()); // Replace with your SubItem's data getter } @Override public int getItemCount() { return mSubItemList.size(); } static class SubViewHolder extends RecyclerView.ViewHolder { TextView tvSubContent; public SubViewHolder(@NonNull View itemView) { super(itemView); tvSubContent = itemView.findViewById(R.id.tv_sub_content); } } }
Modify your main ListView's BaseAdapter to initialize the sub-recyclerView and bind SubItem data for each main item:
public class MainItemAdapter extends BaseAdapter { private Context mContext; private List<Item> mItemList; public MainItemAdapter(Context context, List<Item> itemList) { mContext = context; mItemList = itemList; } @Override public int getCount() { return mItemList.size(); } @Override public Object getItem(int position) { return mItemList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = LayoutInflater.from(mContext) .inflate(R.layout.item_main, parent, false); holder = new ViewHolder(); holder.tvMainTitle = convertView.findViewById(R.id.tv_main_title); holder.rvSubItems = convertView.findViewById(R.id.rv_sub_items); // Configure sub-recyclerView layout manager holder.rvSubItems.setLayoutManager(new LinearLayoutManager(mContext)); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } // Bind main item data Item currentItem = mItemList.get(position); holder.tvMainTitle.setText(currentItem.getTitle()); // Replace with your Item's data getter // Bind sub-item data via SubItemAdapter SubItemAdapter subAdapter = new SubItemAdapter(currentItem.getSubItems()); holder.rvSubItems.setAdapter(subAdapter); // Configure SwipeLayout (adjust mode as needed) SwipeLayout swipeLayout = (SwipeLayout) convertView; swipeLayout.setShowMode(SwipeLayout.ShowMode.LayDown); // Add swipe listeners if required return convertView; } static class ViewHolder { TextView tvMainTitle; RecyclerView rvSubItems; } }
- Avoid nesting ListView: ListView doesn't handle dynamic height well for nested scenarios, which leads to truncated sub-items. RecyclerView is the better choice here.
- Swipe conflict handling: If you encounter swipe conflicts between SwipeLayout and the sub-recyclerView, you can override the sub-recyclerView's
onTouchEventto intercept gestures when needed. - Performance: For large datasets, consider adding view recycling optimizations (like stable IDs for adapters) and using
DiffUtilfor sub-item updates.
内容的提问来源于stack exchange,提问作者NameTopSecret

