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))
);
}
}
but in case I’m using Cursoradapter, and it has no getView, instead it’s bindView, bindView has no position
– felipe.rce
@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.– ramaral
@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
– W0rmH0le
@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...
– felipe.rce
Try to put this in the xml of listview: android:longClickable="true" and keep the log in function... to make sure it was called
– W0rmH0le
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
– W0rmH0le
@Guilhermep put android:longClickable="true" and gave in the same, is not entering longclick
– felipe.rce
@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
– W0rmH0le