从回收站视图获取原始项目。

huangapple go评论59阅读模式
英文:

Getting original Item from Recycler View?

问题

我已经完成了学习如何实现RecyclerView这个复杂任务。我的RecyclerView正确地显示了提供的ArrayList中的信息,并且根据新的添加进行了更新。

问题:这些单独的项代表着我FireBase数据库中的一个条目。数据库中的每个条目都有自己独特的ID,当然。然而,当我实现一个onClickListener()来能够按下这些项以获得更多信息,以根据数据库在屏幕上显示时,我为视图持有者分配的项目ID仅与视图持有者的位置一致,而不是分配的ArrayList。这反过来导致我的对象一次又一次地引用相同的ID,这取决于我为其分配的ScrollView在RecyclerView的哪个部分中。我如何将所点击视图的位置转换为它在原始ArrayList中正确的对象表示?

原谅我的代码,我刚开始学习Java,很难理解这个RecyclerView。在代码中,你会发现许多我试图为每个单独的视图实例分配适当ID的多余内容。

OrderAdapter

public class OrderAdapter extends RecyclerView.Adapter<OrderAdapter.OrderViewHolder> {

    private ArrayList<Order> orderList;
    private Context context;
    private View.OnClickListener clickListener;
    private HashMap<Integer, OrderViewHolder> holderlist;

    public OrderAdapter(Context context, ArrayList<Order> orderList){
        this.orderList = orderList;
        this.context = context;
        holderlist = new HashMap<>();
    }

    @NonNull
    @Override
    public OrderViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.order_list, parent, false);
        RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        view.setLayoutParams(lp);
        Log.e("VIEW HOLDER", "VIEW CREATED");

        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                clickListener.onClick(view);
            }
        });

        return new OrderViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull OrderViewHolder holder, int position) {
        holderlist.put(position, holder);

        Order order = orderList.get(position);
        holder.text.setText(order.getOrderText());
        holder.getOrder().setOrderID(orderList.get(position).getOrderID());

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                clickListener.onClick(view);
            }
        });

        if(order.getOrderStatus().equals("ACCEPTED")) {
            holder.text.setBackgroundResource(R.drawable.rounded_corner_green);
        } else {
            holder.text.setBackgroundResource(R.drawable.rounded_corner_white);
        }

        holderlist.put(position, holder);
    }

    @Override
    public int getItemCount() {
        return orderList.size();
    }

    public void setClickListener(View.OnClickListener callback) {
        clickListener = callback;
    }

    public OrderViewHolder returnHolderByPosition(int position){
        return holderlist.get(position);
    }

    public class OrderViewHolder extends RecyclerView.ViewHolder{

        public TextView text;
        public Order order;

        public OrderViewHolder(@NonNull View itemView) {
            super(itemView);
            text = (TextView) itemView;
            order = new Order();
        }

        public void setOrder(Order order){
            this.order = order;
        }

        public Order getOrder(){
            return order;
        }
    }
}

在我的Activity中的实现

orderActiveAdapter.setClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        int pos = cardActive.indexOfChild(view);
        OrderAdapter.OrderViewHolder holder = orderActiveAdapter.returnHolderByPosition(pos);
        int orderID = holder.getOrder().getOrderID();
        Log.e("ORDER ID ", Integer.toString(orderID));
    }
});
英文:

I have gone through the very convoluted task of learning how to implement a Recycler View. My recycler view is properly displaying the information from the ArrayList provided and updating according to new additions.

The issue : These individual items are meant to represent an item in my FireBase database. Each entry in the database has its own unique ID of course. However on implementing an onClickListener() to be able to press these items to obtain more information to be displayed on screen according to the database, the Item ID I am assigning the view holder is only consistent with the position of the view holder, not the assigned ArrayList. This in turn has my objects referencing the same ID over and over depending on what part of the RecyclerView the ScrollView I assigned it is located. How do I convert the position of the view clicked to its proper object representation in the original ArrayList?

Forgive my code, I am new to learning Java and it is very difficult to understand this recycler View. In it you will find a bunch of redundant stuff from my attempts at assigning the proper ID to each individual view instance.

Order Adapter

 public class OrderAdapter extends RecyclerView.Adapter&lt;OrderAdapter.OrderViewHolder&gt; {
private ArrayList&lt;Order&gt; orderList;
private Context context;
private View.OnClickListener clickListener;
private HashMap&lt;Integer, OrderViewHolder&gt; holderlist;
public OrderAdapter(Context context, ArrayList&lt;Order&gt; orderList){
this.orderList = orderList;
this.context = context;
holderlist = new HashMap&lt;&gt;();
}
@NonNull
@Override
public OrderViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.order_list, parent, false);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
//View view = new TextView(context);
//View rootView = LayoutInflater.from(context).inflate(R.layout.order_list, parent, false);
Log.e(&quot;VIEW HOLDER&quot;, &quot;VIEW CREATED&quot;);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
clickListener.onClick(view);
}
});
return new OrderViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull OrderViewHolder holder, int position) {
holderlist.put(position,holder);
Order order = orderList.get(position);
holder.text.setText(order.getOrderText());
holder.getOrder().setOrderID(orderList.get(position).getOrderID());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
clickListener.onClick(view);
}
});
if(order.getOrderStatus().equals(&quot;ACCEPTED&quot;)) {
holder.text.setBackgroundResource(R.drawable.rounded_corner_green);
}
else{
holder.text.setBackgroundResource(R.drawable.rounded_corner_white);
}
holderlist.put(position,holder);
}
@Override
public int getItemCount() {
return orderList.size();
}
public void setClickListener(View.OnClickListener callback) {
clickListener = callback;
}
public OrderViewHolder returnHolderByPosition(int position){
return holderlist.get(position);
}
public class OrderViewHolder extends RecyclerView.ViewHolder{
public TextView text;
public Order order;
public OrderViewHolder(@NonNull View itemView) {
super(itemView);
text = (TextView) itemView;
order = new Order();
}
public void setOrder(Order order){
this.order = order;
}
public Order getOrder(){
return order;
}
}

My Implementation in my Activity

 orderActiveAdapter.setClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int pos = cardActive.indexOfChild(view);
OrderAdapter.OrderViewHolder holder = orderActiveAdapter.returnHolderByPosition(pos);
int orderID = holder.getOrder().getOrderID();
Log.e(&quot;ORDER ID &quot;, Integer.toString(orderID));
}
});

答案1

得分: 1

不需要使用视图来获取点击位置,您只需调整监听器的实现方式。
创建一个监听器,在回收视图中的任何项目上单击以获取数据。需要在此处删除监听器-

从onCreateViewHolder中删除监听器,并在onBindViewholder或嵌套类内部实现监听器。

调整后的代码如下-

public class OrderAdapter extends RecyclerView.Adapter<OrderAdapter.OrderViewHolder> {

    private ArrayList<Order> orderList;
    private Context context;
    private HashMap<Integer, OrderViewHolder> holderlist;
    
    // 添加此监听器以从回收视图传递数据到活动/片段
    private OrderSelectListener orderSelectListener;

    public OrderAdapter(Context context, ArrayList<Order> orderList){
        this.orderList = orderList;
        this.context = context;
        holderlist = new HashMap<>();
    }
    
    // 创建一个接口
    public interface OrderSelectListener{
        void onOderClick(Order order, int position);
    }
    
    // 为将实现此监听器的活动/片段创建一个方法
    public void setOrderClickListener(OrderSelectListener orderSelectListener){
        this.orderSelectListener = orderSelectListener;
    }
}

    @NonNull
    @Override
    public OrderViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.order_list, parent, false);
        RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        view.setLayoutParams(lp);
        //View view = new TextView(context);
        //View rootView = LayoutInflater.from(context).inflate(R.layout.order_list, parent, false);
        Log.e("VIEW HOLDER", "VIEW CREATED");
        return new OrderViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull OrderViewHolder holder, int position) {
        holderlist.put(position,holder);
        Order order = orderList.get(position);
        holder.text.setText(order.getOrderText());
        if(order.getOrderStatus().equals("ACCEPTED")) {
            holder.text.setBackgroundResource(R.drawable.rounded_corner_green);
        }
        else{
            holder.text.setBackgroundResource(R.drawable.rounded_corner_white);
        }

        // 将Order和Position作为参数传递给接口方法
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                orderSelectListener.onOrderClick(orderList.get(position),position);
            }
        });

    }

    @Override
    public int getItemCount() {
        return orderList.size();
    }

    public class OrderViewHolder extends RecyclerView.ViewHolder{

        public TextView text;
        public View itemView;
        public Order order;

        public OrderViewHolder(@NonNull View itemView) {
            super(itemView);
            text = (TextView) itemView;
            order = new Order();
            this.itemView = itemView;
        }

        public void setOrder(Order order){
            this.order = order;
        }

        public Order getOrder(){
            return order;
        }
}

在您的活动/片段中实现此(OrderSelectListener)监听器,如下所示-

orderActiveAdapter.setOrderClickListener(new OrderAdapter.OrderSelectListener() {
    @Override
    public void onOrderClick(Order order, int position) {
        // 在这里执行一些令人惊奇的操作

    }
});

愉快的编码
英文:

No need to use view to get click position, you simply need to adjust the implementation of listener.
Create a listener to get data onClick of any item in recycle view. Need to remove the listener here-

@NonNull
@Override
public OrderViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.order_list, parent, false);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
//View view = new TextView(context);
//View rootView = LayoutInflater.from(context).inflate(R.layout.order_list, parent, false);
Log.e(&quot;VIEW HOLDER&quot;, &quot;VIEW CREATED&quot;);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
clickListener.onClick(view);
}
});
return new OrderViewHolder(view);
}

Remove listener from onCreateViewHolder, and implement the listener in either onBindViewholder or inside nested class.

Adjusted Code as follow-

public class OrderAdapter extends RecyclerView.Adapter&lt;OrderAdapter.OrderViewHolder&gt; {
private ArrayList&lt;Order&gt; orderList;
private Context context;
private HashMap&lt;Integer, OrderViewHolder&gt; holderlist;
//Add this Listener to pass data from recycle view to activity/fragment
private OrderSelectListener orderSelectListener;
public OrderAdapter(Context context, ArrayList&lt;Order&gt; orderList){
this.orderList = orderList;
this.context = context;
holderlist = new HashMap&lt;&gt;();
}
//Create an interface
public interface OrderSelectListener{
void onOderClick(Order order, int position);
}
//create a method for the activity/fragment which will implement this listener
public void setOrderClickListener(OrderSelectListener orderSelectListener){
this.orderSelectListener = orderSelectListener;
}
}
@NonNull
@Override
public OrderViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.order_list, parent, false);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
//View view = new TextView(context);
//View rootView = LayoutInflater.from(context).inflate(R.layout.order_list, parent, false);
Log.e(&quot;VIEW HOLDER&quot;, &quot;VIEW CREATED&quot;);
return new OrderViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull OrderViewHolder holder, int position) {
holderlist.put(position,holder);
Order order = orderList.get(position);
holder.text.setText(order.getOrderText());
if(order.getOrderStatus().equals(&quot;ACCEPTED&quot;)) {
holder.text.setBackgroundResource(R.drawable.rounded_corner_green);
}
else{
holder.text.setBackgroundResource(R.drawable.rounded_corner_white);
}
// passing Order and Position as parameter to interface method,
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
orderSelectListener.onOrderClick(orderList.get(position),position);
}
});
}
@Override
public int getItemCount() {
return orderList.size();
}
public class OrderViewHolder extends RecyclerView.ViewHolder{
public TextView text;
public View itemView;
public Order order;
public OrderViewHolder(@NonNull View itemView) {
super(itemView);
text = (TextView) itemView;
order = new Order();
this.itemView = itemView;
}
public void setOrder(Order order){
this.order = order;
}
public Order getOrder(){
return order;
}
}

In your activity/fragment implement this(OrderSelectListener) listener, as following-

orderActiveAdapter.orderSelectListener(new OrderAdapter.OrderSelectListener() {
@Override
public void onOrderClick(Order order, int position) {
//do something amazing here
}
});

Happy Coding!!

huangapple
  • 本文由 发表于 2020年7月27日 22:13:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/63117196.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定