繁体   English   中英

从recycleview获取cardview中的textview的值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM