Android添加到ListView notifyDataSetChanged()只能工作一次?

时间:2015-05-20 08:05:00

标签: android listview

我正在动态添加listview

public class AddReferenceActivity extends AppCompatActivity {
    private List<BookingDetails> arrayOfBookings;
    private Activity mActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_reference);

        // Construct the data source
        arrayOfBookings = new ArrayList<BookingDetails>();
        // Create the adapter to convert the array to views
        adapter = new BookingRefAdapter(this, 0, arrayOfBookings);
        // Attach the adapter to a ListView
        listView = (ListView) findViewById(R.id.lvBookingRefs);
        listView.setAdapter(adapter);

        btnBooking.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showProgress();
                //Validate Booking number
                String booking_ref = edtBooking.getText().toString();
                if (Constants.validateNotEmpty(booking_ref)){
                    //Associate
                    ApiManager.getService().associate(user_id, booking_ref, "", new Callback<BookingDetails>() {
                        @Override
                        public void success(BookingDetails booking, Response response) {
                            arrayOfBookings.add(booking);
                            adapter.notifyDataSetChanged();
                        }

                        @Override
                        public void failure(RetrofitError error) {
                            Log.e(TAG, "Error Creating Booking Associations");
                        }
                    });
                }
                else{
                    Constants.showError(mActivity, "Booking Reference", "Booking Reference Can't be null");
                }
            }
        });

问题是只有第一项被添加到列表中,下次我添加时什么都没有添加。

更新BookingRefAdapter.java

public class BookingRefAdapter extends ArrayAdapter<BookingDetails>{
    public BookingRefAdapter(Context context, int resource, List<BookingDetails> objects) {
        super(context, resource, objects);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        BookingDetails book = getItem(position);
        //Check if existing view is being used, otherwise inflate the view
        if (convertView == null){
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_booking_ref, parent, false);
        }

        TextView tvType = (TextView) convertView.findViewById(R.id.tvType);
        TextView tvNumber = (TextView) convertView.findViewById(R.id.tvNumber);

        if (book.getBookingRef() != null){
            tvType.setText("Booking Reference");
            tvNumber.setText(book.getBookingRef());
        }
        else{
            tvType.setText("e-Ticket Number");
            tvNumber.setText(book.getEticket());
        }

       return convertView;
    }
}

1 个答案:

答案 0 :(得分:2)

正如评论中所述,问题可能与您的ArrayAdapter实施有关。但是,我可以给你一些建议:

1)确保你的ListView不在Scrollview内,因为android不会知道要滚动的内容。如第47页或Google IO 10

所述

2)如果您不需要使用任何项目初始化ListView(查看您的代码,这似乎就是这种情况),您不应该传递一个空列表,(恕我直言,您可以随时避免它)和你应该使用这样的构造函数:

private class MyAdapter extends ArrayAdapter<BookingDetails>{
    private Context mContext;
    public MyAdapter(Context c){
        super(c, 0);
        mContext = c;
    }
}

避免明确地传递一个列表,你不应该对List引用有问题,因为ListView是通过引用传递的,Adapter和你的外部类(Activity)都可以修改它。

3)使用适配器公开的方法更改(添加,删除等)ListView中的项目:

  • add(Object o)
  • 的addAll(集合)
  • 删除(T对象)

等等。因此,在您的情况下,使用此代码行简单添加项目:

adapter.add(booking);

4)如果不需要,请不要使用notifyDataSetChanged()。如果您查看add() method的源代码,可以看到代码行:

if (mNotifyOnChange) notifyDataSetChanged();

布尔mNotifyOnChange也初始化为true:

private boolean mNotifyOnChange = true;

因此,在适配器中添加项目时会自动调用notifyDataSetChanged()。