我有一个recylerview,其项目包含两个textview(名称,时间),我有一个运行在不同线程上的计时器,每秒运行一次,我想更新我的特定项目的时间textview值名单。但由于数据量很大,我无法每秒在我的arraylist数据中添加计时器值。我应该如何将时间值传递给我的适配器并每秒刷新UI而不传递我的arraylist中的数据,通知适配器并依赖Bindview来刷新UI。
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 :(得分:1)
使计时器可观察并将其作为变量传递给绑定实例。 这将在计时器滴答(并调度更改事件)时正确更新这些行。 我还建议使用我们在github上发布的适配器,以便您的更新非常有效。
https://github.com/google/android-ui-toolkit-demos/tree/master/DataBinding/DataBoundRecyclerView
答案 1 :(得分:0)
我使用RxJava和RxAndroid找到了解决方案。我希望它可能会有所帮助。
我创建了一个包含名称的列表。您可以在名称处单击计时器。每个名称都有一个特定的计时器
我的活动如下:
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);
}
}
我的Adapter
。
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中看到完整的功能示例。