2

I want to multi select custom ListView row, I designed it using CardView and all events happens on this card, I want to implement Contextual Action bar 'CAB' when the user long press the card, actually I made it but can't change the row color state when selected like this, I used the code from this answer:

and make CardView checkable using this code:

    public class CheckableCard extends CardView implements Checkable {
    private boolean mChecked;

    private final static int[] CHECKED_STATE_SET = {
        android.R.attr.state_checked
    };

    public CheckableCard(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected int[] onCreateDrawableState(int extraSpace) {
        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
        if (isChecked()) {
            mergeDrawableStates(drawableState, CHECKED_STATE_SET);
        }
        return drawableState;
    }

    @Override
    public void toggle() {
        setChecked(!mChecked);
    }

    @Override
    public boolean isChecked() {
        return mChecked;
    }

    @Override
    public void setChecked(boolean checked) {
        if (mChecked != checked) {
            mChecked = checked;
            refreshDrawableState();
        }
    }
}

Then in OnLongClickListener in the CardView I make it checked:

cardView.setChecked(true);

but nothing works!

Also I don't know how to multi select it, because it normal ListView row we use setMultiChoiceModeListener but when the events happens on card not list I don't know how to implement this.

I am a beginner and need help please.

Community
  • 1
  • 1
Stephan
  • 45
  • 7
  • Having the checked state doesn't do anything to CardView, sadly. However, now I work on my app (here: https://play.google.com/store/apps/details?id=com.lb.app_manager ) to update it (currently it has fake cards), that will use the "selected" field to know that it's selected, and set the backround color accordingly. It's not the same, but maybe it will be enough for you. About multi-selection itself, I've stored which items are selected, so that in getView you will be able to update them accordingly. – android developer Nov 24 '15 at 09:43
  • @androiddeveloper Did you used [this](http://stackoverflow.com/a/30192562/5598148) answer to achieve the selector effect?, Also can you please post code snippet because i don't know how to implement that. – Stephan Nov 24 '15 at 11:44
  • Only for the foreground, and only for the unselected state (meaning default and clicking). I'm at the office right now and my app is done on my spare time. I will post code. Do you need it for the adapter too? The adapter only call setSelected(_selectedItems.contains(getItem(pos).someId)) or something like that. – android developer Nov 24 '15 at 12:08
  • yes please post full snippet because i am a beginner and this is my first time to deal with this. – Stephan Nov 24 '15 at 12:20
  • well I only did it recently, but it really depends if that's what you need. – android developer Nov 24 '15 at 13:57
  • i tried your app after you attached the link and i need to implement what you made, when i long click on the card i got the card selected and the CAB appears. – Stephan Nov 24 '15 at 14:07
  • Well currently the play store version doesn't have real cardView (which is why it looks a bit bad, especially on some screens) , but I've found a solution for the next version that I intend to publish. – android developer Nov 24 '15 at 14:13
  • So what to do now?, i don't know how to implement those stuff and i have a dead line to deliver the app. – Stephan Nov 24 '15 at 14:38
  • I don't understand. You don't want the code of what I did? – android developer Nov 24 '15 at 15:11
  • No man i need that code, just explain it please. – Stephan Nov 24 '15 at 17:38

1 Answers1

0

OK, here's what I did:

SelectableCardView

public class SelectableCardView extends CardView
  {
  private int _unselectedBackgroundColor;
  private int _selectedBackgroundColor;
  private boolean _isSelectedble;

  public SelectableCardView(Context context)
    {
    this(context,null);
    }

  public SelectableCardView(Context context,AttributeSet attrs)
    {
    this(context,attrs,0);
    }

  public SelectableCardView(Context context,AttributeSet attrs,int defStyleAttr)
    {
    super(context,attrs,defStyleAttr);
    final Resources res=context.getResources();
    _selectedBackgroundColor=...
    _unselectedBackgroundColor=... // you could use cardview_light_background or cardview_dark_background for the default values here, depending on your theme
    }

  public void setSelectedBackgroundColor(@ColorInt int selectedBackgroundColor)
    {
    _selectedBackgroundColor=selectedBackgroundColor;
    }

  public void setUnselectedBackgroundColor(@ColorInt int unselectedBackgroundColor)
    {
    _unselectedBackgroundColor=unselectedBackgroundColor;
    }

  @Override
  public void setSelected(final boolean selected)
    {
    super.setSelected(selected);
    if(_isSelectedble)
      setCardBackgroundColor(isSelected()?_selectedBackgroundColor:_unselectedBackgroundColor);
    }

  public void setSelectedble(final boolean selectedble)
    {
    if(!selectedble)
      {
      super.setSelected(false);
      setCardBackgroundColor(_unselectedBackgroundColor);
      }
    _isSelectedble=selectedble;
    }
  }

usage:

<...SelectableCardView
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:clickable="true"
  android:foreground="@drawable/card_foreground"
  app:cardCornerRadius="@dimen/card_radius"
  app:cardElevation="4dp"
  app:contentPadding="10dp">
  ...

In order to make a card as selected, just call setSelected(...) on it.

No magic tricks here...

The rest of the code is similar to the link you've given here

Community
  • 1
  • 1
android developer
  • 114,585
  • 152
  • 739
  • 1,270