У меня проблемы с отображением моих пользовательских объектов в Android ListView

Идея состоит в том, чтобы иметь возможность хранить объект, который передается из дочернего действия в массив объектов, и отображать его в виде списка в родительском действии. Я не могу придумать, как реализовать это в коде, который у меня уже есть, но я знаю, что логика моего кода неверна.

Это моя основная деятельность.

public class MainActivity extends AppCompatActivity {

    //List<Expense> Expenses = new ArrayList<Expense>();
    ArrayList<Expense>  expenses;
    ListView listView;

    private static CustomArrayAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar myToolbar = (Toolbar) findViewById(R.id.toolbarLayout);
        setSupportActionBar(myToolbar);

        listView = (ListView)findViewById(R.id.listView);

        expenses= new ArrayList<>();

        adapter = new CustomArrayAdapter(expenses, getApplicationContext());

        listView.setAdapter(adapter);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1) {
            if (resultCode == Activity.RESULT_OK){
                Expense expense = (Expense) data.getParcelableExtra("expense");

                //THIS LINE HERE IS WHAT I AM ON ABOUT.
                expenses.add(expense);
            }
            if (resultCode == Activity.RESULT_CANCELED) {
                //Write your code if there's no result
            }
        }
    }
}

Поэтому я создал отдельный класс для адаптера пользовательского массива. Вот

public class CustomArrayAdapter extends ArrayAdapter<Expense> {

    private ArrayList<Expense> expenseDataSet;

    Context mContext;

    private static class ViewHolder {
        TextView txtAmount;
        TextView txtDateAdded;
        TextView txtDateOfExpense;
        TextView txtDes;
        TextView txtDatePaid;
        ImageView expenseImage;
    }

    public CustomArrayAdapter(ArrayList<Expense> data, Context context) {
        super(context, R.layout.list_item, data);
        this.expenseDataSet = data;
        this.mContext=context;
    }
    private int lastPosition = -1;

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        //checking whether there is an instance of the view, inflate this view to make view not null
        Expense currentExpense = expenseDataSet.get(position);

        ViewHolder viewHolder; // view lookup cache stored in tag

        final View result;

        if (view == null)
        {
            viewHolder = new ViewHolder();
            LayoutInflater inflater = LayoutInflater.from(getContext());
            view = inflater.inflate(R.layout.list_item, parent, false);
            //setting the text views in list to the currentContact

            TextView amount = (TextView) view.findViewById(R.id.txtAmount2);

            TextView description= (TextView) view.findViewById(R.id.txtDescription);

            TextView dateOfExpense = (TextView) view.findViewById(R.id.txtDateOfExpense2);

            TextView dateAdded = (TextView) view.findViewById(R.id.txtDateAdded2);

            TextView datePaid = (TextView) view.findViewById(R.id.txtDatePaid2);

            ImageView ivExpenseImage = (ImageView) view.findViewById(R.id.ivExpenseImage);

            result=view;

            view.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) view.getTag();
            result=view;
        }

        Animation animation = AnimationUtils.loadAnimation(mContext, (position > lastPosition) ? R.anim.up_from_top : R.anim.down_from_top);
        result.startAnimation(animation);
        lastPosition = position;

        viewHolder.txtAmount.setText(currentExpense.get_amount());
        viewHolder.txtDes.setText(currentExpense.get_amountVat());
        viewHolder.txtDateOfExpense.setText(currentExpense.get_dateOfExpense());
        viewHolder.txtDateAdded.setText(currentExpense.get_dateAdded());
        viewHolder.txtDatePaid.setText(currentExpense.get_datePaid());
        viewHolder.expenseImage.setImageURI(currentExpense.get_imageUri());

        // Return the completed view to render on screen
        return view;
    }

}
0
0
32
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

попробуйте вызвать notifyDataSetChanged на своем адаптере после добавления элемента.

if (resultCode == Activity.RESULT_OK){
        Expense expense = (Expense) data.getParcelableExtra("expense");

        //THIS LINE HERE IS WHAT I AM ON ABOUT.
        expenses.add(expense);
        adapter.notifyDataSetChanged();
    }
    if (resultCode == Activity.RESULT_CANCELED) {
        //Write your code if there's no result
    }

больше информации Пример notifyDataSetChanged

Большое спасибо, но я все равно получаю эту ошибку. java.lang.NullPointerException: попытка вызвать виртуальный метод void android.widget.TextView.setText (java.lang.CharSequence) для ссылки на нулевой объект.

KPullet 10.03.2018 01:49

Я отлаживал и знаю, что объект добавляется в список расходов.

KPullet 10.03.2018 01:54

эта ошибка означает, что ваш объект TextView имеет значение null, вы должны ссылаться на переменные ViewHolder и назначать их, а не создавать новые, поэтому измените значение на viewHolder.amount = (TextView) view.findViewById (R.id.txtAmount2); и то же самое в остальном, и попробуйте снова запустить код

Burol 10.03.2018 02:18

если я скажу, что он выделяет "количество", так как для viewHolder нет переменной суммы

KPullet 10.03.2018 02:42
Ответ принят как подходящий

Первый, вам необходимо вызывать Adapter.notifyDataSetChanged() всякий раз, когда данные вашего элемента изменяются.

Второй, вам нужно исправить обработку ViewHolder, потому что ваше представление не перерабатывается с вашим текущим кодом. Правильный способ использования паттерна ViewHolder выглядит примерно так:

@Override
public View getView(int position, View view, ViewGroup parent) {
  Expense currentExpense = expenseDataSet.get(position);
  ViewHolder viewHolder; // view lookup cache stored in tag

  if (view == null) {
     // If there's no view to re-use, inflate new view
    viewHolder = new ViewHolder();
    LayoutInflater inflater = LayoutInflater.from(getContext());
    view = inflater.inflate(R.layout.list_item, parent, false);

    viewHolder.txtAmount = (TextView) view.findViewById(R.id.txtAmount2);
    viewHolder.txtDes= (TextView) view.findViewById(R.id.txtDescription);
    viewHolder.txtDateOfExpense = (TextView) view.findViewById(R.id.txtDateOfExpense2);
    viewHolder.txtDateAdded = (TextView) view.findViewById(R.id.txtDateAdded2);
    viewHolder.txtDatePaid = (TextView) view.findViewById(R.id.txtDatePaid2);
    viewHolder.expenseImage = (ImageView) view.findViewById(R.id.ivExpenseImage);
    // Cache viewHolder object inside the new view
    view.setTag(viewHolder);
  } else {
    // Recycle view, retrieve viewHolder object from tag
    viewHolder = (ViewHolder) view.getTag();
  }

  ...

  // Populate the data from the data object
  viewHolder.txtAmount.setText(currentExpense.get_amount());
  viewHolder.txtDes.setText(currentExpense.get_amountVat());

  ...

  // Return the completed view to render on screen
  return view;
}

Другие вопросы по теме