我可以为 ViewHolder 创建一个没有 xml 布局的 recyclerview 吗?
Can I make a recyclerview without an xml layout for the ViewHolder?
我要在我的 android 应用程序中添加一个 RecyclerView
。因此,就像我在回收站视图中看到的所有文档一样,我有一个 Adapter
class,其中定义了一个 ViewHolder
class。该代码如下所示(在 PointChangeAdapter.java
中)。
但是,我的代码和我见过的大多数教程之间有一处不同;
我没有为 ViewHolder
定义布局的 xml
文件。至少那是我正在努力工作的。
看来我不需要定义自定义布局,因为我的 RecyclerView
的元素只是 TextView
。这可能可以通过 ListView 来完成,但我喜欢 RecyclerView
的灵活性,并且也只是想了解是否有可能让我在这里工作。也就是说,有 回收站,没有 xml
布局。
为了弥补 xml
布局的不足,我修改了 Adapter 的 onCreateViewHolder
方法。
一个典型的例子会使用布局充气器,例如
@Override
public PointChangeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final TextView textView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_viewholder_xml_layout, parent, false);
return new PointChangeViewHolder(textView);
}
我有
@Override
public PointChangeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final TextView textView = new TextView(parent.getContext());
parent.addView(textView);
return new PointChangeViewHolder(textView);
}
也就是说,不是在 xml 布局上调用 inflate
并指定 RecyclerView
父级,
我创建了一个新的 TextView
并通过 addView
.
将其直接添加到 RecyclerView
父级
唯一的问题是这不起作用。
它给我一个“ViewHolder views must not be attached when created”错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mherzl.pointcounter, PID: 5253
java.lang.IllegalStateException: ViewHolder views must not be attached when created. Ensure that you are not passing 'true' to the
attachToRoot parameter of LayoutInflater.inflate(..., boolean
attachToRoot)
at androidx.recyclerview.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:7080)
...
我也试过完全删除 parent.addView(textView);
行,
使我的示例几乎与 this 示例相同,
就像我正在尝试做的那样,它没有指定 xml
布局。
当我 运行 我的代码没有 addView
行时,我没有得到错误,
但在那种情况下,文本仍然不会出现在回收站视图中。
所以也出现了错误。
另外,我觉得应该需要 addView
行;
由于充气器似乎将 TextView
附加到 RecyclerView
父项,
看来我更换充气器的东西也应该附在上面。
是否可以使用 TextView
作为元素制作 RecyclerView
而不是由自定义 xml 布局定义的元素?
这是我的代码:
PointChangeAdapter.java
:
package com.mherzl.pointcounter;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class PointChangeAdapter extends RecyclerView.Adapter<PointChangeAdapter.PointChangeViewHolder> {
private List<Integer> recentChanges;
public PointChangeAdapter(List<Integer> recentChanges) {
this.recentChanges = recentChanges;
}
@Override
public int getItemCount() {
if (recentChanges == null) {
return 0;
}
return recentChanges.size();
}
@Override
public PointChangeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final TextView textView = new TextView(parent.getContext());
parent.addView(textView);
return new PointChangeViewHolder(textView);
}
@Override
public void onBindViewHolder(PointChangeViewHolder holder, int position) {
final int pointChange = recentChanges.get(position);
String text = Integer.toString(pointChange);
holder.setText(text);
}
public static class PointChangeViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
public PointChangeViewHolder(TextView textView) {
super(textView);
this.textView = textView;
}
public void setText(String text) {
textView.setText(text);
}
}
}
这就是 运行 的内容 -- 在片段的 onCreateView
中使用 RecyclerView
:
RecyclerView pointChangeRecycler =
(RecyclerView) view.findViewById(R.id.point_changes_recycler);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
pointChangeRecycler.setLayoutManager(layoutManager);
List<Integer> myList = new ArrayList<>();
myList.add(1); myList.add(2); myList.add(3);
PointChangeAdapter pointChangeAdapter = new PointChangeAdapter(myList);
pointChangeRecycler.setAdapter(pointChangeAdapter);
是的。 onCreateViewHolder 只是 returns 一个带有 ViewGroup(甚至可能只是一个视图)作为根视图的 ViewHolder。
您的问题是您将其添加到了父级。你不想那样做。 RecyclerView 最终将成为它的父级。您应该只是创建它并返回一个以该视图作为根视图的持有者。
是的,即使传入的父级可能(尽管不一定)也是 RecyclerView。回收器视图的布局管理器进行添加。这就是为什么您的 inflate() 调用的最后一个参数是 false- 以防止 inflate 将其添加到父级。
我要在我的 android 应用程序中添加一个 RecyclerView
。因此,就像我在回收站视图中看到的所有文档一样,我有一个 Adapter
class,其中定义了一个 ViewHolder
class。该代码如下所示(在 PointChangeAdapter.java
中)。
但是,我的代码和我见过的大多数教程之间有一处不同;
我没有为 ViewHolder
定义布局的 xml
文件。至少那是我正在努力工作的。
看来我不需要定义自定义布局,因为我的 RecyclerView
的元素只是 TextView
。这可能可以通过 ListView 来完成,但我喜欢 RecyclerView
的灵活性,并且也只是想了解是否有可能让我在这里工作。也就是说,有 回收站,没有 xml
布局。
为了弥补 xml
布局的不足,我修改了 Adapter 的 onCreateViewHolder
方法。
一个典型的例子会使用布局充气器,例如
@Override
public PointChangeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final TextView textView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_viewholder_xml_layout, parent, false);
return new PointChangeViewHolder(textView);
}
我有
@Override
public PointChangeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final TextView textView = new TextView(parent.getContext());
parent.addView(textView);
return new PointChangeViewHolder(textView);
}
也就是说,不是在 xml 布局上调用 inflate
并指定 RecyclerView
父级,
我创建了一个新的 TextView
并通过 addView
.
RecyclerView
父级
唯一的问题是这不起作用。
它给我一个“ViewHolder views must not be attached when created”错误:
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.mherzl.pointcounter, PID: 5253 java.lang.IllegalStateException: ViewHolder views must not be attached when created. Ensure that you are not passing 'true' to the attachToRoot parameter of LayoutInflater.inflate(..., boolean attachToRoot) at androidx.recyclerview.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:7080)
...
我也试过完全删除 parent.addView(textView);
行,
使我的示例几乎与 this 示例相同,
就像我正在尝试做的那样,它没有指定 xml
布局。
当我 运行 我的代码没有 addView
行时,我没有得到错误,
但在那种情况下,文本仍然不会出现在回收站视图中。
所以也出现了错误。
另外,我觉得应该需要 addView
行;
由于充气器似乎将 TextView
附加到 RecyclerView
父项,
看来我更换充气器的东西也应该附在上面。
是否可以使用 TextView
作为元素制作 RecyclerView
而不是由自定义 xml 布局定义的元素?
这是我的代码:
PointChangeAdapter.java
:
package com.mherzl.pointcounter;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class PointChangeAdapter extends RecyclerView.Adapter<PointChangeAdapter.PointChangeViewHolder> {
private List<Integer> recentChanges;
public PointChangeAdapter(List<Integer> recentChanges) {
this.recentChanges = recentChanges;
}
@Override
public int getItemCount() {
if (recentChanges == null) {
return 0;
}
return recentChanges.size();
}
@Override
public PointChangeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final TextView textView = new TextView(parent.getContext());
parent.addView(textView);
return new PointChangeViewHolder(textView);
}
@Override
public void onBindViewHolder(PointChangeViewHolder holder, int position) {
final int pointChange = recentChanges.get(position);
String text = Integer.toString(pointChange);
holder.setText(text);
}
public static class PointChangeViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
public PointChangeViewHolder(TextView textView) {
super(textView);
this.textView = textView;
}
public void setText(String text) {
textView.setText(text);
}
}
}
这就是 运行 的内容 -- 在片段的 onCreateView
中使用 RecyclerView
:
RecyclerView pointChangeRecycler =
(RecyclerView) view.findViewById(R.id.point_changes_recycler);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
pointChangeRecycler.setLayoutManager(layoutManager);
List<Integer> myList = new ArrayList<>();
myList.add(1); myList.add(2); myList.add(3);
PointChangeAdapter pointChangeAdapter = new PointChangeAdapter(myList);
pointChangeRecycler.setAdapter(pointChangeAdapter);
是的。 onCreateViewHolder 只是 returns 一个带有 ViewGroup(甚至可能只是一个视图)作为根视图的 ViewHolder。
您的问题是您将其添加到了父级。你不想那样做。 RecyclerView 最终将成为它的父级。您应该只是创建它并返回一个以该视图作为根视图的持有者。
是的,即使传入的父级可能(尽管不一定)也是 RecyclerView。回收器视图的布局管理器进行添加。这就是为什么您的 inflate() 调用的最后一个参数是 false- 以防止 inflate 将其添加到父级。