【问题标题】:Strange behaviour of listview position onlicklistenerlistview位置onlicklistener的奇怪行为
【发布时间】:2017-04-08 09:00:47
【问题描述】:

我有一个列表视图,显示某家餐厅的食品订单。当用户单击其中一个列表视图项目时,它应该显示所单击项目的位置以及食品订单的订单 ID。由于某种原因,显示了错误的位置。

PendingOrders.java。数据从 firebase 加载

public class PendingOrders extends AppCompatActivity {

private DatabaseReference mDatabase;
ArrayList<OrderDetails> activeorders = new ArrayList<OrderDetails>();
private OrdersAdapter adapter;
ListView listview;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_pending_orders);
    listview = (ListView)findViewById(R.id.pendinglistview);
    adapter = new OrdersAdapter(this,activeorders);
    listview.setAdapter(adapter);


    ValueEventListener listen = new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            OrderDetails order = dataSnapshot.getValue(OrderDetails.class);
            String str = order.UserId;

            if (str.equals("abc")) {
                boolean add = true;
                for (int i = 0; i < activeorders.size(); i++) {
                    String checking = activeorders.get(i).OrderId;
                    if (checking.equals(order.OrderId)) {
                        add = false;
                    }
                }

                if (add = true) {
                    activeorders.add(order);
                    ((OrdersAdapter) listview.getAdapter()).notifyDataSetChanged();
                }

            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {

        }

    };



    for (int i=1; i<=4;i++) {
        mDatabase = FirebaseDatabase.getInstance().getReference().child("Active Orders")
                .child(Integer.toString(i));
        mDatabase.addValueEventListener(listen);
    }



}

}

OrdersAdapter.java

public class OrdersAdapter extends BaseAdapter {

Context context;
ArrayList<OrderDetails> activeorders;
Button confirmationbutton;

public OrdersAdapter(Context context, ArrayList<OrderDetails> activeorders){
    this.context = context;
    this.activeorders = activeorders;
}

@Override
public int getCount() {
    return  activeorders.size() ;
}

@Override
public Object getItem(int position) {
    return activeorders.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, final ViewGroup parent) {

    ViewHolder viewHolder = null;

    if (convertView == null) {

        LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

        viewHolder = new ViewHolder();

        convertView = layoutInflater.inflate(R.layout.orderlistview, null);

        viewHolder.mdtitle = (TextView) convertView.findViewById(R.id.mdtitle);
        confirmationbutton = (Button) convertView.findViewById(R.id.confirmationbutton);
        confirmationbutton.setTag(position);
        viewHolder.switchbutton = (MultiStateToggleButton) convertView.findViewById(R.id.mstb_multi_id);
        viewHolder.switchbutton.setElements(R.array.planets_array,0);
        Typeface font = Typeface.createFromAsset(context.getAssets(), "fonts/Lato-Semibold.ttf");

        viewHolder.mdtitle.setTypeface(font);

        convertView.setTag(viewHolder);


    } else {

        viewHolder = (ViewHolder) convertView.getTag();


    }

    confirmationbutton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Integer pos = (Integer)v.getTag();
            OrderDetails orders = (OrderDetails)getItem(pos);
            String orderingid = orders.OrderId;
            Toast.makeText(context, "Position :"+ Integer.toString(pos)+" orderid : "+orderingid,
                    Toast.LENGTH_SHORT).show();
            DatabaseReference mDatabase;
            mDatabase = FirebaseDatabase.getInstance().getReference();
            mDatabase.child("Active Orders").child(orderingid).child("Status").setValue("Cooking");

            FrameLayout vwParentRow = (FrameLayout)v.getParent();
            Button btnChild = (Button)vwParentRow.getChildAt(0);
            MultiStateToggleButton btnchild2 = (MultiStateToggleButton)vwParentRow.getChildAt(1);
            btnChild.setVisibility(View.INVISIBLE);
            btnchild2.setVisibility(View.VISIBLE);
            notifyDataSetChanged();
        }
    });


    OrderDetails orders = (OrderDetails)getItem(position);
    viewHolder.mdtitle.setText(orders.foodname);

    return convertView;
}

private class ViewHolder{
    TextView mdtitle;
    Button confirmationbutton;
    MultiStateToggleButton switchbutton;

}

}

Screenshot of listview

预期输出:

披萨的点击按钮:位置 0 orderid 3

点击 sopp 的按钮:位置 1 orderid 4

电流输出:

披萨的点击按钮:位置 0 orderid 3

点击 sopp 的按钮:位置 0 orderid 3

这是如果我等待数据加载并立即单击按钮。我注意到,如果我等待数据加载,然后按后退按钮并再次返回活动,那么输出将是正确的。我做错了什么?

【问题讨论】:

    标签: android listview


    【解决方案1】:

    您的 OnClickListener 应该在 getView 中设置并获取 ViewHolder 模式

    为什么奇怪?

    您的按钮单击侦听器只会在第 0 位附加 convertView 将为 null。在 onwords convertView 将被填充后 听众不会附加到那个位置,比如第 1、第 2 等等。

    查看更新的getView

    public View getView(int position, View convertView, final ViewGroup parent) {
        ViewHolder viewHolder = null;
        if (convertView == null) {    
            LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);  
            viewHolder = new ViewHolder();    
            convertView = layoutInflater.inflate(R.layout.orderlistview, null);
            confirmationbutton = (Button) convertView.findViewById(R.id.confirmationbutton);
            confirmationbutton.setTag(position);
    
            convertView.setTag(viewHolder);
    
        } else {
    
           viewHolder = (ViewHolder) convertView.getTag();
        }
    
       final int pos = position;
       confirmationbutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
    
                OrderDetails orders = (OrderDetails)getItem(pos);
                String orderingid = orders.OrderId;
                Toast.makeText(context, "Position :"+ Integer.toString(pos)+" orderid : "+orderingid,
                        Toast.LENGTH_SHORT).show();
                notifyDataSetChanged(); 
                }
        });
    
        OrderDetails orders = (OrderDetails)getItem(pos);
        viewHolder.mdtitle.setText(orders.foodname);
    
        return convertView;
    }
    

    【讨论】:

    • 我已尝试根据您的建议移动代码块,但仍然遇到同样的问题。
    • 为了以防万一,也发布了整个pendingorders类
    • 我认为您尝试使用错误的positon 这里Integer pos = (Integer)v.getTag(); 它应该是getview 的位置
    • 谢谢,更新的答案有效,你对听众立场的解释也很好。
    【解决方案2】:

    尝试将您的setOnClickListener 移出if(convertview == null)statment。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      相关资源
      最近更新 更多