带有多个倒计时器的Recyclerview会导致闪烁

时间:2016-03-08 06:45:36

标签: android android-recyclerview countdowntimer

我想显示我的RecyclerView的每个单元格内剩余多少时间......因为我已经为每个单元格使用了倒数计时器。在每一行中我启动一个计数器并管理onTick() ...所有工作都按预期工作......我有一个计时器勾选每一行,我的单元格也在更新,但我的单元格现在闪烁....当我滚动时它会发疯。

这是我的适配器......

if (product.getProductType().equalsIgnoreCase("Auction Product")) {
                isAuction=true;
                viewHolder.img_product_type.setImageResource(R.drawable.bid);
                viewHolder.txt_timeleft.setVisibility(View.VISIBLE);
               start_countDown(product.getStart(),product.getStop(),viewHolder.txt_timeleft);
            }

计数器代码如下....

private void start_countDown(String start, String stop, final TextView txt_timeleft) {
        try {
            //Log.e("hetal",start+"....."+stop);
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            Calendar start_date = Calendar.getInstance();
            start_date.setTime(format.parse(start));

            Calendar end_date = Calendar.getInstance();
            end_date.setTime(format.parse(stop));

            final Calendar today = Calendar.getInstance();
            CountDownTimer timer;

            txt_timeleft.setTextColor(Color.DKGRAY);
            if(today.before(start_date)){
                txt_timeleft.setTextColor(context.getResources().getColor(R.color.red));
                txt_timeleft.setText(context.getString(R.string.auction_not_start));
                Animation anim = new AlphaAnimation(0.0f, 1.0f);
                anim.setDuration(1000); //You can manage the time of the blink with this parameter
                anim.setStartOffset(20);
                anim.setRepeatMode(Animation.REVERSE);
                anim.setRepeatCount(Animation.INFINITE);
                txt_timeleft.startAnimation(anim);
                return;
            }
            if (!today.before(end_date)) {

                txt_timeleft.setTextColor(context.getResources().getColor(R.color.red));
                txt_timeleft.setText(context.getString(R.string.time_out));
                        Animation anim = new AlphaAnimation(0.0f, 1.0f);
                        anim.setDuration(1000); //You can manage the time of the blink with this parameter
                        anim.setStartOffset(20);
                        anim.setRepeatMode(Animation.REVERSE);
                        anim.setRepeatCount(Animation.INFINITE);
                txt_timeleft.startAnimation(anim);
                return;
            }

            timer = new CountDownTimer(end_date.getTimeInMillis(), 1000) {
                @Override
                public void onTick(long millisUntilFinished) {

                    Calendar calendar = Calendar.getInstance();
                    calendar.setTimeInMillis(millisUntilFinished);

                    long diff = calendar.getTimeInMillis() - today.getTimeInMillis();

                    long seconds = diff / 1000 % 60;
                    long minutes = diff / (60 * 1000) % 60;
                    long hours = diff / (60 * 60 * 1000) % 24;
                    //long days = (int) diff / (24 * 60 * 60 * 1000);
                    long days = TimeUnit.MILLISECONDS.toDays(diff);


                    String left = "";
                    if (days > 0)
                        left += days + " " + context.getString(R.string.txt_day) + " ,";
                    if (hours > 0)
                        left += hours + " " + context.getString(R.string.txt_hour) + " ,";
                    if (minutes > 0)
                        left += minutes + " " + context.getString(R.string.txt_minute) + " ,";

                    left += seconds + " " + context.getString(R.string.txt_second);

                    final String finalLeft = left;


                            if (finalLeft.equals("0") || finalLeft.contains("-")) {
                                txt_timeleft.setText(context.getString(R.string.time_out));
                                txt_timeleft.setTextColor(context.getResources().getColor(R.color.red));
                                Animation anim = new AlphaAnimation(0.0f, 1.0f);
                                anim.setDuration(1000); //You can manage the time of the blink with this parameter
                                anim.setStartOffset(20);
                                anim.setRepeatMode(Animation.REVERSE);
                                anim.setRepeatCount(Animation.INFINITE);
                                txt_timeleft.startAnimation(anim);
                            } else
                                txt_timeleft.setText(finalLeft);
                }

                @Override
                public void onFinish() {

                }
            };
            timer.start();
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

2 个答案:

答案 0 :(得分:5)

thanx Hammad Tariq Sahi我已经用你的逻辑并以这种方式解决了我的问题....我也审查了这个link

在我的适配器

ArrayList<ViewHolder> viewHoldersList;
    private Handler handler = new Handler();
    private Runnable updateRemainingTimeRunnable = new Runnable() {
        @Override
        public void run() {
            synchronized (viewHoldersList) {
                for (ViewHolder holder : viewHoldersList) {
                    holder.updateTimeRemaining();
                }
            }
        }
    };

我的适配器的内部构造函数

viewHoldersList = new ArrayList<>();
startUpdateTimer();

并添加此方法来计算时间

private void startUpdateTimer() {
        Timer tmr = new Timer();
        tmr.schedule(new TimerTask() {
            @Override
            public void run() {
                handler.post(updateRemainingTimeRunnable);
            }
        }, 1000, 1000);
    }

向我的viewholder类添加了两个方法

public void setData(Product product){
            this.product = product;
        }
        public void updateTimeRemaining() {
            if(product.getProductType().equalsIgnoreCase("Auction Product")) {
                Log.e("hetal",product.getProductType());
                try {
                    String start = product.getStart();
                    String stop = product.getStop();

                    //txt_timeleft.setText("");
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                    Calendar start_date = Calendar.getInstance();
                    start_date.setTime(format.parse(start));

                    Calendar end_date = Calendar.getInstance();
                    end_date.setTime(format.parse(stop));

                    final Calendar today = Calendar.getInstance();
                    CountDownTimer timer;

                    long timeDiff = end_date.getTimeInMillis() - today.getTimeInMillis();
                    if (timeDiff > 0) {
                        long seconds = timeDiff / 1000 % 60;
                        long minutes = timeDiff / (60 * 1000) % 60;
                        long hours = timeDiff / (60 * 60 * 1000) % 24;
                        //long days = (int) diff / (24 * 60 * 60 * 1000);
                        long days = TimeUnit.MILLISECONDS.toDays(timeDiff);


                        String left = "";
                        if (days > 0)
                            left += days + " " + context.getString(R.string.txt_day) + " ,";
                        if (hours > 0)
                            left += hours + " " + context.getString(R.string.txt_hour) + " ,";
                        if (minutes > 0)
                            left += minutes + " " + context.getString(R.string.txt_minute) + " ,";

                        left += seconds + " " + context.getString(R.string.txt_second);

                        final String finalLeft = left;
                        txt_timeleft.setText(finalLeft);
                    } else {
                        txt_timeleft.setText("Time Out !!");
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }

最后在onBindViewHolder中

synchronized (viewHoldersList) {
                viewHolder.setData(product);
                if(viewHoldersList.size()< (list.size()-2)) viewHoldersList.add(viewHolder);
            }

完美......比所有

答案 1 :(得分:3)

您需要在 RecyclerView onCreateViewHolder 方法中添加倒计时器,因为 onCreateViewHolder 只会被调用一次。

每次用户向上或向下滚动时都会调用

onBindViewHolder

请查看以下代码。

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

Context mContext;
int position;
DecoView decoView;

public UsageDetailsAdapter(Context context) {

    this.mContext = context;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_adapter_usage_details, parent, false);
    decoView = (DecoView) view.findViewById(R.id.dynamicArcView);


    Toast.makeText(mContext,""+ position, Toast.LENGTH_SHORT).show();


    position++;
    return new ViewHolder(view);


}

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

    /*
    * onBindViewHolder will be called every time user scroll up or down
    *
    * */


}

@Override
public int getItemCount() {
    return 10;
}

public class ViewHolder extends RecyclerView.ViewHolder {

    public ViewHolder(View itemView) {
        super(itemView);
        decoView = (DecoView) itemView.findViewById(R.id.dynamicArcView);
        decoView.setBackgroundColor(mContext.getResources().getColor(R.color.textColorPrimary));
        /*
        * View holder will be called once, but if user scroll before completing arc view
        * animation will not be completed.
        *
        * */
    }
}

}