Подтвердить что ты не робот

Recyclerview + поставщик контента + CursorLoader

У меня есть некоторые данные в базе данных SQLite. У меня есть поставщик контента, который получит данные из базы данных. Теперь проблема в том, как я могу реализовать cursorLoader для работы с recyclerview?

Кроме того, кто-нибудь может объяснить, почему нам нужно перенести данные с курсора на объект, который будет отображаться в listview/recyclerview, а не прямо из курсора?

Например, в пользовательском классе cursorAdapter

Person person = new Person(cursor.getString(cursor.getColumnIndexOrThrow(PERSON_NAME)));
textview.setText = person.getName();

ИЛИ

textview.setText = cursor.getString(cursor.getColumnIndexOrThrow(PERSON_NAME));

Какой из вышеперечисленных методов лучше?

Раньше у нас было listview и gridview, и теперь кажется, что они объединены, чтобы стать recyclerview. Затем, как мне реализовать recyclerview на основе сетки?

4b9b3361

Ответ 1

В целом вы должны попытаться отделить требования к представлению и данным. Так что вам нужно получить все ваши объекты из базы данных заранее, а затем настроить адаптер, который выглядит следующим образом:

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
    private final List<Person> objectList = new ArrayList<>();

    @Override
    public CustomAdapter.ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
        final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        return new ViewHolder(layoutInflater.inflate(R.layout.adapter_item, parent, false));
    }

    @Override
    public void onBindViewHolder(final CustomAdapter.ViewHolder holder, final int position) {
        holder.bindItem(objectList.get(position));
    }

    // Set the persons for your adapter
    public void setItems(final List<Person> persons) {
        objectList.addAll(persons);
        notifyDataSetChanged();
    }

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

    public static class ViewHolder extends RecyclerView.ViewHolder {
        private final TextView mTextViewTitle;
        private Object mObject;

        public ViewHolder(final View itemView) {
            super(itemView);
            mTextViewTitle = (TextView) itemView.findViewById(R.id.view_item_textViewTitle);                
            mTextViewTitle.setText(mObject.getText());
        }

        private void bindItem(@NonNull final Person object) {
            mObject = object;
        }
    }
}

Затем вы можете привязать адаптер к RecyclerView с помощью:

final CustomAdapter adapter = new CustomAdapter();
adapter.setItems(mPersons);
mRecyclerView.setAdapter();

Чтобы ответить на ваш второй вопрос ( "Раньше у нас были списки и gridview, и теперь кажется, что они объединены, чтобы стать recyclerview. Затем, как мне реализовать grid-recyclerview?" ):

При привязке LayoutManager к RecyclerView вы можете решить, какой из них вы берете:

final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(layoutManager);

или

final GridLayoutManager layoutManager = new GridLayoutManager(this, COLUMN_SPAN_COUNT);
mRecyclerView.setLayoutManager(layoutManager);

Существует несколько LayoutManagers. Подробнее здесь.

UPDATE: Вам не нужно загружать все предметы заранее, просто переименуйте setItems в addItems, и вам хорошо идти

Ответ 2

Есть несколько Github gists/projects, таких как this и this, которые показывают такой прецедент.

В то время как вы будете использовать адаптор, специально адаптированный для адаптера курсора, для обычного использования вы должны использовать GridLayoutManager/LinearLayoutManager.

Ответ 3

Я думаю, вы можете использовать непосредственно Custom CursorAdapter для RecyclerView, поэтому вам не нужно преобразовывать Курсор в ArrayList

public class ProductListAdapter extends RecyclerView.Adapter<ProductListAdapter.ViewHolder> {

    // Because RecyclerView.Adapter in its current form doesn't natively 
    // support cursors, we wrap a CursorAdapter that will do all the job
    // for us.
    CursorAdapter mCursorAdapter;

    Activity mContext;
    Random rnd;

    public ProductListAdapter(AppCompatActivity context, Cursor c) {

        mContext = context;
        rnd = new Random();

        mCursorAdapter = new CursorAdapter(mContext, c, 0) {

            @Override
            public View newView(Context context, Cursor cursor, ViewGroup parent) {
                // Inflate the view here
                LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
                return inflater.inflate(R.layout.row_product_layout_grid, parent, false);
            }

            @Override
            public void bindView(View view, Context context, Cursor cursor) {
                String productName = cursor.getString(cursor.getColumnIndex(TProduct.PRODUCT_NAME));

                // Binding operations
                ((TextView) view.findViewById(R.id.sub_product_name_text_view)).setText(productName);



                int color = Color.argb(200, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));

                String url = "http://dummyimage.com/300/" + color + "/ffffff&text=" + (cursor.getPosition() + 1);

                Picasso
                        .with(context)
                        .load(url)
                        .placeholder(R.mipmap.ic_launcher) // can also be a drawable
                        .into((ImageView) view.findViewById(R.id.sub_product_image_view));
            }
        };
    }

    public void reQuery(Cursor c) {
        if (mCursorAdapter != null) {
            mCursorAdapter.changeCursor(c);
            mCursorAdapter.notifyDataSetChanged();
        }
    }

    @Override
    public int getItemCount() {
        return mCursorAdapter.getCount();
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // Passing the binding operation to cursor loader
        mCursorAdapter.getCursor().moveToPosition(position); //EDITED: added this line as suggested in the comments below, thanks :)
        mCursorAdapter.bindView(holder.view, mContext, mCursorAdapter.getCursor());
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // Passing the inflater job to the cursor-adapter
        View v = mCursorAdapter.newView(mContext, mCursorAdapter.getCursor(), parent);
        return new ViewHolder(v);
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        View view;
        public ViewHolder(View itemView) {
            super(itemView);
            view = itemView.findViewById(R.id.product_row_card_view);
        }
    }
}

Пусть это будет полезно для вас.:)