【问题标题】:Update text within card view list?更新卡片视图列表中的文本?
【发布时间】:2015-06-09 00:33:01
【问题描述】:

所以我有一个卡片视图的 recyclerview 列表。我试图在用户单击卡片时更新每个视图中的文本时间文本,然后在时间过去时将其重置回来。我在 recyclerviewadapter 中设置了一个内部方法,但是当我调用 updateTimes(从片段调用)时,它不会重置文本。有人可以指导我做错了什么吗?

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;
}

}

片段代码

@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();
}

【问题讨论】:

  • 再看一下,您似乎正在使用共享首选项来检索您更新的文本。在您的 setRenewal 方法中,您将获得首选项,对其进行编辑并放置字符串。但是您没有应用 apply() 或 commit() 它以便更新您的共享偏好。
  • 谢谢。更新代码和新问题
  • 新问题是什么?
  • UpdateTimes 方法现在不起作用。
  • 您可以编辑和添加您的片段代码吗?我想看看我是否可以重现这个问题,也许可以让它更简单。

标签: android android-fragments android-cardview android-recyclerview


【解决方案1】:

notifyDataSetChanged 应该作为最后的手段使用,因为它没有指定发生了什么,因此适配器假定没有任何东西是有效的,这导致列表不仅重新绑定,而且重新布局所有可见视图。您应该改用 notifyItem[Range][Inserted|Changed|Removed]() 方法之一,在您的情况下,notifyItemChanged(int position) 可以。

updateText() 中编辑文本,但不要将结果存储在任何字段中。然后稍后,将调用bindViewHolder(),它调用setText(getTime()) 并将文本重置为其先前的值。这可能就是为什么没有任何变化的原因。您应该向 ViewHolder 添加一个方法,该方法首先存储结果,然后调用 TextView.setText()。

如果您的 onClick() 从未被调用,您可能需要检查您是否已在其布局文件中设置了可聚焦和可点击的视图。

这是我在 StackOverflow 上的第一个 awnser,英语不是我的第一语言,如果我输入错误,请见谅。

【讨论】:

    【解决方案2】:

    两件事,

    • 我实际上并没有看到您的updateText 被调用的位置。
    • 您应该调用notifyDataSetChanged() 来更新适配器,让您的适配器重新绘制列表。

    我添加了一个简单的回收器视图,并在 textView 中添加了一个侦听器。它应该在你调用文本更新然后调用notifyDataSetChanged() 后工作,见下文

    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!");
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-08
      • 1970-01-01
      相关资源
      最近更新 更多