2016-06-15 10 views
2

私は、2つのtextview(Name、Time)を含む項目を持つrecylerviewを持っています。毎秒実行される別のスレッドでタイマーを実行しています。 。しかし、大きなデータのために、毎秒私のarraylistデータにタイマー値を追加することはできません。アダプタに通知し、UIを更新するためにBindviewに頼ることなく、どのように私のアダプタに時間値を渡し、毎秒UIをリフレッシュするべきですか?recylerviewの値を更新する

public class MyListAdapter extends RecyclerView.Adapter<MyListAdapter.ContactViewHolder> 
{ 
public ArrayList<Users> data; 
private Context context; 

public MyListAdapter(ArrayList<Users> dataList, Context context) 
{ 
    this.data = dataList; 
    this.context = context; 

} 

@Override 
public ContactViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
{ 
    View itemView = LayoutInflater. 
      from(parent.getContext()). 
      inflate(R.layout.card_layout, parent, false); 

    return new ContactViewHolder(itemView); 
} 

@Override 
public void onBindViewHolder(ContactViewHolder holder, int position) 
{ 
    Users user = data.get(position); 
    holder.name.setText(user.getName()); 
    holder.time.setText("00:00"); 
} 

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



class ContactViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener 
{ 

    TextView name, time; 

    public ContactViewHolder(View v) 
    { 
     super(v); 
     name = (TextView) v.findViewById(R.id.card_layout_name_txt); 
     time = (TextView) v.findViewById(R.id.card_layout_time_txt); 

    } 

} 
} 





recyclerView = (RecyclerView) findViewById(R.id.fragment_recyclerview); 
recyclerView.setHasFixedSize(true); 
recyclerView.setAdapter(adapter); 
LinearLayoutManager manager=new LinearLayoutManager(context,LinearLayoutManager.VERTICAL,false); 
recyclerView.setLayoutManager(manager); 





    myTimer = new Timer(); 
    myTimer.schedule(new TimerTask() 
    { 
     @Override 
     public void run() 
     { 
      TimerMethod(); 
     } 

    }, 0, 1000); 


private void TimerMethod() 
{ 

    this.runOnUiThread(Timer_Tick); 
} 

public Runnable Timer_Tick = new Runnable() 
{ 
    public void run() 
    { 
    // want to update time in specific item in recylerview 

    } 
}; 
+0

あなたはすべての行で同じ時間を表示するために持っているか、それは異なる時間ですか? –

+0

私の答えをチェックしてください! –

+0

@MalithLakshanは1つのアイテムだけでタイマーを実行し、他のアイテムは何も表示しません。タイマーの開始と停止のアクションは、そのアイテムをクリックすることになります。 –

答えて

0

私はRxJavaとRxAndroidを使用して解決策を見つけました。役に立つと願っています。

名前のリストを作成しました。あなたは名前でクリックしてタイマーを開始します。各名前には1つの特定のタイマーがあります。

私の活動は、次のようになります。私のAdapterをそこに行く

public class MainActivity extends AppCompatActivity { 
    private RecyclerView recyclerView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     recyclerView = (RecyclerView) findViewById(R.id.recyclerView); 
     recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); 
     recyclerView.setAdapter(buildAdapter()); 
    } 

    private RecyclerView.Adapter buildAdapter() { 
     List<String> names = new ArrayList<>(); 

     names.add("Rodrigo"); 
     names.add("Magno"); 
     names.add("Lucas"); 
     names.add("Henrique"); 
     names.add("Marcelo"); 
     names.add("Nadilson"); 
     names.add("Rafael"); 
     names.add("Walmyr"); 
     names.add("Haroldo"); 
     names.add("Samir"); 
     names.add("Eugênio"); 
     names.add("Leonardo"); 
     names.add("Maurício"); 
     names.add("Júlio"); 

     return new Adapter(this, names); 
    } 
} 

public class Adapter extends RecyclerView.Adapter<Adapter.CustomViewHolder> { 
    private final static String TAG = Adapter.class.getSimpleName(); 

    private final List<String> items; 
    private final PublishSubject<Event> publishSubject = PublishSubject.create(); 
    private final Map<String, Subscription> subscriptions; 
    private final Context context; 

    public Adapter(Context context, List<String> items) { 
     this.context = context; 
     this.items = items; 
     this.subscriptions = new HashMap<>(); 
    } 

    @Override 
    public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     final View itemView = LayoutInflater.from(context).inflate(R.layout.holder_layout, parent, false); 
     return new CustomViewHolder(itemView); 
    } 

    @Override 
    public void onBindViewHolder(CustomViewHolder holder, int position) { 
     String name = items.get(position); 
     holder.bind(name); 
    } 

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

    class CustomViewHolder extends RecyclerView.ViewHolder { 
     private TextView textViewName, textViewTimer; 
     private Subscription tempSubscription; 

     public CustomViewHolder(View itemView) { 
      super(itemView); 

      textViewName = (TextView) itemView.findViewById(R.id.textViewName); 
      textViewTimer = (TextView) itemView.findViewById(R.id.textViewTime); 
     } 

     private void bind(String name) { 
      textViewName.setText(name); 

      if (tempSubscription != null) 
       tempSubscription.unsubscribe(); 

      tempSubscription = publishSubject 
        .filter(event -> event.getName().equals(name)) 
        .map(event -> event.getElapsedTime()) 
        .map(elapsedTime -> String.format("%ds", elapsedTime)) 
        .observeOn(AndroidSchedulers.mainThread()) 
        .subscribe(formattedElapsedTime -> textViewTimer.setText(formattedElapsedTime), Adapter.this::handleError); 

      itemView.setOnClickListener(v -> { 
       Subscription subscription = subscriptions.get(name); 

       if (subscription == null || subscription.isUnsubscribed()) { 
        subscription = startTimer(name); 
        subscriptions.put(name, subscription); 
       } else { 
        subscription.unsubscribe(); 
        textViewTimer.setText("0s"); 
       } 
      }); 
     } 

     private Subscription startTimer(String name) { 
      return Observable.interval(1, TimeUnit.SECONDS, Schedulers.io()) 
        .onBackpressureDrop() 
        .map(milliseconds -> new Event(name, milliseconds)) 
        .subscribe(publishSubject::onNext, Adapter.this::handleError); 
     } 
    } 

    private void handleError(Throwable t) { 
     Log.e(TAG, "failure listening events", t); 
    } 
} 

と私のEvent

public class Event { 
    private String name; 
    private Long elapsedTime; 

    public Event(String name, Long elapsedTime) { 
     this.name = name; 
     this.elapsedTime = elapsedTime; 
    } 

    public String getName() { 
     return name; 
    } 

    public Long getElapsedTime() { 
     return elapsedTime; 
    } 
} 

フル機能例はmy Githubです。

プロジェクトURL:https://github.com/rodrigohenriques/rx-timer-list

1

タイマーが観察作り、あなたの結合インスタンスに変数として渡します。 これは、これらの行をタイマーティックとして適切に更新します(そして、変更イベントをディスパッチします)。 githubでリリースしたアダプタを使用して、アップデートが非常に効率的に行われるようにすることもお勧めします。

https://github.com/google/android-ui-toolkit-demos/tree/master/DataBinding/DataBoundRecyclerView

関連する問題