How to update views in a custom PrimaryDrawerItem?

328 Views Asked by At

I am using MaterialDrawer (and also FastAdapter) to create left and right drawers in my app and currently I use a compact style account header in the right drawer (see the green area with user photo in the below screenshot).

However I need few more text fields there, so I would like to switch - and use a custom PrimaryDrawerItem (please see the magenta area in the below screenshot).

I have studied the guides listed at https://github.com/mikepenz/MaterialDrawer/blob/develop/FAQ/howto_modify_add_custom_draweritems.md and have tried creating such an item with an ImageView and two TextViews here:

public class RightDrawerItem extends AbstractDrawerItem<RightDrawerItem, RightDrawerItem.ViewHolder> {

    public String photo;
    public String given;
    public String score;

    @Override
    public int getType() {
        return R.id.right_drawer_item_id;
    }

    @Override
    @LayoutRes
    public int getLayoutRes() {
        return R.layout.right_drawer_item;
    }

    @Override
    public void bindView(ViewHolder vh, List<Object> payloads) {
        super.bindView(vh, payloads);

        Context ctx = vh.itemView.getContext();
        if (ctx.getApplicationContext() instanceof SlovaApplication) {
            SlovaApplication app = (SlovaApplication) ctx.getApplicationContext();

            if (URLUtil.isHttpsUrl(photo)) {
                app.getPicasso()
                        .load(photo)
                        .placeholder(R.drawable.account_gray)
                        .into(vh.mPhoto);
            }
        }

        vh.mGiven.setText(given);
        vh.mScore.setText(score);

        //call the onPostBindView method to trigger post bind view actions (like the listener to modify the item if required)
        onPostBindView(this, vh.itemView);
    }

    @Override
    public ViewHolder getViewHolder(View v) {
        return new ViewHolder(v);
    }

    public void setPhoto(String photo) {
        this.photo = photo;
    }

    public void setGiven(String given) {
        this.given = given;
    }

    public void setScore(String score) {
        this.score = score;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        private ImageView mPhoto;
        private TextView mGiven;
        private TextView mScore;

        private ViewHolder(View view) {
            super(view);

            view.setBackgroundColor(Color.MAGENTA);

            mPhoto = view.findViewById(R.id.photo);
            mGiven = view.findViewById(R.id.given);
            mScore = view.findViewById(R.id.score);
        }
    }
}

My problem is that when I call

mRightDrawerItem.setPhoto(...);
mRightDrawerItem.setGiven(...);
mRightDrawerItem.setScore(...);

then the views my custom PrimaryDrawerItem are not updated, as you can see in the magenta area of the screenshot (pardon the non-english text):

app screenshot

Also, I am not quite sure what exactly is the vh.itemView?

I have also asked my question in the Github issue 2349

1

There are 1 best solutions below

0
On BEST ANSWER

@Alexander Farber as the Drawer is nothing else than a RecyclerView with elements (thus the items are based on the same approach like the items your create for the FastAdapter (theoretically fastAdapter items can be used by additionally implementing the IDrawerItem interface, and drawer items simply in any list))

So that means whenever you adjust fields of an element, you will need to notify the adapter about the update to the item. The MaterialDrawer comes with convenient functions like: https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/Drawer.java#L654

drawerItem.doMyUpdate(); // modify the item
Drawer.updateItem(drawerItem); // notify the drawer about the update

But you can also go to the roots of the adapter. Get the adapter: https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/Drawer.java#L654 and then update the item as you know it from any adapter.

In addition it is very important to note that you might want to provide a payload to allow optimisation of the refresh. (use a custom payload, and then react on that specific payload by updating the view)