java.lang.NullPointerException:尝试在空对象引用上写入字段android.widget.TextView $ ViewHolder.numberTextView

时间:2018-02-19 16:04:22

标签: java android listview nullpointerexception textview

我最近一直在做一个项目,我遇到了一个很奇怪的错误,我可以在许多设备上复制它。问题是ListView中的问题适用于前10-20个项目(总项目数为24),但之后如果我向下滚动则抛出异常。你认为这是一个Android问题,我应该切换到recyclerView吗?这是我的活动代码:

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {
    ArrayList<Item> listViewArrayList;
    ListView itemlistView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Parse.initialize(new Parse.Configuration.Builder(this)
                .applicationId("DAaBpKeoV0llJaxlHJGDP0cR6nkSWa5lV0qADN3R")
                .clientKey("LAm9wqXDaLoHnhXzGe6uXmzJGkcIuAnuZDSXRDwW")
                .server("https://parseapi.back4app.com")
                .build()
        );
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                JSONArray jsonArray = new JSONArray();
                for (Item item : listViewArrayList) {
                    jsonArray.put(item.toJsonObject());
                }
                Log.i("tag", jsonArray.toString());
                Intent intent = new Intent(MainActivity.this, OrderSendActivity.class);
                intent.putExtra("orderJson", jsonArray.toString());
                startActivity(intent);
            }
        });

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = findViewById(R.id.nav_view);
        listViewArrayList = new ArrayList<>();
        navigationView.setNavigationItemSelectedListener(this);
        ParseQuery<ParseObject> menuQuery = ParseQuery.getQuery("Menu");
        menuQuery.findInBackground(new FindCallback<ParseObject>() {
            @Override
            public void done(List<ParseObject> objects, ParseException e) {
                if (e == null) {
                    Toast.makeText(MainActivity.this, "Download Completed", Toast.LENGTH_LONG).show();
                    for (ParseObject item : objects) {
                        listViewArrayList.add(new Item(item.getString("name"), item.getString("pricestring"), item.getInt("pricenumber")));
                    }
                    Log.i("debug", listViewArrayList.toString());
                    ItemAdapter adapter = new ItemAdapter(MainActivity.this, R.layout.layout, listViewArrayList);
                    Log.i("debug", adapter.toString());
                    itemlistView = findViewById(R.id.listView);
                    itemlistView.setAdapter(adapter);
                } else {
                    Toast.makeText(MainActivity.this, "Download Failed", Toast.LENGTH_LONG).show();
                }
            }
        });

    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();
        if (id == R.id.nav_first_layout) {

        } else if (id == R.id.nav_second_layout) {

        } else if (id == R.id.nav_third_layout) {

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    private static class ViewHolder {
        private TextView nameTextView;
        private TextView priceTextView;
        private Button plusButton;
        private Button minusButton;
        private TextView numberTextView;
    }

    private class ItemAdapter extends ArrayAdapter {
        private ArrayList<Item> itemModelList;
        private int resource;


        ItemAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull ArrayList<Item> objects) {
            super(context, resource, objects);
            itemModelList = objects;
            this.resource = resource;
        }

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

            final ViewHolder holder;
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            if (convertView != null) {
                holder = (ViewHolder) convertView.getTag();
            } else {
                convertView = inflater.inflate(resource, parent, false);
                holder = new ViewHolder();
                holder.nameTextView = convertView.findViewById(R.id.nameTextView);
                holder.priceTextView = convertView.findViewById(R.id.priceTextView);
                holder.plusButton = convertView.findViewById(R.id.plusButton);
                holder.minusButton = convertView.findViewById(R.id.minusButton);
            }


            holder.numberTextView = convertView.findViewById(R.id.numberTextView);
            holder.nameTextView.setText(itemModelList.get(position).getName());
            holder.priceTextView.setText(itemModelList.get(position).getPrice());
            holder.numberTextView.setText("0");
            holder.plusButton.setOnClickListener(new View.OnClickListener() {
                @SuppressLint("SetTextI18n")
                @Override
                public void onClick(View view) {
                    itemModelList.get(position).incrementOrderNo();
                    holder.numberTextView.setText(Integer.toString(itemModelList.get(position).getOrderNo()));
                }
            });
            holder.minusButton.setOnClickListener(new View.OnClickListener() {
                @SuppressLint("SetTextI18n")
                @Override
                public void onClick(View view) {
                    itemModelList.get(position).decrementOrderNo();
                    holder.numberTextView.setText(Integer.toString(itemModelList.get(position).getOrderNo()));
                }
            });
            return convertView;
        }
    }
}

我的布局代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="88dp"
    android:orientation="horizontal"
    android:paddingBottom="4dp"
    android:paddingStart="?listPreferredItemPaddingLeft"
    android:paddingEnd="?listPreferredItemPaddingRight">

    <TextView
        android:id="@+id/nameTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:text="Masala Dosa"
        android:textSize="16sp"
        android:textColor="@color/black"/>

    <TextView
        android:id="@+id/priceTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="$15/ltr"
        android:layout_below="@id/nameTextView"
        android:textSize="14sp"/>

    <Button
        android:id="@+id/plusButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/priceTextView"
        android:text="+"
        android:textSize="14sp" />

    <Button
        android:id="@+id/minusButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_below="@+id/priceTextView"
        android:text="-"
        android:textSize="14sp" />

    <TextView
        android:id="@+id/numberTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/minusButton"
        android:layout_alignBottom="@+id/minusButton"
        android:layout_toEndOf="@+id/plusButton"
        android:layout_toStartOf="@+id/minusButton"
        android:text="0"
        android:textAlignment="center"
        android:textSize="14sp" />
</RelativeLayout>

最后,错误:

java.lang.NullPointerException: Attempt to write to field 'android.widget.TextView com.ranjusrecipebox.nalapaka.MainActivity$ViewHolder.numberTextView' on a null object reference
                                                                                at com.ranjusrecipebox.nalapaka.MainActivity$ViewHolder.access$502(MainActivity.java:158)
                                                                                at com.ranjusrecipebox.nalapaka.MainActivity$ItemAdapter.getView(MainActivity.java:195)
                                                                                at android.widget.AbsListView.obtainView(AbsListView.java:2363)
                                                                                at android.widget.ListView.makeAndAddView(ListView.java:1970)
                                                                                at android.widget.ListView.fillDown(ListView.java:704)
                                                                                at android.widget.ListView.fillGap(ListView.java:668)
                                                                                at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5186)
                                                                                at android.widget.ListView.trackMotionScroll(ListView.java:1889)
                                                                                at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3568)
                                                                                at android.widget.AbsListView.onTouchMove(AbsListView.java:3977)
                                                                                at android.widget.AbsListView.onTouchEvent(AbsListView.java:3802)
                                                                                at android.view.View.dispatchTouchEvent(View.java:10023)
                                                                                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2626)
                                                                                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2307)
                                                                                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
                                                                                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
                                                                                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
                                                                                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
                                                                                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
                                                                                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
                                                                                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
                                                                                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
                                                                                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
                                                                                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
                                                                                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
                                                                                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
                                                                                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
                                                                                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
                                                                                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
                                                                                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
                                                                                at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:413)
                                                                                at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1808)
                                                                                at android.app.Activity.dispatchTouchEvent(Activity.java:3061)
                                                                                at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
                                                                                at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
                                                                                at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:375)
                                                                                at android.view.View.dispatchPointerEvent(View.java:10243)
                                                                                at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4438)
                                                                                at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4306)
                                                                                at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3853)
                                                                                at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3906)
                                                                                at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3872)
                                                                                at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3999)
                                                                                at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3880)
                                                                                at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4056)
                                                                                at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3853)
                                                                                at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3906)
                                                                                at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3872)
                                                                                at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3880)
                                                                                at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3853)
02-19 21:24:39.687 7299-7299/com.ranjusrecipebox.nalapaka E/AndroidRuntime:     at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6246)
                                                                                at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6220)
                                                                                at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6181)
                                                                                at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6349)
                                                                                at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
                                                                                at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
                                                                                at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176)
                                                                                at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6320)
                                                                                at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:6372)
                                                                                at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
                                                                                at android.view.Choreographer.doCallbacks(Choreographer.java:686)
                                                                                at android.view.Choreographer.doFrame(Choreographer.java:615)
                                                                                at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
                                                                                at android.os.Handler.handleCallback(Handler.java:751)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                at android.os.Looper.loop(Looper.java:154)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:6119)
                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

2 个答案:

答案 0 :(得分:1)

您正面临此异常,因为您没有设置标记,但是当liistview滚动时您正在检索持有者,因此它在此行返回null

int numbers[14]

在创建像这样的视图持有者对象后设置标记

holder = (ViewHolder) convertView.getTag():

答案 1 :(得分:0)

if (convertView != null) { 
    holder = (ViewHolder) convertView.getTag(); 
} else { 
    convertView = inflater.inflate(resource, parent, false); 
    holder = new ViewHolder();
    holder.nameTextView = convertView.findViewById(R.id.nameTextView); 
    holder.priceTextView = convertView.findViewById(R.id.priceTextView); 
    holder.plusButton = convertView.findViewById(R.id.plusButton); 
    holder.minusButton = convertView.findViewById(R.id.minusButton); 
    holder.numberTextView = convertView.findViewById(R.id.numberTextView); 
    convertView.setTag(holder);
}

尝试这样做。