android - 我可以在没有 ViewHolder 的 xml 布局的情况下制作 recyclerview 吗?

标签 android android-recyclerview

我正在我的 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/

相关文章:

Android - 防止 Activity 在停留在后台后重新启动

android - 如何在我的 android 应用程序主屏幕中实现以下转换?

php - 如何使用 volley api 将 android 应用程序连接到本地服务器

android - 在 Recyclerview 中错误地运行 onBindViewHolder - Kotlin

Android 谷歌地图故障显示中间有 x 的空白方 block android

java - 缩放 View - 不是从可绘制 View

android - 为什么只有第一行显示使用 Recyclerview gridlayoutmanager

Android GridLayout 具有动态每行列数

android - 如何在android中使用flexboxlayoutmaanger创建类似instagram explore的布局?

android - 如果像 flipkart 价格范围一样在 RecyclerView 中检查过,如何将复选框设置为 true