Change cardview and text color of a listview

Asked

Viewed 699 times

0

I have a listview with a card view and inside the card view I have two text, I know how to activate the contextual action bar when you give long press in the list view and how to change the color of the text and cardview, but I don’t know how to change the color of cardview and text specifically in the listview item that was pressed... How to detect the exact item that was pressed and change only the widgets that are inside this listview item?

I tried on Adapter, but it changes the color of other items...

@Override
        public void bindView(View view, Context context, Cursor cursor) {
            TextView textClipper = (TextView) view.findViewById(R.id.clipperTextView);
            TextView textDate = (TextView) view.findViewById(R.id.dateTextView);

            cardView = (CardView) view.findViewById(R.id.clipperListCard);
            cardView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    if(cardView.isSelected()){
                        cardView.setSelected(false);
                        cardView.setCardBackgroundColor(Color.WHITE);
                        Log.i("CARD VIEW", "Esta selecionada!");
                    }else{
                        cardView.setSelected(true);
                        cardView.setCardBackgroundColor(Color.BLUE);
                        Log.i("CARD VIEW", "Não está selecionada!");
                    }

                    return false;
                }
            });

I tried to use xml selector to change the color when pressed, but it does not work for Card, searching saw that it is a bug that exists since 2014 and until today it seems that has not been solved... It simply ignores for Card, but for other widgets work...

Edit: I can’t do it here... I changed a few things but he won’t answer Onitemlongclicklistener.

XML that is played in listview:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="@dimen/clipper_listview">

    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/clipperListCard"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        card_view:cardCornerRadius="4dp"
        android:layout_margin="@dimen/cardview_listitem_margin">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:id="@+id/cardListLinear"
                android:layout_margin="@dimen/cardview_content_margin">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:text="Clipper text"
                android:id="@+id/clipperTextView" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Data - hora"
                android:id="@+id/dateTextView"/>

            </LinearLayout>

            <CheckBox
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_alignParentEnd="true"
                android:layout_centerInParent="true"
                android:id="@+id/checkBox2" />


        </RelativeLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>

Activity ta tab where you have listview:

public void gerarListView(View view){
        clipperListView = (ListView) view.findViewById(R.id.clipperListView);
        TClipper tClipper = new TClipper(view.getContext());
        Cursor cursorClipper = tClipper.getClipperAllLimit();
        final ClipperAdapter clipperAdapter = new ClipperAdapter(view.getContext(), cursorClipper, 0);
        clipperListView.setAdapter(clipperAdapter);
        clipperListView.setDivider(null);
        clipperListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
        clipperListView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
            //chamado cada vez que um item for selecionado
            @Override
            public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
                int qtItemSelected = clipperListView.getCheckedItemCount();
                mode.setTitle(getResources().getQuantityString(R.plurals.selected_items, qtItemSelected, qtItemSelected));
            }

            //chamado a primeira vez que o action for criado
            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                MenuInflater menuInflater = mode.getMenuInflater();
                menuInflater.inflate(R.menu.menu_tab1_contextual, menu);
                return true;
            }

            //é chamado quando a action é invalidate()
            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                return false;
            }

            //quando algum item da action for clicado
            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {

                switch (item.getItemId()) {
                    case R.id.action_card_remove:
                        Log.i("ACTION", "Menu clicado remove");
                        break;

                }
                mode.finish(); //fechar a action
                return true;
            }

            @Override
            public void onDestroyActionMode(ActionMode mode) {

            }
        });
        clipperListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                CardView cardView = (CardView) view.findViewById(R.id.clipperListCard);
                if(cardView.isSelected()){
                    cardView.setSelected(false);
                    cardView.setCardBackgroundColor(Color.WHITE);
                    Log.i("CARD VIEW", "Esta selecionada!");
                }else{
                    cardView.setSelected(true);
                    cardView.setCardBackgroundColor(Color.BLUE);
                    Log.i("CARD VIEW", "Não está selecionada!");
                }
                clipperListView.setItemChecked(position, true);
                Log.i("LIST VIEW", "LONG CLICK");
                return false;
            }
        });
    }

Adapter:

private class ClipperAdapter extends CursorAdapter {

        public ClipperAdapter(Context context, Cursor c, int flags) {
            super(context, c, flags);
        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            return LayoutInflater.from(context).inflate(R.layout.clipper_main_listview, parent, false);
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            //if(view==null) {
                TextView textClipper = (TextView) view.findViewById(R.id.clipperTextView);
                TextView textDate = (TextView) view.findViewById(R.id.dateTextView);
                CardView cardView = (CardView) view.findViewById(R.id.clipperListCard);
            //}



            textClipper.setText(cursor.getString(cursor.getColumnIndexOrThrow(ClipperDbContract.ClipperTable.TABELA_COLUNA_TEXT)));
            textDate.setText(
                    cursor.getString(cursor.getColumnIndexOrThrow(ClipperDbContract.ClipperTable.TABELA_COLUNA_DATA)) + " - " +
                            cursor.getString(cursor.getColumnIndexOrThrow(ClipperDbContract.ClipperTable.TABELA_COLUNA_HORA))
            );
        }
    }

1 answer

1


Felipe

The initial idea I had will not work because you are using the list view in multiple_modal mode.

So here’s what we’re gonna do:

Na Activity:

Remove the clipperListView.setOnItemLongClickListener()

Long Click does not work here because you are using Multiple mode modal.

No Adapter:

I added more logic to achieve your goal.

import android.content.Context;
import android.database.Cursor;
import android.graphics.Color;
import android.support.v7.widget.CardView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.TextView;



public class ClipperAdapter extends CursorAdapter {

    private ListView mListViewParent;

    public ClipperAdapter(Context context, Cursor c, int flags) {
        super(context, c, flags);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        if(mListViewParent == null)
            mListViewParent = (ListView) parent;
        return LayoutInflater.from(context).inflate(R.layout.list_view_row, null);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        final int position = cursor.getPosition();

        TextView textClipper = (TextView) view.findViewById(R.id.clipperTextView);
        TextView textDate = (TextView) view.findViewById(R.id.dateTextView);
        CardView cardView = (CardView) view.findViewById(R.id.clipperListCard);

        /*
            SET TEXT AND COLORS AND TAG FOR LATER USE
         */
        cardView.setTag(position);
        if (( mListViewParent).isItemChecked(position)) {
            setSelectState(cardView, true);
            ( mListViewParent).setItemChecked(position, true);
        } else {
            setSelectState(cardView, false);
            ( mListViewParent).setItemChecked(position, false);
        }

        textClipper.setText(cursor.getString(cursor.getColumnIndexOrThrow(ClipperDbContract.ClipperTable.TABELA_COLUNA_TEXT)));
        textDate.setText(
                cursor.getString(cursor.getColumnIndexOrThrow(ClipperDbContract.ClipperTable.TABELA_COLUNA_DATA)) + " - " +
                        cursor.getString(cursor.getColumnIndexOrThrow(ClipperDbContract.ClipperTable.TABELA_COLUNA_HORA))
        );

        /*
            SET CLICK LISTENER
         */
        cardView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                int position = (int) view.getTag();
                if ((mListViewParent).isItemChecked(position)) {
                    setSelectState(view, false);
                    ( mListViewParent).setItemChecked(position, false);
                } else {
                    setSelectState(view, true); // Creating view. If selected, keep it selected
                    ( mListViewParent).setItemChecked(position, true);
                }
                return true;
            }
        });
    }

    private void setSelectState(View cardview, boolean select) {
        if (select) {
            cardview.setSelected(true);
            ((CardView) cardview).setCardBackgroundColor(Color.BLUE);
        } else {
            cardview.setSelected(false);
            ((CardView) cardview).setCardBackgroundColor(Color.WHITE);
        }
    }
}
  • but in case I’m using Cursoradapter, and it has no getView, instead it’s bindView, bindView has no position

  • @Felipe.rce With a Cursoradapter you must have a field in the table that indicates whether or not it is selected. In bindView() change the color of Cardview depending on it.

  • @Felipe.rce Share your Adapter, your Activity and xml that is inflated by Adapter.. Hence, I update to respotas based on your source code... Share only what is necessary and such... no need to share the whole code

  • @Guilhermep edited the question and put the new editions I made... I just removed the cardview code from the bindView and sent it to Onitemlongclicklistener, but it doesn’t even enter Onitemlongclicklistener... I tried to put only the Log. i to test, and it does not enter...

  • Try to put this in the xml of listview: android:longClickable="true" and keep the log in function... to make sure it was called

  • You have another put in your code. In the list view, views are reused. So you can’t use them to determine whether that position is already selected or not... You need to keep this info separate... I’ll update the code for you to understand the idea

  • @Guilhermep put android:longClickable="true" and gave in the same, is not entering longclick

  • @Felipe.rce think its the reason. As you are using a listview with Multiple mode, that way I think long click will not work... I’ll work here again and share something later

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.