Java 从recycleview获取cardview中textview的值
我有一个回收视图,里面有卡片。每张卡都有一张公司和价格的清单 在我的onBindViewHolder中,我有一个单击事件,我想在该事件中获取Cardview中该行的TextView的价格 每次我点击时,我总是会得到单个卡片中最上面的物品的价值/价格,而不会得到我点击的物品的价格 bindData方法的data参数是我用来在Cardview中创建项目列表的参数 任何帮助都将不胜感激。我只需要在单击的位置获取正确文本视图的值Java 从recycleview获取cardview中textview的值,java,android,android-recyclerview,Java,Android,Android Recyclerview,我有一个回收视图,里面有卡片。每张卡都有一张公司和价格的清单 在我的onBindViewHolder中,我有一个单击事件,我想在该事件中获取Cardview中该行的TextView的价格 每次我点击时,我总是会得到单个卡片中最上面的物品的价值/价格,而不会得到我点击的物品的价格 bindData方法的data参数是我用来在Cardview中创建项目列表的参数 任何帮助都将不胜感激。我只需要在单击的位置获取正确文本视图的值 public class StockCardAdapter extends
public class StockCardAdapter extends RecyclerView.Adapter<StockCardAdapter.ViewHolder> {
public static class ViewHolder extends RecyclerView.ViewHolder {
protected RelativeLayout mCardBodyLayout;
protected TextView mTitleTextView;
public ViewHolder(View v) {
super(v);
mCardBodyLayout = (RelativeLayout) v.findViewById(R.id.card_body);
mTitleTextView = (TextView) v.findViewById(R.id.card_title);
}
public void bindData(StockCategoryModel data, Context ctx) {
this.mTitleTextView.setText(data.getCategoryName());
TableLayout tableLayout = new TableLayout(ctx);
int rows = data.getStockList().size();
for (int r = 0; r < rows; r++) {
TableRow row = new TableRow(ctx);
TableLayout.LayoutParams rowParams = new TableLayout.LayoutParams (TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
rowParams.setMargins(0, 0, 0, 16);
row.setLayoutParams(rowParams);
LinearLayout rl = new LinearLayout(ctx);
rl.setOrientation(LinearLayout.VERTICAL);
Integer priceColor = SharedUtilities.getColor(data.getStockList().get(r).priceChange, ctx);
//price row
LinearLayout priceLayout = new LinearLayout(ctx);
priceLayout.setOrientation(LinearLayout.HORIZONTAL);
priceLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
priceLayout.setWeightSum(4);
LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f);
final TextView price_text = new TextView(ctx);
price_text.setTag("priceTag");
price_text.setText(data.getStockList().get(r).price);
price_text.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
price_text.setTextColor(Color.BLACK);
price_text.setLayoutParams(textViewParams);
priceLayout.addView(price_text);
//company row
final TextView name_text = new TextView(ctx);
name_text.setText(data.getStockList().get(r).company);
name_text.setTextColor(Color.GRAY);
name_text.setLayoutParams( new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
name_text.setMaxWidth(700);
name_text.setEllipsize(TextUtils.TruncateAt.END);
name_text.setMaxLines(1);
name_text.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
rl.addView(priceLayout);
rl.addView(name_text);
row.addView(rl);
tableLayout.setStretchAllColumns(true);
tableLayout.addView(row);
}
mCardBodyLayout.addView(tableLayout);
}
}
private List<StockCategoryModel> mDataset;
private Context mContext;
// Constructor
public StockCardAdapter(List<StockCategoryModel> dataset, Context ctx) {
this.mDataset = dataset;
this.mContext = ctx;
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
// Create new views (invoked by the layout manager)
@Override
public StockCardAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup,
int viewType) {
// create a new view
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_layout, viewGroup, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v2) {
final TextView textViewName = (TextView) v2.findViewWithTag("priceTag"); ;
final String priceTag = textViewName.getText().toString();
}
});
holder.bindData(mDataset.get(position), mContext);
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.size();
}
}
textView的标记在所有情况下都是相同的,这就是它重复的原因,只有第一项的值。通常通过将priceTag与position连接来分配唯一标记。对代码进行如下更改:
public void bindData(StockCategoryModel data, Context ctx, int position) {
//All your code
//..
//...
final TextView price_text = new TextView(ctx);
price_text.setTag("priceTag"+String.valueOf(position));
}
在onBindViewHolder中:
final TextView textViewName = (TextView) v2.findViewWithTag("priceTag"+String.valueOf(position));
holder.bindData(mDataset.get(position), mContext,position);
从标记中查找子视图
请叫它
TextView priceTagTextView =(TextView)getViewsByTag(mCardBodyLayout, "priceTag").get(0);
private ArrayList<View> getViewsByTag(ViewGroup root, String tag){
ArrayList<View> views = new ArrayList<View>();
final int childCount = root.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = root.getChildAt(i);
if (child instanceof ViewGroup) {
getViewsByTag((ViewGroup) child, tag));
}
final Object tagObj = child.getTag();
if (tagObj != null && tagObj.equals(tag)) {
views.add(child);
}
}
return views;
}
您需要做的是分别为每一行设置一个单击侦听器 为什么总是得到第一行的值 这个代码
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v2) {
final TextView textViewName = (TextView) v2.findViewWithTag("priceTag"); ;
final String priceTag = textViewName.getText().toString();
}
});
为每个列表项(整个卡片)设置单击侦听器。这意味着,每当用户在卡视图边界内单击时,就会触发此回调。但是,谁会成为v2?它将始终是我们将侦听器设置为的视图—在本例中—整个卡片
这意味着每次调用v2.findViewWithTagpriceTag;您正在搜索整个卡的第一个子项,该子项具有标签priceTag,这是卡中的顶部项目
如何解决这个问题
如果您想确定正在单击哪个子级,则必须直接为每个子级设置一个单击侦听器
例如,请尝试以下代码,请参阅添加的注释:
public class StockCardAdapter extends
RecyclerView.Adapter<StockCardAdapter.ViewHolder> {
public static class ViewHolder extends RecyclerView.ViewHolder {
protected RelativeLayout mCardBodyLayout;
protected TextView mTitleTextView;
public ViewHolder(View v) {
super(v);
mCardBodyLayout = (RelativeLayout) v.findViewById(R.id.card_body);
mTitleTextView = (TextView) v.findViewById(R.id.card_title);
}
public void bindData(StockCategoryModel data, Context ctx, View.OnClickListener listener) {
this.mTitleTextView.setText(data.getCategoryName());
TableLayout tableLayout = new TableLayout(ctx);
int rows = data.getStockList().size();
for (int r = 0; r < rows; r++) {
TableRow row = new TableRow(ctx);
TableLayout.LayoutParams rowParams = new TableLayout.LayoutParams (TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
rowParams.setMargins(0, 0, 0, 16);
row.setLayoutParams(rowParams);
LinearLayout rl = new LinearLayout(ctx);
rl.setOrientation(LinearLayout.VERTICAL);
Integer priceColor = SharedUtilities.getColor(data.getStockList().get(r).priceChange, ctx);
//price row
LinearLayout priceLayout = new LinearLayout(ctx);
priceLayout.setOrientation(LinearLayout.HORIZONTAL);
priceLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
priceLayout.setWeightSum(4);
LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f);
final TextView price_text = new TextView(ctx);
price_text.setTag("priceTag");
price_text.setText(data.getStockList().get(r).price);
price_text.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
price_text.setTextColor(Color.BLACK);
price_text.setLayoutParams(textViewParams);
priceLayout.addView(price_text);
//company row
final TextView name_text = new TextView(ctx);
name_text.setText(data.getStockList().get(r).company);
name_text.setTextColor(Color.GRAY);
name_text.setLayoutParams( new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
name_text.setMaxWidth(700);
name_text.setEllipsize(TextUtils.TruncateAt.END);
name_text.setMaxLines(1);
name_text.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
rl.addView(priceLayout);
rl.addView(name_text);
row.addView(rl);
tableLayout.setStretchAllColumns(true);
tableLayout.addView(row);
// *ADDED* set the listener directly to each row
row.setOnClickListener(listener);
}
mCardBodyLayout.addView(tableLayout);
}
}
private List<StockCategoryModel> mDataset;
private Context mContext;
// Constructor
public StockCardAdapter(List<StockCategoryModel> dataset, Context ctx) {
this.mDataset = dataset;
this.mContext = ctx;
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
// Create new views (invoked by the layout manager)
@Override
public StockCardAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup,
int viewType) {
// create a new view
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_layout, viewGroup, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
// *ADDED* Send the callback to the bind method
holder.bindData(mDataset.get(position), mContext, new View.OnClickListener() {
@Override public void onClick(View v2) {
final TextView textViewName = (TextView) v2.findViewWithTag("priceTag"); ;
final String priceTag = textViewName.getText().toString();
}
}));
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.size();
}
}
注:
这不是处理RecyclerView的正确方法—在本例中,您永远不希望在数据绑定中创建新的对象new View.OnClickListener{}—这将降低性能。但这是另一个问题:这对我不起作用。我仍然有同样的问题。单击时,我的OnBindViewHolderTerry holder.getAdapterPosition中的position值始终为0,而不是在onBindViewHolder中作为参数传递position的position。让我知道这是否有效。我将相应地编辑answet,但这也不起作用。holder.getAdapterPosition在我单击时始终为0。我现在在应用程序冻结方面也遇到一些问题。是否有更好的地方进行onclickevent侦听器?我想知道将其放入onBindViewHolder是否会导致问题?请尝试将setHasStableIdstrue放入recyclerview构造函数中。一个更好的放置侦听器的地方是在您的Recyclerview支架内。这样做,看看它是否有效。一定要让我知道什么是有效的,因为我现在对此也很好奇看起来如果我在holder.itemView.setOnClickListener上放置一个断点,IDE就会冻结。我想我不会在这里设置断点;只返回卡中的第一个元素。我在onBindViewHolder中尝试了此操作,但单击时我的位置始终为0。我也在我的viewHolder中尝试了这个,但我不知道该设置什么。get0在那里。请检查它。这已更改为GetViewsByTag并检查ArrayList大小。当我尝试在viewholder中调用更新的代码时,我遇到了与以前相同的问题。当我在onBindViewHolder中尝试它时,我得到了IndexOutofBoundsCeptioni很抱歉,您可以将源代码上传到github上吗?这似乎很有效。非常感谢你。我现在没有时间,但会回来仔细复习,并标记答案。