2016-05-16 10 views
0

Recyclerviewに20個のカスタムカウントアップタイマーのリストがあります。最初に開始すると、14番目または15番目の行でも同じタイマーがテキストビューに表示されます。私はタイマーが最初のtextviewへの参照を保持していると推測し、それは14または15行目で再利用されているそれを継続的に更新しています。どのようにこれを効率的に行うか教えてもらえますか?前もって感謝します。Recyclerviewで古いビューを再利用

MainActivity.java

import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 

import java.util.ArrayList; 
import java.util.List; 

public class MainActivity extends AppCompatActivity { 

    private static final String TAG = "MainActivity"; 
    private RecyclerView mRecyclerView; 
    private CountAdapter mAdapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     mAdapter = new CountAdapter(getCount(), this); 
     mRecyclerView = (RecyclerView) findViewById(R.id.rv); 
     LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); 
     mRecyclerView.setLayoutManager(linearLayoutManager); 
     mRecyclerView.setAdapter(mAdapter); 

    } 

    private List<String> getCount() { 
     List<String> strings = new ArrayList<>(); 
     for (int i = 0; i < 20; i++) { 
      strings.add(i + ""); 
     } 
     return strings; 
    } 

} 

CountAdapter.java

import android.content.Context; 
import android.support.v7.widget.RecyclerView; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.CheckBox; 
import android.widget.ImageButton; 
import android.widget.TextView; 

import java.util.ArrayList; 
import java.util.List; 

public class CountAdapter extends RecyclerView.Adapter<CountAdapter.ViewHolder> { 
    private static final String TAG = "CountAdapter"; 
    private final List<String> mData; 
    private final List<CountUpTimer> mCountUpList = new ArrayList<>(); 
    private final ArrayList<Boolean> mSelectedRows = new ArrayList<>(); 
    private final Context mContext; 

    public CountAdapter(List<String> mData, Context mContext) { 
     this.mData = mData; 
     this.mContext = mContext; 

     mCountUpList.clear(); 
     for (int i = 0; i < mData.size(); i++) { 
      mCountUpList.add(i, null); 
     } 
     mSelectedRows.clear(); 
     for (int i = 0; i < mData.size(); i++) { 
      mSelectedRows.add(i, false); 
     } 
    } 


    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, 
             int viewType) { 
     View v = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.item, parent, false); 
     return new ViewHolder(v, mContext, mCountUpList, mSelectedRows); 
    } 

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

     checkTimerStatus(holder, position); 
     Log.d(TAG, "onBindViewHolder: " + position + " " + String.valueOf(mCountUpList.get(position))); 
    } 

    private void checkTimerStatus(final ViewHolder holder, int position) { 

     CountUpTimer countUpTimer = mCountUpList.get(position); 
     if (countUpTimer != null) { 
      Log.d(TAG, "checkTimerStatus: " + position); 
      countUpTimer.setOnTickListener(new CountUpTimer.OnTickListener() { 
       @Override 
       public void OnTick(long elapsed) { 
        holder.mTimeText.setText(elapsed + ""); 
       } 
      }); 
     } else { 
      holder.mTimeText.setText("00:00:00"); 
     } 

     boolean state = mSelectedRows.get(position); 
     holder.mCheckBox.setChecked(state); 

    } 

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

    static class ViewHolder extends RecyclerView.ViewHolder implements 
      CountUpTimer.OnTickListener, View.OnClickListener { 
     private static final String TAG = "ViewHolder"; 
     private final Context mContext; 
     private final ArrayList<Boolean> mSelectedRows; 
     private final TextView mTimeText; 
     private final ImageButton mStartButton; 
     private final CheckBox mCheckBox; 
     private final List<CountUpTimer> mCountUpList; 

     public ViewHolder(View v, Context mContext, List<CountUpTimer> mCountUp, 
          ArrayList<Boolean> mSelectedRows) { 

      super(v); 
      this.mContext = mContext; 
      this.mCountUpList = mCountUp; 
      this.mSelectedRows = mSelectedRows; 
      mTimeText = (TextView) v.findViewById(R.id.itemText); 
      mStartButton = (ImageButton) v.findViewById(R.id.ibPlay); 
      mCheckBox = (CheckBox) v.findViewById(R.id.checkBox); 
      mStartButton.setOnClickListener(this); 
      mCheckBox.setOnClickListener(this); 
     } 

     @Override 
     public void onClick(View v) { 

      switch (v.getId()) { 

       case R.id.ibPlay: 
        final CountUpTimer upTimer = new CountUpTimer(100); 
        upTimer.setOnTickListener(this); 
        upTimer.start(); 
        mCountUpList.set(getAdapterPosition(), upTimer); 
        break; 

       case R.id.checkBox: 
        mSelectedRows.set(getAdapterPosition(), 
          !mSelectedRows.get(getAdapterPosition())); 
        break; 
      } 
     } 

     @Override 
     public void OnTick(long elapsed) { 

      mTimeText.setText(elapsed + ""); 
     } 
    } 

} 

CountUpTimer.java

import android.os.Handler; 
import android.os.Message; 
import android.os.SystemClock; 

public class CountUpTimer { 

    private final long interval; 
    private long base; 
    public long mElapsedTime; 
    private OnTickListener onTickListener; 

    public CountUpTimer(long interval) { 
     this.interval = interval; 
    } 

    public void start() { 
     base = SystemClock.elapsedRealtime(); 
     handler.sendMessage(handler.obtainMessage(MSG)); 
    } 

    public void stop() { 
     handler.removeMessages(MSG); 
    } 

    public void reset() { 
     synchronized (this) { 
      base = SystemClock.elapsedRealtime(); 
     } 
    } 

    public void setOnTickListener(OnTickListener onTickListener) { 
     this.onTickListener = onTickListener; 
    } 

    private static final int MSG = 1; 

    private Handler handler = new Handler() { 

     @Override 
     public void handleMessage(Message msg) { 
      synchronized (CountUpTimer.this) { 
       long elapsedTime = SystemClock.elapsedRealtime() - base; 
       if (onTickListener != null) { 
        mElapsedTime = elapsedTime; 
        onTickListener.OnTick(elapsedTime); 
       } 
       sendMessageDelayed(obtainMessage(MSG), interval); 
      } 
     } 
    }; 

    interface OnTickListener { 
     void OnTick(long elapsed); 
    } 
} 
+0

を動作するかどうかを確認するためにそのことについては

if(countUpTimer != null) { holder.mTimeText.setText(elapsed + ""); } 

か、単に何かを設定してみてください を更新されるたびに、希望はこれが誰かhttpsのに役立ちます/github.com/saikiran91/Multiple-Timers-in-Recyclerview –

答えて

-1

ティonBindViewHolderで毎回holder.mTimeTextを更新していないために発生する可能性があります。つまり、あなたのコードが文に達していない:したがって、ビューはアイテムをリサイクルしています。 /:

  holder.mTimeText.setText(elapsed + ""); 

ビューは、それは私が解決策を自分で見つけ

関連する問題