【问题标题】:RecyclerView isn't visible on FragmentRecyclerView 在 Fragment 上不可见
【发布时间】:2020-07-22 17:10:27
【问题描述】:

我正在关注 this 教程来实现 Room 数据库。一切都一样,除了我在一个片段上。没有错误,RecyclerView 卡片根本不可见。 (不使用RecyclerView 时我仍然可以动态添加卡片)

我已经在一个 Activity 上尝试过这个,但它仍然不起作用,所以我一定错过了一些东西,因为我没有从教程中复制整个代码。也许这很简单,因为我是 Android 新手。

适配器:

public class CartItemAdapter extends RecyclerView.Adapter<CartItemAdapter.CartItemHolder> {
    private List<CartItem> cartItems = new ArrayList<>();

    @NonNull
    @Override
    public CartItemHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.sample_product_item, parent, false);
        return new CartItemHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull CartItemHolder holder, int position) {
        CartItem currentCartItem = cartItems.get(position);
        holder.tvItemName.setText(currentCartItem.getItemName());
        holder.tvItemPrice.setText(currentCartItem.getItemPrice());
        holder.tvQuantity.setText(String.valueOf(currentCartItem.getQuantity()));
    }

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

    public void setCartItems(List<CartItem> cartItems) {
        this.cartItems = cartItems;
        notifyDataSetChanged();
    }

    class CartItemHolder extends RecyclerView.ViewHolder {
        private TextView tvItemName;
        private TextView tvItemPrice;
        private TextView tvQuantity;

        public CartItemHolder(@NonNull View itemView) {
            super(itemView);
            tvItemName = itemView.findViewById(R.id.itemName);
            tvItemPrice = itemView.findViewById(R.id.itemPrice);
            tvQuantity = itemView.findViewById(R.id.quantity);
        }
    }

}

视图模型:

public class CartItemViewModel extends AndroidViewModel {
    private CartItemRepository repository;
    private LiveData<List<CartItem>> allCartItems;

    public CartItemViewModel(@NonNull Application application) {
        super(application);
        repository = new CartItemRepository(application);
        allCartItems = repository.getAllCartItems();
    }

    public void insert(CartItem cartItem) {
        repository.insert(cartItem);
    }

    public void update(CartItem cartItem) {
        repository.update(cartItem);
    }

    public void delete(CartItem cartItem) {
        repository.delete(cartItem);
    }

    public void deleteAllCartItems() {
        repository.deleteAll();
    }

    public LiveData<List<CartItem>> getAllCartItems() {
        return allCartItems;
    }
}

片段布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    android:orientation="vertical">

    <!--Views...-->

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/cart_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/totalCard"
        android:layout_below="@id/titleCard"
        android:padding="8dp"
        tools:listitem="@layout/sample_product_item">

        <!-- cart items dynamically added here -->

    </androidx.recyclerview.widget.RecyclerView>

    <!--Views...-->

</RelativeLayout>

片段类:

    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.frag_cart, container, false);
    RecyclerView recyclerView = view.findViewById(R.id.cart_recyclerview);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setHasFixedSize(true);
        final CartItemAdapter adapter = new CartItemAdapter();
        recyclerView.setAdapter(adapter);

        cartItemViewModel = new ViewModelProvider(getActivity(),
                ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication())).get(CartItemViewModel.class);
        cartItemViewModel.getAllCartItems().observe(getActivity(), new Observer<List<CartItem>>() {
            @Override
            public void onChanged(List<CartItem> cartItems) {
                adapter.setCartItems(cartItems);
                Log.i(TAG, "items set!");
            }
        });
    return view;
}

我已经在CartItemDatabase中填充了数据库

@Database(entities = {CartItem.class}, version = 1)
public abstract class CartItemDatabase extends RoomDatabase {

    private static CartItemDatabase instance;

    public abstract CartItemDao cartItemDao();

    public static synchronized CartItemDatabase getInstance(Context context) {
        if (instance == null) {
            instance = Room.databaseBuilder(context.getApplicationContext(),
                    CartItemDatabase.class, "cart_item_database")
                    .fallbackToDestructiveMigration()
                    .addCallback(roomCallback)
                    .build();
        }
        return instance;
    }

    private static RoomDatabase.Callback roomCallback = new RoomDatabase.Callback() {
        @Override
        public void onCreate(@NonNull SupportSQLiteDatabase db) {
            super.onCreate(db);
            new PopulateDbAsyncTask(instance).execute();
        }
    };

    private static class PopulateDbAsyncTask extends AsyncTask<Void, Void, Void> {
        private CartItemDao cartItemDao;

        private PopulateDbAsyncTask(CartItemDatabase db) {
            cartItemDao = db.cartItemDao();
        }

        @Override
        protected Void doInBackground(Void... voids) {
            cartItemDao.insert(new CartItem("Bread", "60", 2));
            cartItemDao.insert(new CartItem("Butter", "70", 1));
            return null;
        }
    }

}

我做错了什么? 请询问我是否需要更多信息。提前致谢。

【问题讨论】:

  • 检查适配器中是否有物品

标签: java android android-fragments android-recyclerview android-room


【解决方案1】:

建议

学习调试您的代码并查明您的错误。我得到的大多数错误都是通过调试来解决的。如果您不知道调试是什么或如何进行,您可以 google 一下。这真的很简单,它可以节省您解决问题的时间,并且完全可以节省您的问题。

我建议这样做是因为根据您的描述,我首先要检查的是我的 RecyclerView 是否收到任何东西。我会通过在我的 RecyclerView 的 getItemCount 方法中设置一个调试断点来做到这一点。如果返回的值大于 0 表示没问题。

然后我会继续检查我的代码的其他步骤,这样您就可以真正看到哪里出了问题,这对于更好地了解正在发生的事情和工作方式非常有用。

通过这种方式,您可以查明您的错误并提出更具体的问题。您可以只引用一个方法或一行代码,而不是引用整个代码。

编辑

很高兴听到问题在列表中。现在我发现您在适配器的第一行遇到了问题。当你这样做时,你正在创建一个新的空列表

private List&lt;CartItem&gt; cartItems = new ArrayList&lt;&gt;();

也许你可以考虑给适配器加一个参数比如

public class CartItemAdapter(List<CartItem> cartItems) extends RecyclerView.Adapter<CartItemAdapter.CartItemHolder>

您可以在适配器内使用该列表。它应该已经被填充。在您的 onCreateView 方法中,您可以执行类似的操作

// create the list
private List<CartItem> cartItems = new ArrayList<>();

// populate the list with some element or elements
CartItem item = new CartItem(constructor parameters);
cartItems.add(item);

// create the adapter and send the list as a parameter
final CartItemAdapter adapter = new CartItemAdapter(cartItems)
recyclerView.setAdapter(adapter)

然后在您的适配器中,您可以随意使用cartItems

【讨论】:

  • 感谢您的建议。如您所料,getItemCount 返回 0。所以现在我必须找到解决方法
  • 还是不行。我认为问题与 ViewModel 类有关,因为 insertupdatedelete 方法被标记为未使用。
  • 更新:稍后添加项目时效果很好。问题在于预填充数据库,我不需要。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-21
  • 2016-05-03
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
相关资源
最近更新 更多