【问题标题】:Adding a button to a card with the RecyclerView pattern使用 RecyclerView 模式向卡片添加按钮
【发布时间】:2014-12-27 20:22:40
【问题描述】:

根据Creating Lists and Cards 和 RecyclerView 模式,我实现了一个显示一系列项目的卡片的活动。我希望每张卡片都有一个按钮,可以弹出该项目的选项对话框:

如您所见,每张卡片的右上角都有一个按钮。我已经这样实现了:

CardViewHolder.java:

public class CardViewHolder extends RecyclerView.ViewHolder {
    protected TextView itemTitle;
    protected TextView itemCode;
    protected TextView itemDate;
    protected TextView itemStatus;
    protected Button optionsButton;
    public CardViewHolder(View v) {
        super(v);
        itemTitle = (TextView) v.findViewById(R.id.itemTitle);
        itemCode = (TextView) v.findViewById(R.id.itemCode);
        itemStatus = (TextView) v.findViewById(R.id.itemStatus);
        itemDate = (TextView) v.findViewById(R.id.itemDate);
        optionsButton = (Button) v.findViewById(R.id.options_button);
    }
}

然后,实现了在我的 RecyclerView 活动中设置的 DataAdapter:

DataAdapter.java:

public class DataAdapter extends RecyclerView.Adapter<CardViewHolder>{
    private JSONArray mDataSet;
    private Context mContext;

    //constructor
    public DataAdapter(JSONArray myDataSet, Context c) {
        mContext = c;
        mDataSet = myDataSet;
    }
    //creates new views (invoked by the layout manager)
    @Override
    public CardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //create a new view
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_text_view, parent, false);
        //set the view's size, margins, padding and layout parameters
        CardViewHolder vh = new CardViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(CardViewHolder holder, int position) {
        //get element from dataset at position
        //replace the contets of the view with that element
        String title,itemCode,itemStatus, itemDate;
        title = itemCode = itemDate = itemStatus = "";
        try {
            JSONObject item = new JSONObject(mDataSet.get(position).toString());
            title = item.getString("desc");
            itemCode = item.getString("code");
            itemDate = item.getString("date");
            itemStatus = item.getString("status");

        } catch (JSONException e) {
            e.printStackTrace();
        }
        holder.itemTitle.setText(title);
        holder.itemCode.setText(itemCode);
        holder.itemDate.setText(itemDate);
        holder.itemStatus.setText(Html.fromHtml(itemStatus));
        holder.optionsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(mContext,title,Toast.LENGTH_LONG).show();
            }
        });
    }

    @Override
    public int getItemCount() {
        return mDataSet.length();
    }

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView mTextView;
        public ViewHolder(TextView v) {
            super(v);
            mTextView = v;
        }
    }
}

我对此的问题和想法是:

  • 我如何通过这个按钮 onClick 监听这个项目的值?例如,尝试从 onClick 处理程序中访问 title 是错误的,因为它不是最终变量,而是从内部类中访问的。另一方面,如果我让我的 DataAdapter 类实现 View.onClickListener 接口,我仍然不确定如何从 onClick 方法中获取这些项目特定的值。

  • 这是否被认为是一种好的做法? (将应用程序上下文传递给我的 DataAdapter)?我应该从另一个角度攻击这个吗?

【问题讨论】:

    标签: android android-recyclerview


    【解决方案1】:

    您可以轻松地使您的适配器实现 View.OnClickListener 或实现您自己的实现 OnClickListener 并具有您可以设置的文本参数的类...

    static class MyClick implements View.OnClickListener{
    
        String text
        /**
         * Called when a view has been clicked.
         *
         * @param v The view that was clicked.
         */
        @Override
        public void onClick (View v) {
    
        }
    } 
    
     MyClick click = new MyClick();
     click.text = text;
     holder.button.setOnClickListener(click);
    

    另外你为什么要传递 ApplicationContext 而不是活动上下文?适配器已“绑定”到活动。

    使您不将上下文传递给适配器的更好解决方案是使用侦听器,使您的片段/活动实现侦听器并运行 onClick 方法。例如:

    @适配器:

    public interface MyAdapterListener {
        public void onCLick(String text);
    }
     private MyAdapterListener mListener;
     ...
    
     void onClick(){
         mListener.onCLick(text)
     }
    

    【讨论】:

    • 我不需要对实现接口的活动进行某种引用吗? mListener.onClick(text); 抛出 NullPointerException..
    • 实例化适配器时,将监听器分配给实现者,通常是活动或片段。它是 android 中的常规设计模式
    • 是的,但这正是我的问题。如果我使用另一个类来保存文本字符串,它就无法访问活动侦听器。如果我让适配器本身实现 View.OnClickListener 我看不到如何传递字符串。 ://
    • 当然有,只要在callable中传递字符串
    • 别担心,如果您需要更多帮助,请告诉我,现在我该睡觉了(:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    • 2016-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多