如何在另一个recyclerView中添加recyclerView

Moh*_*emi 47 java android android-cardview android-recyclerview

我打算开发一个应用程序,在其中显示一些动态数据recyclerCardView.所以我决定 在我的主要内部添加一个recyclerView名字.这是我的应用程序的代码:CheckBoxRecyclerViewrecyclerView

我的主要活动:

setContentView(R.layout.activity_startup);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
reminderView = (RecyclerView) findViewById(R.id.reminder_recycler_view);
RlayoutManager = new LinearLayoutManager(this);
reminderView.setLayoutManager(RlayoutManager);

setSupportActionBar(toolbar);
cardView = (CardView) findViewById(R.id.card_first);
cardView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(getApplicationContext() , ReminderActivity.class);
        startActivity(intent);
    }
});
ReminderHelper helper = new ReminderHelper(getApplicationContext());
ReminderAdapter reminderAdapter = new ReminderAdapter(helper);
ContentValues reminderValues = new ContentValues();
ContentValues checkboxValues = new ContentValues();
// Devlopment Part ->
reminderValues.put("reminderTitle" , "A Reminder Title");
reminderValues.put("reminderLastModDate" , 0);
reminderValues.put("reminderAlarm" , 0);
reminderValues.put("reminderPicURI" , "skjshksjh");
reminderValues.put("ReminderBackground" , "#00796b");
checkboxValues.put("checkboxText" , "This is a CheckBox");
checkboxValues.put("isDone" , false);
checkboxValues.put("checkboxReminderID" , 0);
reminderAdapter.INSERT_REMINDER(reminderValues);
reminderAdapter.INSERT_CHECKBOX(checkboxValues);
File dbPath = getApplicationContext().getDatabasePath(ReminderHelper.DATABASE_NAME);
if(dbPath.exists()){
    List<Reminder> reminders = new ReminderAdapter(helper).getAllReminders();
    List<CheckBoxItem> checkBoxItems = new ReminderAdapter(helper).getAllCheckBoxes();
    RAdapter = new RAdapter(reminders , getApplicationContext() , checkBoxItems);
    reminderView.setAdapter(RAdapter);
}else{

}
Run Code Online (Sandbox Code Playgroud)

它的布局文件:

<LinearLayout 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="match_parent"
    android:orientation="vertical"
    android:paddingBottom="8dp"
    android:paddingLeft="8dp"
    android:paddingRight="8dp"
    android:paddingTop="8dp"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.smflog.sreminder.StartupActivity"
    tools:showIn="@layout/app_bar_startup">

    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:id="@+id/reminder_recycler_view"
        android:scrollbars="vertical"
        android:layout_height="match_parent">
Run Code Online (Sandbox Code Playgroud)

在这个rec​​yclerView里面还有另一个:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/reminder_card"
    card_view:cardCornerRadius="2dp"
    card_view:cardElevation="4dp"
    card_view:cardUseCompatPadding="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="16dp"
        android:paddingLeft="8dp">

        <com.smflog.sreminder.utils.TitleView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/reminder_title"
            android:paddingTop="8dp"
            android:text="Wellcome To Google Keep !"
            android:textSize="15dp"
            android:textStyle="bold" />
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:orientation="horizontal">
<android.support.v7.widget.RecyclerView
    android:layout_width="wrap_content"
    android:id="@+id/checkbox_recycler_view"
    android:layout_height="wrap_content">

</android.support.v7.widget.RecyclerView>
        </LinearLayout>

    </LinearLayout>
</android.support.v7.widget.CardView>
Run Code Online (Sandbox Code Playgroud)

他们的适配器,Main(RAdapter):

public class RAdapter extends RecyclerView.Adapter<RAdapter.ViewHolder> {
    List<Reminder> reminder;
    private Context context;
    private LinearLayoutManager lln;
    private CAdapter checkBoxAdapter;
    private List<CheckBoxItem> checkBoxItems;
    public static class ViewHolder extends RecyclerView.ViewHolder {
        public CardView rCardView;
        public RecyclerView recyclerView;
        public TitleView rTitleView;
        public ViewHolder(View itemView) {
            super(itemView);
            rCardView = (CardView) itemView.findViewById(R.id.reminder_card);
            rTitleView = (TitleView) itemView.findViewById(R.id.reminder_title);
            recyclerView = (RecyclerView) itemView.findViewById(R.id.checkbox_recycler_view);
        }
    }

    public RAdapter(List<Reminder> reminder, Context context, List<CheckBoxItem> checkBoxItems) {
        this.reminder = reminder;
        this.context = context;
        this.checkBoxItems = checkBoxItems;
    }

    @Override
    public RAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.reminder_card, parent, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(RAdapter.ViewHolder holder, int position) {
        lln = new LinearLayoutManager(context);
        holder.recyclerView.setLayoutManager(lln);
        checkBoxAdapter = new CAdapter(checkBoxItems, context);
        holder.recyclerView.setAdapter(checkBoxAdapter);
        holder.rCardView.setCardBackgroundColor(Color.parseColor("#00796b"));
        holder.rTitleView.setText(reminder.get(position).getReminderTitle());
    }

    @Override
    public int getItemCount() {
        return reminder.size();
    }
}
Run Code Online (Sandbox Code Playgroud)

和第二个适配器:

public class CAdapter extends RecyclerView.Adapter<CAdapter.ViewHolder> {
    List<CheckBoxItem> checkBoxItems;
    Context context;

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TitleView checkBoxTitle;
        public ImageView deleteCheckBox;
        public CheckBox checkBoxCheckBox;

        public ViewHolder(View itemView) {
            super(itemView);
            checkBoxTitle = (TitleView) itemView.findViewById(R.id.checkbox_item_text);
            checkBoxCheckBox = (CheckBox) itemView.findViewById(R.id.checkbox_item_checkbox);
            Log.d("CAdapterLog", "Adpater Holded !!!!! :( ");
            deleteCheckBox = (ImageView) itemView.findViewById(R.id.btn_delete_checkbox);
        }
    }

    public CAdapter(List<CheckBoxItem> checkBoxItems, Context context) {
        this.checkBoxItems = checkBoxItems;
        this.context = context;
        Log.d("CAdapterLog", "Adpater Created !!!!! :( ");
    }


    @Override
    public CAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.checkbox_item, parent, false);
        ViewHolder vh = new ViewHolder(v);
        Log.d("CAdapterLog", "Adpater ViewHolded :( !!!!! :( ");
        return vh;
    }

    @Override
    public void onBindViewHolder(CAdapter.ViewHolder holder, int position) {
        Boolean isCheckboxChecked = Boolean.parseBoolean(checkBoxItems.get(position).getCheckBoxIsDone());
        String checkBoxText = checkBoxItems.get(position).getCheckBoxBody();
        Log.d("CAdapterLog", "Adpater Binded :( ");
        final int checkboxID = Integer.parseInt(checkBoxItems.get(position).getCheckBoxID());
        int reminderCheckBoxID = Integer.parseInt(checkBoxItems.get(position).getCheckBoxReminderID());
        holder.deleteCheckBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("CAdapterLog", "Cross Button Clicked !");
            }
        });
        holder.checkBoxCheckBox.setChecked(isCheckboxChecked);
        holder.checkBoxTitle.setText(checkBoxText);
    }

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

}
Run Code Online (Sandbox Code Playgroud)

我的问题:正如您在CAdapter中看到的那样,只显示了构造函数的Log消息.

更新:如果有另一种方式在另一个动态卡内显示一些动态数据,如果是,最好使用它而不是recyclerView吗?
有人帮我吗?
输出:应用程序输出 ,只看到RTPapter的setTitle有效.

Rea*_*hed 39

我建议使用单个RecyclerView动态填充列表项.我添加了一个github项目来描述如何做到这一点.你可以看看.虽然其他解决方案可以正常工作,但我想建议,这是一种更快更有效的方式来显示多个列表RecyclerView.

我们的想法是在你的方法onCreateViewHolderonBindViewHolder方法中添加逻辑,这样你就可以为你的确切位置充气RecyclerView.

我已经添加了一个示例项目以及该wiki.您可以克隆并检查它的作用.

还有另一种方法可以将项目保存在单个ArrayList对象中,以便您可以设置标记项目的属性,以指示哪个项目来自第一个列表,哪个项目属于第二个列表.然后将其传递ArrayList给您RecyclerView,然后在适配器中实现逻辑以动态填充它们.

希望有所帮助.

  • "在另一个内部添加RecyclerView并不常见" - >包含水平滚动图像的垂直滚动列表怎么样?如果两个列表都非常大,你会怎么做?看起来像嵌套的recyclerview在这里非常有用. (35认同)
  • 即使谷歌使用嵌套的recyclerViews,这个答案是无关的,误导性的,并没有提供任何适当的解决方案 (4认同)
  • 问题不在于是否常见。当它是一个要求时,它需要完成。而且 stackoverflow 不仅仅针对常见问题。 (3认同)
  • @AbdulAli,是的,你是对的.那段时间对我来说并不常见.但是,后来我看到有很多实现.感谢您的意见.:) (3认同)
  • @EgeKuzubasioglu 你怎么知道 Google 使用 Nested RecyclerViews? (3认同)
  • 而且我没有看到这是如何回答任意嵌套项目列表的.该链接仅提供固定3个外部组的硬编码 (2认同)

Kha*_*hay 21

我一段时间遇到了类似的问题,在我的情况下发生的事情是外部回收器视图工作得非常好,但内部/第二个回收器视图的适配器有小问题所有方法,如构造函数已启动甚至getCount()方法被调用,虽然负责生成视图的最终方法即...

1. onBindViewHolder()方法永远不会被调用. - >问题1.

2.当它最终被调用时,它永远不会显示回收器视图的列表项/行. - >问题2.

发生这种情况的原因 ::当您将回收站视图放在另一个回收站视图中时,第一个/外部回收站视图的高度不会自动调整.它是在创建第一个/外部视图时定义的,然后保持固定.此时,您的第二个/内部回收站视图尚未加载其项目,因此其高度设置为零,即使获取数据也不会更改.然后,当onBindViewHolder()在你的第二/内回收视图调用时,它得到的物品,但它不具备的空间去展示它们,因为它的高度仍然是零.因此,即使onBindViewHolder()已将它们添加到第二个回收器视图中的项目也不会显示.

解决方案 ::您必须为第二个回收站视图创建自定义LinearLayoutManager,就是这样.要创建自己的LinearLayoutManager: 使用名称创建一个Java类,CustomLinearLayoutManager并将下面的代码粘贴到其中.无需更改

public class CustomLinearLayoutManager extends LinearLayoutManager {

    private static final String TAG = CustomLinearLayoutManager.class.getSimpleName();

    public CustomLinearLayoutManager(Context context) {
        super(context);

    }

    public CustomLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    private int[] mMeasuredDimension = new int[2];

    @Override
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {

        final int widthMode = View.MeasureSpec.getMode(widthSpec);
        final int heightMode = View.MeasureSpec.getMode(heightSpec);
        final int widthSize = View.MeasureSpec.getSize(widthSpec);
        final int heightSize = View.MeasureSpec.getSize(heightSpec);

        int width = 0;
        int height = 0;
        for (int i = 0; i < getItemCount(); i++) {
            measureScrapChild(recycler, i, View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    mMeasuredDimension);


            if (getOrientation() == HORIZONTAL) {
                width = width + mMeasuredDimension[0];
                if (i == 0) {
                    height = mMeasuredDimension[1];
                }
            } else {
                height = height + mMeasuredDimension[1];
                if (i == 0) {
                    width = mMeasuredDimension[0];
                }
            }
        }
        switch (widthMode) {
            case View.MeasureSpec.EXACTLY:
                width = widthSize;
            case View.MeasureSpec.AT_MOST:
            case View.MeasureSpec.UNSPECIFIED:
        }

        switch (heightMode) {
            case View.MeasureSpec.EXACTLY:
                height = heightSize;
            case View.MeasureSpec.AT_MOST:
            case View.MeasureSpec.UNSPECIFIED:
        }

        setMeasuredDimension(width, height);
    }

    private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
                                   int heightSpec, int[] measuredDimension) {
        try {
            View view = recycler.getViewForPosition(position);

            if (view != null) {
                RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();

                int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
                        getPaddingLeft() + getPaddingRight(), p.width);

                int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
                        getPaddingTop() + getPaddingBottom(), p.height);

                view.measure(childWidthSpec, childHeightSpec);
                measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
                measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
                recycler.recycleView(view);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 第二个怎么样是gridlayout? (7认同)

小智 8

您可以使用LayoutInflater将动态数据充当布局文件.

更新:首先在CardView的布局中创建一个LinearLayout并为其分配一个ID.之后创建一个要膨胀的布局文件.最后在你onBindViewHolder的"RAdaper"类的方法中.写下这些代码:

  mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

  view = mInflater.inflate(R.layout.my_list_custom_row, parent, false);
Run Code Online (Sandbox Code Playgroud)

之后,您可以使用RAdapter数据初始化数据和ClickListeners.希望能帮助到你.

这个可能有用:)

  • 从答案中的链接中得到重要点的简短摘要会很棒.如果链接不再有效,其他用户将有机会看到答案. (3认同)