Изменение цвета фона выбранного элемента в recyclerview
Как изменить цвет фона только выбранного вида в моем примере просмотра корзины? нужно изменить только цвет фона щелкнутого элемента itemview.
Только один выбранный элемент должен отображаться с изменением цвета фона за раз, а остальное должно быть как и перед выбором.
вот мой код:
MainActivity
public class MainActivity extends AppCompatActivity {
RecyclerView rv1;
private final String android_versions[]={
"Donut",
"Eclair",
"Froyo",
"Gingerbread",
"Honeycomb",
"Ice Cream Sandwich",
"Jelly Bean",
"KitKat",
"Lollipop",
"Marshmallow"
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews(){
rv1=(RecyclerView)findViewById(R.id.recyclerView1);
rv1.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager=new LinearLayoutManager(getApplicationContext());
rv1.setLayoutManager(layoutManager);
RecyclerDataAdapter rda=new RecyclerDataAdapter(rv1,getApplicationContext(),android_versions);
rv1.setAdapter(rda);
}
}
RecyclerDataadapter
public class RecyclerDataAdapter extends RecyclerView.Adapter<RecyclerDataAdapter.ViewHolder> {
private String android_versionnames[];
private Context context1;
private RecyclerView mRecyclerView;
public RecyclerDataAdapter(RecyclerView recylcerView,Context context,String android_versionnames[]){
this.android_versionnames=android_versionnames;
this.context1=context;
mRecyclerView=recylcerView;
setHasStableIds(true);
System.out.println("Inside dataadapter,Android names : \n ");
for(int i=0;i<android_versionnames.length;i++){
System.out.println("\n"+android_versionnames[i]);
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.tv1.setText(android_versionnames[position]);
}
@Override
public int getItemCount() {
return android_versionnames.length;
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView tv1;
LinearLayout row_linearlayout;
RecyclerView rv2;
public ViewHolder(final View itemView) {
super(itemView);
tv1=(TextView)itemView.findViewById(R.id.txtView1);
row_linearlayout=(LinearLayout)itemView.findViewById(R.id.row_linrLayout);
rv2=(RecyclerView)itemView.findViewById(R.id.recyclerView1);
/*itemView.setBackgroundColor(0x00000000);//to transparent*/
}
}
}
Ответы
Ответ 1
Наконец-то я получил ответ.
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.tv1.setText(android_versionnames[position]);
holder.row_linearlayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
row_index=position;
notifyDataSetChanged();
}
});
if(row_index==position){
holder.row_linearlayout.setBackgroundColor(Color.parseColor("#567845"));
holder.tv1.setTextColor(Color.parseColor("#ffffff"));
}
else
{
holder.row_linearlayout.setBackgroundColor(Color.parseColor("#ffffff"));
holder.tv1.setTextColor(Color.parseColor("#000000"));
}
}
здесь 'row_index' изначально устанавливается как '-1'
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView tv1;
LinearLayout row_linearlayout;
RecyclerView rv2;
public ViewHolder(final View itemView) {
super(itemView);
tv1=(TextView)itemView.findViewById(R.id.txtView1);
row_linearlayout=(LinearLayout)itemView.findViewById(R.id.row_linrLayout);
rv2=(RecyclerView)itemView.findViewById(R.id.recyclerView1);
}
}
Ответ 2
Очень простой способ добиться этого:
//instance variable
List<View>itemViewList = new ArrayList<>();
//OnCreateViewHolderMethod
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_row, parent, false);
final MyViewHolder myViewHolder = new MyViewHolder(itemView);
itemViewList.add(itemView); //to add all the 'list row item' views
//Set on click listener for each item view
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
for(View tempItemView : itemViewList) {
/** navigate through all the itemViews and change color
of selected view to colorSelected and rest of the views to colorDefault **/
if(itemViewList.get(myViewHolder.getAdapterPosition()) == tempItemView) {
tempItemView.setBackgroundResource(R.color.colorSelected);
}
else{
tempItemView.setBackgroundResource(R.color.colorDefault);
}
}
}
});
return myViewHolder;
}
ОБНОВИТЬ
Вышеуказанный метод может испортить некоторые атрибуты по умолчанию элемента itemView, в моем случае я использовал CardView, а угловой радиус карты удалялся по клику.
Лучшее решение:
//instance variable
List<CardView>cardViewList = new ArrayList<>();
public class MyViewHolder extends RecyclerView.ViewHolder {
CardView cardView; //THIS IS MY ROOT VIEW
...
public MyViewHolder(View view) {
super(view);
cardView = view.findViewById(R.id.row_item_card);
...
}
}
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
final OurLocationObject locationObject = locationsList.get(position);
...
cardViewList.add(holder.cardView); //add all the cards to this list
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//All card color is set to colorDefault
for(CardView cardView : cardViewList){
cardView.setCardBackgroundColor(context.getResources().getColor(R.color.colorDefault));
}
//The selected card is set to colorSelected
holder.cardView.setCardBackgroundColor(context.getResources().getColor(R.color.colorSelected));
}
});
}
ОБНОВЛЕНИЕ 2 - ВАЖНО
Метод onBindViewHolder вызывается несколько раз, а также каждый раз, когда пользователь прокручивает представление из поля зрения и обратно! Это приведет к тому, что одно и то же представление будет добавлено в список несколько раз, что может вызвать проблемы и незначительную задержку при выполнении кода!
Чтобы исправить это, измените
cardViewList.add(holder.cardView);
в
if (!cardViewList.contains(holder.cardView)) {
cardViewList.add(holder.cardView);
}
Ответ 3
Я могу предложить это решение, которое я использовал в своем приложении. Я поместил этот код onTouchListener в свой конструктор класса ViewHolder. itemView - аргумент конструктора. Обязательно используйте return false для этого метода, потому что это необходимо для работы OnClickListener
itemView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
v.setBackgroundColor(Color.parseColor("#f0f0f0"));
}
if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL)
{
v.setBackgroundColor(Color.TRANSPARENT);
}
return false;
}
});
Ответ 4
Создать графический файл в Drawable foloder
<item android:drawable="@color/SelectedColor" android:state_pressed="true"></item>
<item android:drawable="@color/SelectedColor" android:state_selected="true"></item>
<item android:drawable="@color/DefultColor"></item>
И в xml файле
android:background="@drawable/Drawable file"
В RecyclerView onBindViewHolder
holder.button.setSelected(holder.button.isSelected()?true:false);
Как кнопка переключения
Ответ 5
Если вы используете kotlin, это действительно просто.
В вашем классе RecyclerAdapter
userV.invalidateRecycler()
holder.card_User.setCardBackgroundColor(Color.parseColor("#3eb1ae").withAlpha(60))
В вашем фрагменте или деятельности
override fun invalidateRecycler() {
if (v1.recyclerCompanies.childCount > 0) {
v1.recyclerCompanies.childrenRecursiveSequence().iterator().forEach { card ->
if (card is CardView) {
card.setCardBackgroundColor(Color.WHITE)
}
}
}
}
Ответ 6
Мое решение:
public static class SimpleItemRecyclerViewAdapter
extends RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder> {
private final MainActivity mParentActivity;
private final List<DummyContent.DummyItem> mValues;
private final boolean mTwoPane;
private static int lastClickedPosition=-1;
**private static View viewOld=null;**
private final View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
DummyContent.DummyItem item = (DummyContent.DummyItem) view.getTag();
if (mTwoPane) {
Bundle arguments = new Bundle();
arguments.putString(ItemDetailFragment.ARG_ITEM_ID, item.id);
ItemDetailFragment fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
mParentActivity.getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment)
.commit();
} else {
Context context = view.getContext();
Intent intent = new Intent(context, ItemDetailActivity.class);
intent.putExtra(ItemDetailFragment.ARG_ITEM_ID, item.id);
context.startActivity(intent);
}
**view.setBackgroundColor(mParentActivity.getResources().getColor(R.color.SelectedColor));
if(viewOld!=null)
viewOld.setBackgroundColor(mParentActivity.getResources().getColor(R.color.DefaultColor));
viewOld=view;**
}
};
viewOld
имеет null
в начале, затем указывает на последнее выбранное представление. С помощью onClick
вы изменяете фон выбранного вида и переопределяете фон предпоследнего выбранного вида. Просто и функционально.
Ответ 7
Добавить клик для просмотра элементов в .onBindViewHolder() вашего адаптера RecyclerView. получить текущую выбранную позицию и изменить цвет на .setBackground() для ранее выбранного и текущего элемента
Ответ 8
Создайте селектор в папку Drawable:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<solid android:color="@color/blue" />
</shape>
</item>
<item android:state_pressed="false">
<shape>
<solid android:color="@android:color/transparent" />
</shape>
</item>
</selector>
Добавьте свойство в свой xml (где вы объявляете RecyclerView):
android:background="@drawable/selector"
Ответ 9
Самый простой способ с моей стороны - добавить переменную в adapterPage в качестве последней нажатой позиции.
in onBindViewHolder вставляет этот код, который проверяет последнюю сохраненную позицию, соответствующую положению загрузки
Константы - это класс, в котором я объявляю свои глобальные переменные
if(Constants.LAST_SELECTED_POSITION_SINGLE_PRODUCT == position) {
//change the view background here
holder.colorVariantThumb.setBackgroundResource(R.drawable.selected_background);
}
//on view click you store the position value and notifyItemRangeChanged will
// call the onBindViewHolder and will check the condition
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view){
Constants.LAST_SELECTED_POSITION_SINGLE_PRODUCT=position;
notifyItemRangeChanged(0, mColorVariants.size());
}
});
Ответ 10
Мне удалось сделать это из моей Activity, где я устанавливаю свой Rv, а не из адаптера
Если кому-то нужно сделать что-то подобное здесь, код
В этом случае цвет меняется на logClick
@Override
public void onLongClick(View view, int position) {
Toast.makeText(UltimasConsultasActivity.this, "Item agregado a la lista de mails",
Toast.LENGTH_SHORT).show();
sendMultipleMails.setVisibility(View.VISIBLE);
valueEmail.setVisibility(View.VISIBLE);
itemsSeleccionados.setVisibility(View.VISIBLE);
listaEmails.add(superListItems.get(position));
listaItems ="";
NameOfyourRecyclerInActivity.findViewHolderForAdapterPosition(position).NameOfYourViewInTheViewholder.setBackgroundColor((Color.parseColor("#336F0D")));
for(int itemsSelect = 0; itemsSelect <= listaEmails.size() -1; itemsSelect++){
listaItems += "*"+listaEmails.get(itemsSelect).getDescripcion() + "\n";
}
itemsSeleccionados.setText("Items Seleccionados : "+ "\n" + listaItems);
}
}));
Ответ 11
Я буду использовать этот код, но это не сработает для меня. Не измените цвет текста, пожалуйста, помогите мне здесь [ Как выделить один цвет текста и фона при использовании режима перекопа
Ответ 12
Я получил это так
public void onClick(View v){
v.findViewById(R.id.textView).setBackgroundColor(R.drawable.selector_row);
}
Спасибо
Ответ 13
То, что я сделал для достижения этой цели, на самом деле принимало статическую переменную, чтобы сохранить последнее нажатое положение элемента в RecyclerView, а затем уведомить адаптер, чтобы обновить макет в позиции в последнем нажатом положении, т.е. notifyItemChanged (lastClickedPosition) всякий раз, когда новая позиция щелчок. Вызов notifyDataSetChanged() на весь макет очень дорогостоящий и неосуществимый, поэтому сделать это только для одной позиции намного лучше.
Вот код для этого:
public class RecyclerDataAdapter extends RecyclerView.Adapter<RecyclerDataAdapter.ViewHolder> {
private String android_versionnames[];
private Context mContext;
private static lastClickedPosition = -1; // Variable to store the last clicked item position
public RecyclerDataAdapter(Context context,String android_versionnames[]){
this.android_versionnames = android_versionnames;
this.mContext = context;
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.row_layout,
parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.tv1.setText(android_versionnames[position]);
holder.itemView.setBackgroundColor(mContext.getResources().
getColor(R.color.cardview_light_background));
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
v.setBackgroundColor(mContext.getResources().
getColor(R.color.dark_background));
if (lastClickedPosition != -1)
notifyItemChanged(lastClickedPosition);
lastClickedPosition = position;
}
});
}
@Override
public int getItemCount() {
return android_versionnames.length;
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView tv1;
public ViewHolder(final View itemView) {
super(itemView);
tv1=(TextView)itemView.findViewById(R.id.txtView1);
}
}
}
Таким образом, мы будем фактически обновлять только предназначенный элемент и не перезапускать ненужные обновления для элементов, которые даже не были изменены.