Как избежать изменения цвета текста и изображения в режиме просмотра с помощью Scrolling на ресивере? - PullRequest
0 голосов
/ 19 июня 2019

Я использую recyclerview для реализации своих элементов списка В каждой строке товара у меня есть текстовое изображение и значок часов. У меня также есть базовое время, в которое я сравниваю время каждого элемента повторного просмотра с ним. если разница составляет менее 30 минут, цвет значка просмотра текста и часов должен измениться на желтый. Я делаю это с помощью следующих строк кода:

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);
        }

но когда я прокручиваю строки в окне повторного просмотра, цвет текста и значок часов меняются неправильно. Я также использую массив для хранения состояния переменной isNear, но результаты такие же. Что мне делать?

Код адаптера:

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()));
        }
    }
}

1 Ответ

0 голосов
/ 19 июня 2019

Одним из способов решения этой проблемы было бы использование двух viewHolders.

Во-первых, спроектируйте два отдельных макета XML: один для isNear, а другой для другого. Например:

<?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>

Этот макет является первым макетом. А следующий - второй.

<?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>

Если вы посмотрите внимательно, вы увидите, что я изменил цвет текста для второго, чтобы показать изменение.

Теперь вам нужно взять два ViewHolders для каждого из них. Например: Для первого:

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

Я связал textView XML здесь. Теперь второй viewHolder:

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

Здесь я связываю этот файл со вторым файлом XML.

Теперь в классе адаптера вам нужно расширить его следующим образом:

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

Здесь вы увидите, что я не включил какой-либо конкретный viewHolder, но общий класс RecyclerView.ViewHolder. Теперь вам нужно переопределить метод getItemViewType в классе адаптера. Например:

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

Теперь, один ваш метод onCreateViewHolder в адаптере, вы должны проверить viewType и вернуть ViewHolder (View) в соответствии с ним. Например:

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);
    }

Теперь, в вашем методе onBindViewHolder, получите элемент из вашего ArrayList и установите для него элементы ViewHolder.

@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");
    }
}

Попробуйте и дайте мне знать, решаете ли вы это или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...