【问题标题】:I am having issues with displaying my custom objects in a ListView android我在 ListView android 中显示我的自定义对象时遇到问题
【发布时间】:2018-08-18 14:06:22
【问题描述】:

这个想法是能够将从子活动传递的对象存储到对象数组中,并在父活动的列表视图中显示它。我想不出如何在我已有的代码中实现这一点,但我知道我的代码逻辑是错误的。

这是我的主要活动。

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;
    }

}

【问题讨论】:

    标签: android arrays listview object


    【解决方案1】:

    首先,每当您的商品数据发生变化时,您都需要致电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;
    }
    

    【讨论】:

      【解决方案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 example

      【讨论】:

      • 非常感谢,但我仍然收到此错误。 java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“void android.widget.TextView.setText(java.lang.CharSequence)”。
      • 我已经调试过了,我知道该对象正在添加到费用数组列表中。
      • 这个错误意味着你的TextView对象为空,你应该参考ViewHolder vars并分配它们,而不是创建新的,所以改为viewHolder.amount = (TextView) view.findViewById(R.id .txt金额2);其余部分相同,然后尝试再次运行您的代码
      • 如果我说它突出显示“数量”,因为 viewHolder 没有数量变量
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-04
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      相关资源
      最近更新 更多