我正在我的 Android 应用程序中放置一个 RecyclerView
。因此,就像我在回收器 View 中看到的所有文档一样,我有一个 Adapter 类,其中定义了一个 ViewHolder 类。该代码如下所示(在 PointChangeAdapter.java
中)。
但是,我的代码和我见过的大多数教程之间有一个区别;
我没有为我的 ViewHolder
定义布局的 xml
文件。至少这就是我正在努力实现的目标。
看来我不需要定义自定义布局,因为我的 RecyclerView
的元素只是 TextView
。这可能可以通过 ListView 来完成,但我喜欢 RecyclerView 的灵活性,并且也只是想了解是否可以让我在这里工作。也就是说,有回收器,没有xml
布局。
为了适应缺少 xml
布局的情况,我修改了适配器的 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 View 在创建时不得附加”错误:
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
行的情况下运行代码时,我没有收到错误,
但在这种情况下,文本仍然不会显示在回收者 View 中。
所以也出现了一些问题。
另外,我觉得应该需要 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);
}
}
}
下面是运行它的内容 - 在 fragment 的 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 只是返回一个 ViewHolder,其中一个 ViewGroup(甚至可能只是一个 View)作为 Root View 。
您的问题是您将其添加到了父项中。你不想那样做。 RecyclerView 最终将成为其父级。您应该只是创建它并返回一个以该 View 作为 Root View 的持有者。
是的,即使传入的父级可能(尽管不一定)也是 RecyclerView。回收器 View 的布局管理器进行添加。这就是为什么 inflate() 调用的最后一个参数为 false - 以防止 inflate 将其添加到父级。
关于android - 我可以在没有 ViewHolder 的 xml 布局的情况下制作 recyclerview 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71791304/