【问题标题】:Why RecyclerView onBindViewHolder called just once?为什么 RecyclerView onBindViewHolder 只调用一次?
【发布时间】:2016-07-02 03:19:01
【问题描述】:

我的代码中有一个奇怪的错误。我使用 Recycler View(过去使用没有任何问题)。我创建了测试 ArrayList 以在 Recycler 中显示它,但我在 RecyclerView 中获得了唯一的第一行,之后,应用程序停止(而不是崩溃),就像 ArrayList 完成一样。

我的主要代码:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view =  inflater.inflate(R.layout.fragment_all_tab, container, false);

    Activity activity = getActivity();

    //TODO: For testing ONLY
    ArrayList<Order> orders = new ArrayList<>();
    for(int i = 0; i < 10; i++) {
        orders.add(new Order(i, i, i));
    }

    // Initialising Orders Recycler View.
    OrderAdapter orderAdapter = new OrderAdapter(activity, orders);
    RecyclerView recyclerViewOrders = (RecyclerView) view.findViewById(R.id.recylerViewAllDiners);
    recyclerViewOrders.setLayoutManager(new LinearLayoutManager(activity));
    recyclerViewOrders.setAdapter(orderAdapter);

    return view;
}

适配器:

package com.slavafleer.tipcalculator;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;

/**
 * Order Adapter for Order Recycler View
 */
public class OrderAdapter extends RecyclerView.Adapter<OrderHolder> {

    private Context context;
    private ArrayList<Order> orders;

    public OrderAdapter(Context context, ArrayList<Order> orders) {

        this.context = context;
        this.orders = orders;
    }

    @Override
    public OrderHolder onCreateViewHolder(ViewGroup parent, int viewType) {

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

        View view = layoutInflater.inflate(R.layout.item_order, parent, false);

        return new OrderHolder(view);
    }

    // TODO: why it has been done just once ?
    @Override
    public void onBindViewHolder(OrderHolder holder, int position) {

        Order order = orders.get(position);

        holder.bindOrder(order);
    }

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

持有人:

package com.slavafleer.tipcalculator;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;

/**
 * Order Holder for Order Recycler View
 */
public class OrderHolder extends RecyclerView.ViewHolder {

    private TextView textViewOrderId;
    private TextView textViewDinerId;
    private TextView textViewPrice;

    public OrderHolder(View itemView) {
        super(itemView);

        textViewOrderId = (TextView) itemView.findViewById(R.id.textViewOrderId);
        textViewDinerId = (TextView) itemView.findViewById(R.id.textViewDinerId);
        textViewPrice = (TextView) itemView.findViewById(R.id.textViewPrice);
    }

    // Bind Data Object to the Views.
    public void bindOrder(Order order) {

        textViewOrderId.setText(order.getOrderId() + "");
        textViewDinerId.setText(order.getDinerId() + "");
        textViewPrice.setText(order.getPrice() + "");
    }


}

【问题讨论】:

    标签: java android android-recyclerview


    【解决方案1】:

    你可以试试这个吗?

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = (LayoutInflater)
                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    
        View view = layoutInflater.inflate(R.layout.item_order, parent, false);
    
        return new OrderHolder(view);
    }
    
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        Order order = orders.get(position);
    
        OrderHolder orderHolder = (OrderHolder)holder;
        orderHolder.bindOrder(order);
    }
    

    【讨论】:

    • onBindViewHolder 是@Override,所以我不能更改它的参数。
    • 将“扩展 RecyclerView.Adapter”替换为“扩展 RecyclerView.Adapter
    • OrderHolder 是从 RecyclerView.ViewHolder 扩展而来的,他为什么要替换它?在这种情况下不需要这样做
    【解决方案2】:

    首先,Febi Mathew,感谢您尝试帮助我解决此问题。

    我找到了解决方法。

    我在 Gradle 中的原始代码是

    compile 'com.android.support:recyclerview-v7:23.2.0'
    

    在我为 Recycler 做了样品后,它是一样的,我尝试了一个旧版本

    compile 'com.android.support:recyclerview-v7:23.1.1'
    

    而且效果很好。所以我想这不是我的错误 =)。如果您知道如何报告此错误,欢迎您这样做。

    更新: 问题是我没有将我的项目的布局高度设置为包装内容。而且由于我不理解旧版本的原因,这没关系,但在新版本上它只会占用我所有的屏幕,我没想过要尝试将其滑下。

    【讨论】:

    • 我不知道它是否重要,但我正在开发 Android Studio 2.0 的 beta 6 版本
    • 即时运行可能有问题。您是否尝试过使用 23.2 库进行全新安装?
    • WarrenFaith,不太清楚你的意思(你试过用 23.2 库干净安装干净的版本吗?)但这还没有结束 =)在我的简单测试 RecyclerView 上它按我说的那样工作以前,但在我的项目中它具有旧效果。我想我会尝试卸载测试版并在 Android Studio 的稳定版本上尝试相同的操作。
    • 我建议从模拟器/设备中删除您的应用程序,进行“构建 -> 清洁”并再次尝试运行并使用 23.2.0 库安装它。即时运行功能只是“注入”新代码,似乎仍然存在一些问题,所以我想知道您的 AS 注入的代码是否已经存在错误
    • 我觉得很愚蠢 =) 问题是我没有将我的项目的布局高度设置为包装内容。由于我不理解旧版本的原因,这并不重要,但在新版本上它只会占用我所有的屏幕,我没想过要尝试将其滑下。真是愚蠢的情况,但我很高兴它已经过去了。只是花时间重新安装工作室=)。再次感谢您尝试帮助我。
    【解决方案3】:

    我也遇到过同样的问题,因为高度参数设置错了。

    应该是wrap_content,但是我设置了layout-height = match_parent。

    所以第一个列表项会占据列表视图中的所有空间,所以它只显示一个列表项。

    【讨论】:

    • 。它帮了我很多。我在挖掘为什么 onBindViewHolder 只调用第一项而不是所有项目,即使我添加了日志。最后你的回答对我有帮助。谢谢
    【解决方案4】:

    检查项目布局高度的最外层元素是否未设置为“match_parent”值,而是设置为“wrap_content”或某个 Ndp 值。示例:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout mlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"  // Just like this!
        >
        <TextView
            android:id="@+id/item_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
        />
    </LinearLayout>
    

    【讨论】:

      【解决方案5】:

      我以前的提交 Recyclerview 支持版本:24.2.1

      后来我通过添加以下内容更新了 build.gradle:

      > configurations.all {
         >     resolutionStrategy.eachDependency { DependencyResolveDetails details ->
         >         def requested = details.requested
         >         if (requested.group == 'com.android.support') {
         >             if (!requested.name.startsWith("multidex")) {
         >                 details.useVersion '25.3.0'
         >             }
         >         }
         >     } }
      

      因此,在此之后,所有支持版本都已升级到 25.3.0,“multidex”除外。这意味着 recyclerview 版本也升级了。

      这是问题所在,在运行构建之后我的 recyclerview onbindviewholder 方法没有被调用。

      在评论上面的代码并运行后,我如何发现这个原因,能够使用我的 recyclerview

      希望这对某人有用。

      问候 维诺德

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-05
        • 1970-01-01
        • 2021-11-25
        相关资源
        最近更新 更多