Retrofit RecyclerViewAdapter 列表未分配

Retrofit RecyclerViewAdapter List not assigned

我被卡住了

如您所见,

List 为空,但我想在将其传递给适配器之前将其分配给来自 API 的响应。但是 List 作为 null 传递并抛出 null 异常。 我在 Adapter 初始化之前在 onCreate() 方法中调用了 API 方法,但不知何故它不起作用。

我不明白我在这里想念什么。怎么可能是List没有赋值。 我尝试初始化新的 ArrayList,它没有抛出任何错误,但这次 RecyclerView 是空的。

有什么帮助吗?

代码:

public class InventoryInfoActivity extends AppCompatActivity {


InventoryInfoRecyclerViewAdapter inventoryInfoRecyclerViewAdapter;
RecyclerView recyclerView;
ProductService productService;
List<Product> productList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_inventory_info);

    productService = new ProductService(this);
    // CALL METHOD
    this.getProductList();

    recyclerView  = findViewById(R.id.recycler_inventory);
    recyclerView.setLayoutManager(new LinearLayoutManager(InventoryInfoActivity.this));
    inventoryInfoRecyclerViewAdapter = new InventoryInfoRecyclerViewAdapter(productList,this);
    recyclerView.setAdapter(inventoryInfoRecyclerViewAdapter);
}

// API REQUEST
private void getProductList() {
    productService.getProducts().enqueue(new Callback<List<Product>>() {
        @Override
        public void onResponse(Call<List<Product>> call, Response<List<Product>> response) {
            if (response.isSuccessful()) {
                Log.i("REQUEST","OK");
               // ASSIGN
                productList = response.body();
            }else {
                Log.i("REQUEST","BAD");
                productList = new ArrayList<>();
            }
        }

        @Override
        public void onFailure(Call<List<Product>> call, Throwable t) {
            Log.i("REQUEST","FAILED");
            productList = new ArrayList<>();
        }
    });
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.search_action,menu);
    MenuItem menuItem = menu.findItem(R.id.action_search);

    SearchView searchView = (SearchView) menuItem.getActionView();
    searchView.setQueryHint("Ara");

    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            filter(newText);
            return false;
        }
    });


    return super.onCreateOptionsMenu(menu);
}

private void filter(String text) {
    ArrayList<Product> filteredlist = new ArrayList<>();
    for (Product item : productList) {
        if (item.getProductName().toLowerCase().contains(text.toLowerCase())) {
            filteredlist.add(item);
        }
    }
    if (filteredlist.isEmpty()) {
        Toast.makeText(this, "Böyle bir ürün yok", Toast.LENGTH_SHORT).show();
    } else {
        inventoryInfoRecyclerViewAdapter.filterList(filteredlist);
    }
}
}

LogCat:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.tempter.stoktakip, PID: 32165
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference

首先,在onCreate的最后调用getProductList

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); 
    List<Product> productlist = new ArrayList<Product>();
    setContentView(R.layout.activity_inventory_info);
    productService = new ProductService(this);
    recyclerView  = findViewById(R.id.recycler_inventory);
    recyclerView.setLayoutManager(new LinearLayoutManager(InventoryInfoActivity.this));
    inventoryInfoRecyclerViewAdapter = new InventoryInfoRecyclerViewAdapter(productList,this);
    recyclerView.setAdapter(inventoryInfoRecyclerViewAdapter);
    this.getProductList();
}

然后我推测 getProductList 应该是 return 一个产品列表或另一个 class 的列表。

private ArrayList<Product> getProductList() {
    productService.getProducts().enqueue(new Callback<List<Product>>() {
        @Override
        public void onResponse(Call<List<Product>> call, Response<List<Product>> response) {
            if (response.isSuccessful()) {
                Log.i("REQUEST","OK");
               // ASSIGN
                productList = response.body();
            }else {
                Log.i("REQUEST","BAD");
                productList = new ArrayList<>();
            }
        }

        @Override
        public void onFailure(Call<List<Product>> call, Throwable t) {
            Log.i("REQUEST","FAILED");
            productList = new ArrayList<>();
        }
    });
}
return productList;

这里的问题是,在您收到响应后,您应该通知您的适配器您有一个新列表。 RecyclerView 中有很多很酷的方法,叫做 notifiyDataSetChanged.

你所做的并不全是错的。让我解释一下您可以在代码中做什么:

  1. 你定义的变量是一个没有任何值的列表,所以它是空的。

private List<Product> items = new ArrayList<Product>();

或者您应该修复适配器中的 getItems 方法,如下所示:

 public int getItems() {
    return items == null || items.isEmpty() ? 0 : items.size();
}
  1. 收到回复后,请将新列表传递给适配器。首先,您需要在适配器中创建一个方法来传递这些数据,如下所示
    //  in your adapter
    public void setData(List<String> newItems) {
        adapterItems.clear();
        adapterItems.addAll(newItems);
        notifyDataSetChange();
    }

然后在你成功 api 调用后你应该像下面那样做:

private void getProductList() {
        productService.getProducts().enqueue(new Callback<List<Product>>() {
            @Override
            public void onResponse(Call<List<Product>> call, Response<List<Product>> response) {
                if (response.isSuccessful()) {
                    Log.i("REQUEST", "OK");
                    // ASSIGN
                    productList = response.body();
        
                    //!! This is here important

                    inventoryInfoRecyclerViewAdapter.setData(productList);

                    //!! This is here important 

                } else {
                    Log.i("REQUEST", "BAD");
                    productList = new ArrayList<>();
                }
            }

            @Override
            public void onFailure(Call<List<Product>> call, Throwable t) {
                Log.i("REQUEST", "FAILED");
                productList = new ArrayList<>();
            }
        });
    }

现在就是这样。您现在应该使用新列表更新了 recyclerView。