嵌套的 RecyclerViews

huangapple 未分类评论47阅读模式
英文:

Nested RecyclerViews

问题

我正在创建一个日历应用程序,每个月都使用RecyclerView显示。在每个月的每一天里,有另一个RecyclerView来显示当天的事件。我正在使用来自https://stackoverflow.com/a/38513905/13199395的custuomLinearLayoutManager,并且我已经查看了许多示例。我的嵌套代码与它们非常相似,但由于某种原因不起作用。非常感谢对于为什么不起作用的任何帮助。

月视图:

<FrameLayout 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"
    tools:context=".MonthViewActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/calView"
        android:layout_width="match_parent"
        android:layout_height="581dp"
        android:layout_gravity="bottom" />
</FrameLayout>

每天的视图:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dayView"
    android:layout_width="145px"
    android:layout_height="265px"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/eventDayView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    </androidx.recyclerview.widget.RecyclerView>
</LinearLayout>

内部RecyclerView的视图:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/showEvents"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/eventName"
        android:layout_width="145px"
        android:layout_height="wrap_content" />
</LinearLayout>

主RecyclerView的适配器:

public class MonthViewAdapter extends RecyclerView.Adapter<MonthViewAdapter.ViewHolder>  {
    // ... 你的适配器代码 ...
}

内部RecyclerView的适配器:

public class EventViewAdapter extends RecyclerView.Adapter<EventViewAdapter.ViewHolder> {
    // ... 你的适配器代码 ...
}

自定义线性布局管理器:链接已省略

活动:

public class MonthViewActivity extends AppCompatActivity {
    // ... 你的活动代码 ...
}

我只翻译了您提供的代码部分,如有需要,您可以根据需要进行调整。如果您有任何进一步的问题,请随时提问。

英文:

I'm creating a calendar app, with each month being displayed using a RecylcerView. Inside each day of each month, there is another RecyclerView to display events on that day. I'm using the custuomLinearLayoutManager from https://stackoverflow.com/a/38513905/13199395, and I've looked at many examples. My code for the nesting is very similar to them but for some reason is not working. Any help as to why is not working would be much appreciated.

The month view:

&lt;FrameLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:orientation=&quot;vertical&quot;
    tools:context=&quot;.MonthViewActivity&quot;&gt;

    &lt;androidx.recyclerview.widget.RecyclerView
        android:id=&quot;@+id/calView&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;581dp&quot;

        android:layout_gravity=&quot;bottom&quot; /&gt;
&lt;/FrameLayout&gt;

The view for each day:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:id=&quot;@+id/dayView&quot;
    android:layout_width=&quot;145px&quot;
    android:layout_height=&quot;265px&quot;
    android:orientation=&quot;vertical&quot;&gt;

    &lt;androidx.recyclerview.widget.RecyclerView
        android:id=&quot;@+id/eventDayView&quot;
        android:layout_width=&quot;wrap_content&quot;

        android:layout_height=&quot;wrap_content&quot;&gt;

    &lt;/androidx.recyclerview.widget.RecyclerView&gt;
&lt;/LinearLayout&gt;

and the view for the inner recyclerView:

    &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
    &lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:id=&quot;@+id/showEvents&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:orientation=&quot;vertical&quot;&gt;

    &lt;TextView
        android:id=&quot;@+id/eventName&quot;
        android:layout_width=&quot;145px&quot;
        android:layout_height=&quot;wrap_content&quot; /&gt;

&lt;/LinearLayout&gt;

The adapter for the main recyclerview:

public class MonthViewAdapter extends RecyclerView.Adapter&lt;MonthViewAdapter.ViewHolder&gt;  {

    Context context;
    ArrayList&lt;Day&gt; days;
    
    CustomLinearLayoutManager l;

    public MonthViewAdapter(Context context, ArrayList&lt;Day&gt; arrayList) {
       
        this.context = context;
        this.days = arrayList;
    }

    @NonNull
    @Override
    public MonthViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.content_events, parent, false);
        return new ViewHolder(view, this.mOnDayClickListener);
    }

    @Override
    public void onBindViewHolder(MonthViewAdapter.ViewHolder holder, int position) {

        l = new CustomLinearLayoutManager(context, LinearLayout.VERTICAL, false);
        ViewGroup.LayoutParams params=holder.r.getLayoutParams();
        params.height=100;
        holder.r.setLayoutParams(params);
        holder.r.setLayoutManager(l);
        EventViewAdapter adapter = new EventViewAdapter(context, days.get(position).getEvents(), this.mOnDayClickListener);

        holder.r.setAdapter(adapter);
        holder.t.setText(days.get(position).getMonthDayNumber());

    }

    @Override
    public int getItemCount() {
        return days.size();
    }
    public class ViewHolder extends RecyclerView.ViewHolder  {
        RecyclerView r;
        TextView t;
        FrameLayout f;
        LinearLayout l;

        public ViewHolder(View itemView) {
            super(itemView);
            l = itemView.findViewById(R.id.dayView);
            t = itemView.findViewById(R.id.dayNum);
            r  = itemView.findViewById(R.id.eventDayView);

            
        } 
    }
}

The adapter for the inner RecyclerView:

public class EventViewAdapter extends RecyclerView.Adapter&lt;EventViewAdapter.ViewHolder&gt; {

    Context context;
    ArrayList&lt;Event&gt; events;
    

    public EventViewAdapter (Context context, ArrayList&lt;Event&gt; arrayList) {
        this.context = context;
        this.events = arrayList;
        
    }

    @Override
    public EventViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.content_single_event, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(EventViewAdapter.ViewHolder holder, int position) {
        Log.d(&quot;event&quot;, Integer.toString(events.size()));
        holder.eventName.setText(events.get(position).getName());

    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView eventName;
        
        LinearLayout linearLayout;

        public ViewHolder(View itemView) {
            super(itemView);
            eventName = itemView.findViewById(R.id.eventName);
            linearLayout = itemView.findViewById(R.id.showEvents);
            
        }
    }
}

The custom linear layout manager: https://stackoverflow.com/a/38513905/13199395

And the activity

public class MonthViewActivity extends AppCompatActivity{

        RecyclerView month;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_month_view);
           
            month.setHasFixedSize(true);
            month.addItemDecoration(new DividerItemDecoration(this,
                    DividerItemDecoration.HORIZONTAL));
            month.addItemDecoration(new DividerItemDecoration(this,
                    DividerItemDecoration.VERTICAL));
    
            GridLayoutManager g = new GridLayoutManager(this, 7);
    
            month.setLayoutManager(g);
    
            ArrayList&lt;Day&gt; day = new ArrayList&lt;&gt;();
            LocalDate dd = LocalDate.now();
            Day d1 = new Day(dd);
            Day d2 = new Day(dd.plusDays(1));
            Day d3 = new Day(dd.plusDays(2));
            d1.addEvent(new Event(&quot;a&quot;));
            day.add(d1);
            adapter = new MonthViewAdapter(this, day, this);
            month.setAdapter(adapter);
        }
    }

Each element of the list that I pass into the month view adapter has a list of events that are then passed into the event adapter. However, each day in the grid only shows one of the events, it does not show all of the events in the event list on each day. Why is this happening and how can I fix it? I am getting an error (java.lang.IndexOutOfBoundsException: Invalid item position) on

View view = recycler.getViewForPosition(position);

in the custom layout manager, but the program does not crash.

huangapple
  • 本文由 发表于 2020年4月9日 02:05:49
  • 转载请务必保留本文链接:https://java.coder-hub.com/61107153.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定