[英]Get value of textview in cardview from recycleview
我有一個RecycleView
,里面有卡。 每張卡都有公司和價格的列表。
在我的onBindViewHolder
我有一個click事件,我想在Cardview
那一行中獲取TextView
的價格。
每次我單擊時,我總是會得到單個卡內最上面物品的價格/價格,而永遠不會得到我所點擊物品的價格。
bindData
方法的數據參數是我用來在Cardview
內創建項目列表的東西。
任何幫助將不勝感激。 我只需要獲取我單擊的正確TextView
的值。
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();
}
}
您需要做的是將點擊偵聽器分別設置到每一行。
為什么總是得到第一行的值?
此代碼,
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.findViewWithTag("priceTag");
您正在搜索帶有“ priceTag”標簽的整個卡片的第一個子代,該標簽是卡片中的“ top”項目。
如何解決這個問題?
如果要確定正在點擊哪個孩子,則必須直接為每個孩子設置點擊監聽器。
作為示例,請嘗試以下代碼(請參閱添加的注釋):
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() {}
),這會降低性能。 但這是另一個問題:)
在所有情況下,textView的標簽都是相同的,這就是為什么它重復的原因,僅是第一項的值。 通常,通過將"priceTag"
與位置連接來分配唯一的標簽。 在代碼中進行如下更改:
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);
從Tag查找子視圖,請調用它。
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.