更新recylerview中的值

时间:2016-06-15 13:16:40

标签: android data-binding android-recyclerview

我有一个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

    }
};

2 个答案:

答案 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中看到完整的功能示例。

项目网址:https://github.com/rodrigohenriques/rx-timer-list