3

我正在尝试显示从DBFlow (SQLite) 后端提供的 RecyclerView 列表。列表中的每个项目都代表一个项目,一旦选择该项目将转换到详细活动视图。与任何 CursorLoader 一样,我希望每次在支持视图的加载器中发生更改时,布局都会自行更新。

这在Marshmallow中测试时是正确的,但在LollipopJelly Bean (4.3)中都没有这样做。在失败的情况下,一个项目会显示在列表中,尽管在调试器中看到onBindViewHolder()为每个项目调用一次(正确的数据到达光标,顺便说一句)。

以下是我认为的主要内​​容。我特意简化了代码,如有必要,请随时请求更多详细信息:


onResume() 在显示列表的活动中覆盖:

@Override
protected void onResume() {
    super.onResume();

    getSupportLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks<Cursor>() {
        @Override
        public Loader<Cursor> onCreateLoader(int arg0, Bundle cursor) {
            return BackendManager.getListCursorLoader(mContext);
        }

        @Override
        public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {
            int numItemsRetrieved = cursor.getCount();
            if ((numItemsRetrieved == 1) {
                Optional<Item> selectedItemOpt = BackendManager.getSingleItem();

                if (selectedItemOpt.isPresent()) {
                    Item selectedItem = selectedItemOpt.get();

                    Intent t = new Intent(mContext, ItemDetailActivity.class);
                    Bundle b = new Bundle();
                    b.putSerializable("item", selectedItem);
                    it.putExtras(b);
                    startActivityForResult(it, SHOW_ITEM_DETAIL);
                }
            }

            ((ItemListRecyclerAdapter) mRecyclerListView.getAdapter()).swapCursor(cursor);
        }

        @Override
        public void onLoaderReset(Loader<Cursor> arg0) {
            ((ItemListRecyclerAdapter) mRecyclerListView.getAdapter()).swapCursor(null);
        }
    });
}

在静态管理器中生成 CursorLoader:

public static CursorLoader getListCursorLoader(Context ctx) {
    return new CursorLoader(
            ctx,                                            // Context
            Item.CONTENT_URI,                               // Uri
            null,                                           // Projection
            null,                                           // Selection
            null,                                           // selectionArgs
            null                                            // sortOrder
    );
}

用于游标的 RecyclerView 适配器。目前使用skyfish的

public class ItemListRecyclerAdapter extends CursorRecyclerViewAdapter<ItemListRecyclerAdapter.ViewHolder> {

    private Context mContext;

    public ItemListRecyclerAdapter(Context context, Cursor cursor) {
        super(context, cursor);

        mContext = context;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView itemText;
        public ImageView itemImage;

        public ViewHolder(View view) {
            super(view);
            itemText = (TextView) view.findViewById(R.id.itemTitle);
            itemImage = (ImageView) view.findViewById(R.id.itemPicture);
        }
    }

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

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, Cursor cursor) {

        // Find fields to populate in inflated template
        String itemTextData = cursor.getString(cursor.getColumnIndex("itemText"));
        viewHolder.itemText.setText(itemTextData);
        // Force text fit
        AutofitHelper afh = AutofitHelper.create(viewHolder.itemText);
        afh.setMaxTextSize(TypedValue.COMPLEX_UNIT_SP, 22.0f);

        String itemImageUrl = cursor.getString(cursor.getColumnIndex("logo"));
        if ((itemImageUrl != null) && (!itemImageUrl.isEmpty())) {
            Picasso.with(mContext)
                    .load(itemImageUrl)
                    .resize(300, 300)
                    .centerCrop()
                    .placeholder(R.drawable.placeholder)
                    .into(viewHolder.itemImage);
        } else {
            viewHolder.itemImage.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.placeholder));
        }
    }
}

如上所述,这已经过测试和验证:

  • Nexus 6 上的棉花糖 (6.0.1):工作
  • Galaxy S5 上的棒棒糖 (5.0):不工作
  • Galaxy S3上的果冻豆(4.3):不工作

我在这里错过了什么吗?关于在哪里进一步寻找的任何提示?

4

1 回答 1

3

由于没有任何答案,我将解释我最终为解决此问题所做的工作。

完全重写后,我摆脱了 skyfish 的 Cursor Adapter 并使用 Android 的 RecyclerView 界面全力以赴。我没有使用游标/适配器方案从 SQLite 后端提取数据并在对底层存储进行更改时交换游标,而是在存储管理器中启用了一个get-all-items静态方法来检索最新数据。为了在数据更改时更新列表,我使用 DBFlow 的Observables来获取此类更改的通知。一旦检测到更改,我会使用此类获取所有项目检索更新的数据,并相应地更新 RecyclerView,执行适当的notifyItem()调用以动画布局更改。

无需 Android 和 DBFlow 之外的其他依赖项或代码。这种方法已在原始问题中描述的所有设备中得到验证。

于 2016-03-30T08:09:42.847 回答