Getting NullPointerException in custom ListView

試著忘記壹切 提交于 2020-01-24 07:32:00

问题


I'm getting errors like this when I run my app:

02-27 22:59:19.331: E/AndroidRuntime(2060): FATAL EXCEPTION: main
02-27 22:59:19.331: E/AndroidRuntime(2060): java.lang.NullPointerException
02-27 22:59:19.331: E/AndroidRuntime(2060):     
        at myPlanAdapter.getView(MyPlanActivity.java:145)
        02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.widget.AbsListView.obtainView(AbsListView.java:1315)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.widget.ListView.measureHeightOfChildren(ListView.java:1198)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.widget.ListView.onMeasure(ListView.java:1109)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.view.View.measure(View.java:8171)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1012)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.widget.LinearLayout.measureVertical(LinearLayout.java:381)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.widget.LinearLayout.onMeasure(LinearLayout.java:304)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.view.View.measure(View.java:8171)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.view.View.measure(View.java:8171)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.view.View.measure(View.java:8171)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.view.ViewRoot.performTraversals(ViewRoot.java:801)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.os.Handler.dispatchMessage(Handler.java:99)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.os.Looper.loop(Looper.java:123)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at android.app.ActivityThread.main(ActivityThread.java:4627)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at java.lang.reflect.Method.invokeNative(Native Method)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at java.lang.reflect.Method.invoke(Method.java:521)
    02-27 22:59:19.331: E/AndroidRuntime(2060):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)

And my Source code is:

public class MyPlanActivity extends Activity implements OnItemClickListener,
        OnClickListener {
    private String TAG = "MyPlanActivity";
    private Button addButton = null;
    private ListView listView;
    myPlanAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        viewInit();
        adapter = new myPlanAdapter(getBaseContext());
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(this);

    }

    private void viewInit() {
        setContentView(R.layout.myplan);
        addButton = (Button) findViewById(R.id.AddMyPlanButtonId);
        listView = (ListView) findViewById(R.id.myPlanListViewId);
        addButton.setOnClickListener(this);

    }

    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.AddMyPlanButtonId:
            startActivity(new Intent(this, AddMyPlan.class));
            break;

        default:
            break;
        }
    }

    public void onItemClick(AdapterView<?> paramAdapterView, View paramView,
            int paramInt, long paramLong) {
        // TODO Auto-generated method stub

    }

    @Override
    protected void onResume() {
        super.onResume();
        adapter.notifyDataSetChanged();
    }

    private class myPlanAdapter extends ArrayAdapter<MyPlan> {
        Context context;
        MyPlanDataSource dataSource;

        public myPlanAdapter(Context context) {
            super(context, R.layout.myplan_list_view_entry);
            this.context = context;
            dataSource = new MyPlanDataSource(context);
        }

        private ArrayList<MyPlan> getAllPlan() {

            dataSource.open();
            ArrayList<MyPlan> allPlan = dataSource.getAllPlan();
            dataSource.close();
            Log.d(TAG,allPlan.get(0).getSubjectName());
            return allPlan;
        }

        @Override
        public int getCount() {
            Log.d(TAG,"Size: "+getAllPlan().size());
            return getAllPlan().size();
        }

        @Override
        public MyPlan getItem(int position) {
            return getAllPlan().get(position);
        }

        @Override
        public View getView(final int position, View convertView,
                ViewGroup parent) {
            View row = convertView;
            if (row == null)
            {
                LayoutInflater inflater = (LayoutInflater) context
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                row = inflater.inflate(R.layout.myplan_list_view_entry, parent,
                        false);

                final PlanViewHolder viewHolder = new PlanViewHolder();

                viewHolder.subjectName = (TextView) findViewById(R.id.myPlanListSubNameTextViewId);
                viewHolder.targetGrade = (TextView) findViewById(R.id.myPlanListTargetGradeTextViewId);
                viewHolder.duration = (TextView) findViewById(R.id.myPlanListDurationTextViewId);
                viewHolder.examDate = (TextView) findViewById(R.id.myPlanListExamDateTextViewId);
                viewHolder.daysTogo = (TextView) findViewById(R.id.myplanListDaystogoBoardTextViewId);
                viewHolder.delete = (ImageView) findViewById(R.id.myPlanDeleteImageViewId);
                Log.d(TAG, "" + position);

                row.setTag(viewHolder);
            }
            final PlanViewHolder holder = (PlanViewHolder) row.getTag();


            holder.subjectName.setText((getAllPlan().get(position) 
                    .getSubjectName())); // line 145
            holder.targetGrade.setText("Grade : "
                    + getAllPlan().get(position).getTargetGrade());
            holder.duration.setText(getAllPlan().get(position).getExamTime());
            holder.examDate.setText(getAllPlan().get(position).getExamDate());



            holder.daysTogo.setText(getAllPlan().get(position).getDaysTogo());

            holder.delete.setOnClickListener(new OnClickListener() {

                public void onClick(View v) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(
                            context);
                    builder.setTitle("DELETE")
                            .setMessage(
                                    "Are you sure you want to delete this Subject?")
                            .setCancelable(false)
                            .setPositiveButton("Yes",
                                    new DialogInterface.OnClickListener()
                                    {
                                        public void onClick(
                                                DialogInterface dialog, int id)
                                        {

                                            dataSource.open();
                                            dataSource
                                                    .deletePlan(getItem(position));
                                            dataSource.close();
                                            notifyDataSetChanged();
                                        }
                                    })
                            .setNegativeButton("No",
                                    new DialogInterface.OnClickListener()
                                    {
                                        public void onClick(
                                                DialogInterface dialog, int id)
                                        {
                                            dialog.cancel();
                                        }
                                    });
                    AlertDialog alert = builder.create();
                    alert.show();

                }
            });


            return row;
        }
    }

    static class PlanViewHolder {
        private TextView subjectName;
        private TextView targetGrade;
        private TextView duration;
        private TextView examDate;
        private TextView daysTogo;
        private ImageView delete;
    }

}

回答1:


I think you are searcing for your row views in the wrong place. Try to find them in your inflated row view(in the getView() method):

viewHolder.subjectName = (TextView) row.findViewById(R.id.myPlanListSubNameTextViewId);
viewHolder.targetGrade = (TextView) row.findViewById(R.id.myPlanListTargetGradeTextViewId);
viewHolder.duration = (TextView) row.findViewById(R.id.myPlanListDurationTextViewId);
viewHolder.examDate = (TextView) row.findViewById(R.id.myPlanListExamDateTextViewId);
viewHolder.daysTogo = (TextView) row.findViewById(R.id.myplanListDaystogoBoardTextViewId);
viewHolder.delete = (ImageView) findViewById(R.id.myPlanDeleteImageViewId);



回答2:


Edit on ViewHolder ids, you need to get these ids from convertView(the view passed in) like this:

viewHolder.subjectName = (TextView) row.findViewById(R.id.myPlanListSubNameTextViewId);

Do the same for others.




回答3:


Since this is the line you are getting the NullPointerException, you need to figure out what is null:

holder.subjectName.setText(
  (getAllPlan()
   .get(position)
   .getSubjectName()));

It could be the call to getAllPlan(), the get(position) or the getSubjectName().

What type does the getAllPlan() method return? And are the keys in this type the same values as the positions in the list? By putting the code on different lines it is easier to spot where you get the null.

Also, getAllPlan().get(position) will return the same as getItem(position) in an ArrayAdapter.




回答4:


Make these change to your getView() method:

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

            if (row == null)
            {
                LayoutInflater inflater = (LayoutInflater) context
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.myplan_list_view_entry, parent,
                        false);

                viewHolder = new PlanViewHolder();

                viewHolder.subjectName = (TextView) findViewById(R.id.myPlanListSubNameTextViewId);
                viewHolder.targetGrade = (TextView) findViewById(R.id.myPlanListTargetGradeTextViewId);
                viewHolder.duration = (TextView) findViewById(R.id.myPlanListDurationTextViewId);
                viewHolder.examDate = (TextView) findViewById(R.id.myPlanListExamDateTextViewId);
                viewHolder.daysTogo = (TextView) findViewById(R.id.myplanListDaystogoBoardTextViewId);
                viewHolder.delete = (ImageView) findViewById(R.id.myPlanDeleteImageViewId);
                Log.d(TAG, "" + position);

                convertView.setTag(viewHolder);
            }
            else 
                viewHolder=(PlanViewHolder)convertView.getTag();   
         ... 
         return convertView;
}


来源:https://stackoverflow.com/questions/9468113/getting-nullpointerexception-in-custom-listview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!