Update text within card view list?

筅森魡賤 提交于 2020-01-02 18:23:13

问题


So I have a recyclerview list of card views.I am trying to update the text time text in each view when the user clicks the card, and then reset it back when time has past. I set up an internal method in recyclerviewadapter but when I call updateTimes (calling from fragment), it does not reset the text back. Can someone instruct me on what I'm doing wrong?

import java.util.ArrayList;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.net.Uri;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
 import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;
import java.util.Calendar;
import android.content.Intent;
import java.text.SimpleDateFormat;
import java.util.Locale;


public class RecyclerAdapter extends RecyclerView.Adapter<FaucetHolder> {
    private ArrayList<Faucet> faucets;
    private Context context;
    private SharedPreferences sharedPref;
    private String dateFormat = "h:mm a";
    public    RecyclerAdapter(ArrayList<Faucet> faucetsI, Context context) {
    this.faucets = faucetsI;
    this.context = context;


}

@Override
public FaucetHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_view, viewGroup, false);
    FaucetHolder f = new FaucetHolder(v);
    return f;
}

@Override
public void onBindViewHolder(FaucetHolder f, int k) {
    final Faucet faucet = faucets.get(k);
    f.titleText.setOnClickListener(new View.OnClickListener() {
            public void onClick(View btn) {
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(faucet.getLink()));
                setRenewal(faucet);
                notifyDataSetChanged();
                context.startActivity(intent);
            }
        });
    f.titleText.setText(faucet.getName());
    sharedPref = context.getSharedPreferences("myPref", 0);
    String time = sharedPref.getString(faucet.getSPName(), "could not retrieve time");
    Log.e("tree", time);
    f.timeText.setText(time);

}

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



private void setRenewal(Faucet g) {
    sharedPref = context.getSharedPreferences("myPref", 0);
    SharedPreferences.Editor edit = sharedPref.edit();
    Calendar c = Calendar.getInstance();
    long current = c.getTimeInMillis();
    String x = sharedPref.getString(g.getSPName(), null);

    long future = current + g.getLength();
    g.setCT(future);
    c.setTimeInMillis(future);
    SimpleDateFormat df = new SimpleDateFormat(dateFormat, Locale.US);
    String date = df.format(c.getTime());

    edit.putString(g.getSPName(), date).commit();

}


public void updateTimes() {
    sharedPref = context.getSharedPreferences("myPref", 0);
    SharedPreferences.Editor edit = sharedPref.edit();
    for ( Faucet f : faucets ) {
        boolean m = checkifPast(f);
        if ( m == true ) {
            edit.putString(f.getSPName(), "Ready!").commit();
        }
    }
    notifyDataSetChanged();
}

private boolean checkifPast(Faucet f) {
    Calendar c = Calendar.getInstance();
    long comp = c.getTimeInMillis();
    if ( comp > f.getCT() ) {
        return false;
    }
    return true;
}

}

Fragment Code

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{

    v = inflater.inflate(R.layout.faucetcards, container, false);
    r = (RecyclerView) v.findViewById(R.id.RecyclerView);
    rA = new RecyclerAdapter(generateCards(), getActivity());
    lm = new LinearLayoutManager(getActivity());
    r.setAdapter(rA);
    r.setLayoutManager(lm);

    sharedPref = getActivity().getPreferences(0);
    return v;
}


@Override
public void onResume()
{
    rA.updateTimes();
    super.onResume();
}

回答1:


notifyDataSetChanged should be used as a last resort, since it does not specify what has happened and therefore the adapter asumes nothing is valid anymore, which causes the list to not only rebind, but also relayout all visible views. You should instead use one of the notifyItem[Range][Inserted|Changed|Removed]() methods instead, in your case notifyItemChanged(int position) will do.

In updateText() you edit the text, but don't store the result in any field. Then later, bindViewHolder() will be called, which calls setText(getTime()) and resets the text to its previous value. That is probably why nothing changes. You should add a method to your ViewHolder which first stores the result and then calls TextView.setText().

If your onClick() is never called, you might want to check that you have set the view focusable and clickable in its layout-file.

This is my first awnser on StackOverflow and English is not my first language, so excuse me if I typed something wrong.




回答2:


Two things,

  • I am not actually seeing where your updateText is being called.
  • You should call notifyDataSetChanged() to update the adapter to have your adapter redraw the list.

I added a simple recycler view and I added a listener to a textView. It should work after you call the text update and then call notifyDataSetChanged(), see below

public class MyRecyclerAdapter extends RecyclerView.Adapter<FeedListRowHolder> {

    private List<FeedItem> feedItemList;
    private Context mContext;

    public MyRecyclerAdapter(Context context, List<FeedItem> feedItemList) {
        this.feedItemList = feedItemList;
        this.mContext = context;
    }

    @Override
    public FeedListRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_row, null);
        FeedListRowHolder mh = new FeedListRowHolder(v);
        return mh;
    }

    @Override
    public void onBindViewHolder(FeedListRowHolder feedListRowHolder, int i) {
        final FeedItem feedItem = feedItemList.get(i);

        feedListRowHolder.title.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                updateText(feedItem);
                notifyDataSetChanged();
            }
        });
        Picasso.with(mContext).load(feedItem.getThumbnail())
            .error(R.drawable.placeholder)
            .placeholder(R.drawable.placeholder)
            .into(feedListRowHolder.thumbnail);

        feedListRowHolder.title.setText(Html.fromHtml(feedItem.getTitle()));
    }

    @Override
    public int getItemCount()
    {
        return (null != feedItemList ? feedItemList.size() : 0);
    }

    private void updateText(FeedItem feedItem)
    {
        feedItem.setTitle("TEST!");
    }
}


来源:https://stackoverflow.com/questions/30688651/update-text-within-card-view-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!