简体   繁体   English

如何避免通过在 recyclerview 上滚动来更改 textview 颜色和 Imageview 颜色?

[英]how to avoid changing textview color and Imageview color with Scrolling on recyclerview?

I am using recyclerview to implement my list items.我正在使用 recyclerview 来实现我的列表项。 In each item row I have a textview and a clock icon.在每个项目行中,我都有一个文本视图和一个时钟图标。 I also have a base time which I compare the time of each recyclerview item with it.我还有一个基本时间,我将每个 recyclerview 项目的时间与它进行比较。 if the difference is less than 30 minutes ,the color of textview and clock Icon should change to yellow.如果差异小于 30 分钟,则 textview 和时钟图标的颜色应更改为黄色。 I do this with these lines of code:我用这些代码行来做到这一点:

if(!isNear) {
            time.setTextColor(context.getResources().getColor(R.color.yellow));
            Drawable clockIcon= ContextCompat.getDrawable(context, R.drawable.clock);
            clockIcon.setColorFilter(ContextCompat.getColor(context,R.color.yellow), PorterDuff.Mode.SRC_IN);
            clockIc.setImageDrawable(clockIcon);
        }
        else {
            time.setTextColor(context.getResources().getColor(R.color.white));
            Drawable clockIcon= ContextCompat.getDrawable(context, R.drawable.clock);
            clockIcon.setColorFilter(ContextCompat.getColor(context,R.color.white), PorterDuff.Mode.SRC_IN);
            clockIc.setImageDrawable(clockIcon);
        }

but when I am scrolling in the recyclerview rows, the color of textview and clock icon is changed wrong.但是当我在 recyclerview 行中滚动时,textview 和时钟图标的颜色更改错误。 I also use an array to store the state of the isNear variable but the results are same.我还使用一个数组来存储 isNear 变量的状态,但结果是相同的。 What should I do?我该怎么办?

Adapter code:适配器代码:

public class BusTicketAdapter extends RecyclerView.Adapter<BusTicketAdapter.View_Holder> {
    List<BusFromToResponse> availableBuses=new ArrayList<>();
    List<BusFromToResponse> displayedBuses=new ArrayList<>();
    private boolean[] toggledChoices;
    TicketListener ticketListener;
    Context context;
    String str_date;
    public BusTicketAdapter(List<BusFromToResponse> availableBuses,Context context,String str_date,TicketListener listener){
        this.availableBuses.addAll(availableBuses);
        displayedBuses.addAll(availableBuses);
        toggledChoices=new boolean[displayedBuses.size()];
        this.context=context;
        this.str_date=str_date;
        this.ticketListener=listener;
    }
    @Override
    public BusTicketAdapter.View_Holder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.filler_bus_tickets, parent, false);
        return new View_Holder(v);
    }

    @Override
    public void onBindViewHolder(View_Holder holder, int position) {

        Calendar c = Calendar.getInstance(TimeZone.getTimeZone("Asia/Tehran"));
        String timeC=c.getTime().toString();
        int index=timeC.indexOf("+");
        timeC=timeC.substring(index+1,index+6);
        int hour=4;
        String time=displayedBuses.get(position).getDepartureDate().substring(displayedBuses.get(position).getDepartureDate().indexOf("T")+1,
                displayedBuses.get(position).getDepartureDate().indexOf("Z")-3);
        if(timeC.contains("03:30"))
            hour=3;
        String[] hourmin=time.split(":");
        int min=Integer.valueOf(hourmin[1])+30;
        if(min>59){
            min-=60;
            hour+=1;
        }
        String minute=String.valueOf(min);
        if(min<10)
            minute="0"+minute;
        hour+=Integer.valueOf(hourmin[0]);
        if(hour>23)
            hour=hour-24;
        boolean isNear=DateUtil.IsBigger30Min(String.valueOf(hour)+":"+minute,c.getTime().getHours()+":"+c.getTime().getMinutes(),str_date);
        toggledChoices[position]=isNear;
        holder.time.setText((String.valueOf(hour).length()==1?"0"+String.valueOf(hour):String.valueOf(hour))+" : "+minute);
        holder.onBind(displayedBuses.get(position),position);
        if (position % 2 == 0) {
            holder.rootView.setBackgroundColor(context.getResources().getColor(R.color.ticket_row1));
        } else {
            holder.rootView.setBackgroundColor(context.getResources().getColor(R.color.ticket_row2));
        }
    }

    @Override
    public int getItemCount() {
        return displayedBuses.size();
    }

    class View_Holder extends RecyclerView.ViewHolder implements View.OnClickListener {
        ExtendedTextView time;
        ViewGroup rootView;
        ImageView clockIc;

        View_Holder(View v) {
            super(v);
            rootView = v.findViewById(R.id.fillerBusTicket_root);
            rootView.setOnClickListener(this);
            clockIc=v.findViewById(R.id.clock_ic);
            time=v.findViewById(R.id.time);
        }
        void onBind(BusFromToResponse bus,int position){

            if(!toggledChoices[position]) {
                time.setTextColor(context.getResources().getColor(R.color.yellow));
                Drawable clockIcon= ContextCompat.getDrawable(context, R.drawable.clock);
                clockIcon.setColorFilter(ContextCompat.getColor(context,R.color.yellow), PorterDuff.Mode.SRC_IN);
                clockIc.setImageDrawable(clockIcon);
            }
            else {
                time.setTextColor(context.getResources().getColor(R.color.white));
                Drawable clockIcon= ContextCompat.getDrawable(context, R.drawable.clock);
                clockIcon.setColorFilter(ContextCompat.getColor(context,R.color.white), PorterDuff.Mode.SRC_IN);
                clockIc.setImageDrawable(clockIcon);
            }
        }

        @Override
        public void onClick(View v) {
            ticketListener.onRowClicked(displayedBuses.get(getAdapterPosition()));
        }
    }
}

One way of solving this problem would be to take two viewHolders.解决这个问题的一种方法是采用两个 viewHolder。

First, Design two separate XML layouts, One for isNear and another one for the other.首先,设计两个单独的 XML 布局,一个用于 isNear,另一个用于另一个。 For example:例如:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView" />
</LinearLayout>

This layout is the first layout.这个布局是第一个布局。 And the next one is the second one.下一个是第二个。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@color/colorAccent"
        android:text="TextView" />
</LinearLayout>

If you look carefully, you will see that I have changed the text color for the second one to show the change.如果你仔细看,你会发现我已经改变了第二个的文本颜色来显示变化。

Now you have to take two ViewHolders for each of them.现在您必须为每个视图带两个 ViewHolder。 For example: For the first one:例如: 对于第一个:

public class FirstViewHolder extends RecyclerView.ViewHolder {
    public TextView textView;
    public FirstViewHolder(@NonNull View itemView) {
        super(itemView);
        textView = itemView.findViewById(R.id.textView);
    }
}

I have linked the textView of the XML here.我在这里链接了 XML 的 textView。 Now, the second viewHolder:现在,第二个 viewHolder:

public class SecondViewHolder extends RecyclerView.ViewHolder {
    public TextView textView;
    public SecondViewHolder(@NonNull View itemView) {
        super(itemView);
        textView = itemView.findViewById(R.id.textView);
    }
}

Here, I am linking this one with the second XML file.在这里,我将这个与第二个 XML 文件链接起来。

Now, in the adapter class, you need to extend it like this:现在,在适配器类中,您需要像这样扩展它:

public class NewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

Here, you will see that I haven't included any specific viewHolder but the general RecyclerView.ViewHolder class.在这里,您将看到我没有包含任何特定的 viewHolder,而是包含一般的RecyclerView.ViewHolder类。 Now, you have to override the getItemViewType method in the adapter class.现在,您必须覆盖适配器类中的getItemViewType方法。 For example:例如:

   @Override
    public int getItemViewType(int position) {
        if (isNear)
            return 0;
        else
            return 1;
    }

Now, one your onCreateViewHolder method in the adapter, you have to check the viewType and return ViewHolder(View) according to it.现在,适配器中的一个onCreateViewHolder方法,您必须检查 viewType 并根据它返回 ViewHolder(View) 。 For example:例如:

if (viewType == 0) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.first_layout,
                viewGroup, false);
        return new FirstViewHolder(view);
    } else {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.second_layout,
                viewGroup, false);
        return new SecondViewHolder(view);
    }

Now, on your onBindViewHolder method, get the element from your ArrayList and set it to the ViewHolder's Items.现在,在您的onBindViewHolder方法上,从您的 ArrayList 中获取元素并将其设置为 ViewHolder 的 Items。

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
    if (isNear) {
        FirstViewHolder holder = (FirstViewHolder) viewHolder;
        holder.textView.setText("something you want to set");
    } else {
        SecondViewHolder holder = (SecondViewHolder) viewHolder;
        holder.textView.setText("something you want to set");
    }
}

Try this and let me know whether you solve this or not.试试这个,让我知道你是否解决了这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM