【问题标题】:java.lang.NullPointerException: Attempt to invoke virtual method android in OnClickListenerjava.lang.NullPointerException:尝试在 OnClickListener 中调用虚拟方法 android
【发布时间】:2017-04-11 00:18:18
【问题描述】:

我是安卓新手。我试图构建一个简单的应用程序,但在尝试调用我的 onClickListener 时遇到了 NullPointerException。被困了几个小时进行调试,但未能发现错误在哪里。我需要帮助来修复它。这是我的代码。

例外

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.example.win8user.kidlearnmath, PID: 2593
              java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
                  at com.example.win8user.kidlearnmath.PlayerActivity.displayDialog(PlayerActivity.java:63)
                  at com.example.win8user.kidlearnmath.PlayerActivity.access$000(PlayerActivity.java:24)
                  at com.example.win8user.kidlearnmath.PlayerActivity$1.onClick(PlayerActivity.java:47)
                  at android.view.View.performClick(View.java:4780)
                  at android.view.View$PerformClick.run(View.java:19866)
                  at android.os.Handler.handleCallback(Handler.java:739)
                  at android.os.Handler.dispatchMessage(Handler.java:95)
                  at android.os.Looper.loop(Looper.java:135)
                  at android.app.ActivityThread.main(ActivityThread.java:5257)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at java.lang.reflect.Method.invoke(Method.java:372)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".PlayerActivity"></activity>
</application>

PlayerActivity.java

package com.example.win8user.kidlearnmath;

import android.app.Dialog;
import android.database.Cursor;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import com.example.win8user.kidlearnmath.mDataObject.Player;
import com.example.win8user.kidlearnmath.mDatabase.PlayerAdapter;
import com.example.win8user.kidlearnmath.mListView.CustomAdapter;

import java.util.ArrayList;

public class PlayerActivity extends AppCompatActivity {

ListView lv;
EditText nameEditText;
Button saveBtn, retrieveBtn;
ArrayList<Player> players = new ArrayList<>();
CustomAdapter adapter;
final boolean forUpdate = true;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_player);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    lv = (ListView) findViewById(R.id.lv);
    adapter = new CustomAdapter(this, players);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            displayDialog(false);
        }
    });

    this.getPlayers();
}

 private void displayDialog(boolean forUpdate){
     final Dialog d = new Dialog(this);

     d.setContentView(R.layout.dialog_layout);

     nameEditText = (EditText) findViewById(R.id.nameEditTxt);
     saveBtn = (Button) findViewById(R.id.saveBtn);
     retrieveBtn = (Button) findViewById(R.id.cancelBtn);

     if(!forUpdate){
         d.setTitle("Add New Player");
         saveBtn.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 if(nameEditText.getText().toString().length() == 0){
                     nameEditText.setError("Name is required");
                 }
                 else{
                     save(nameEditText.getText().toString());
                     d.dismiss();
                 }
             }
         });
        retrieveBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getPlayers();
                d.dismiss();
            }
        });

     }
     else {
         d.setTitle("Edit Player Name");
         saveBtn.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 if(nameEditText.getText().toString().length() == 0){
                     nameEditText.setError("Name is required");
                 }
                 else{
                     update(nameEditText.getText().toString());
                     d.dismiss();
                 }
             }
         });
         retrieveBtn.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 getPlayers();
                 d.dismiss();
             }
         });

     }
     d.show();
 }

private void save(String name){
    PlayerAdapter db = new PlayerAdapter(this);
    db.openDB();
    boolean save;
    save = db.add(name);

    if(save){
        nameEditText.setText("");
        getPlayers();
    }
    else{
        Toast.makeText(this,"Unable To Save",Toast.LENGTH_SHORT).show();
    }
}

private void getPlayers(){
    players.clear();
    PlayerAdapter db = new PlayerAdapter(this);
    db.openDB();
    Cursor c = db.retrieve();
    Player player = null;

    while (c.moveToNext()){
        String pid = c.getString(0);
        String pname = c.getString(1);

        player = new Player();
        player.setPlayerId(pid);
        player.setPlayerName(pname);

        players.add(player);
    }
    db.closeDB();
    lv.setAdapter(adapter);
}

private void update(String newname){
    //Get id of player
    String pid = adapter.getSelectedItemID();

    //UPDATE
    PlayerAdapter db = new PlayerAdapter(this);
    db.openDB();
    boolean updated = db.update(newname,pid);
    db.closeDB();

    if(updated){
        nameEditText.setText(newname);
        getPlayers();
    }
    else {
        Toast.makeText(this,"Unable to Update",Toast.LENGTH_SHORT).show();
    }
}

private void delete(){
    String pid = adapter.getSelectedItemID();

    //DELETE
    PlayerAdapter db = new PlayerAdapter(this);
    db.openDB();
    boolean deleted = db.delete(pid);
    db.closeDB();

    if(deleted){
        getPlayers();
    }
    else {
        Toast.makeText(this,"Unable to Delete",Toast.LENGTH_SHORT).show();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main_menu,menu);
    return true;
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    CharSequence title = item.getTitle();

    if(title=="New"){
        displayDialog(!forUpdate);
    }else if(title=="Edit"){
        displayDialog(forUpdate);
    }else if(title=="Delete"){
        delete();
    }

    return super.onContextItemSelected(item);
}
}

activity_player.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.win8user.kidlearnmath.PlayerActivity">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay"
        />

</android.support.design.widget.AppBarLayout>

<include layout="@layout/content_player" />

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="@dimen/fab_margin"
    android:src="@android:drawable/ic_input_add" />

dialog_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="fill_parent"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_margin="1dp"
card_view:cardCornerRadius="10dp"
card_view:cardElevation="5dp"
android:gravity="center"

android:layout_height="match_parent">

<LinearLayout
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent">

    <android.support.design.widget.TextInputLayout
        android:id="@+id/nameLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.design.widget.TextInputEditText
            android:id="@+id/nameEditTxt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:hint="Name"/>

    </android.support.design.widget.TextInputLayout>

    <Button android:id="@+id/saveBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Save"
        android:clickable="true"
        android:background="@color/colorAccent"
        android:layout_marginTop="40dp"
        android:textColor="@android:color/white"/>

    <Button android:id="@+id/cancelBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Cancel"
        android:clickable="true"
        android:background="@color/colorAccent"
        android:layout_marginTop="40dp"
        android:textColor="@android:color/white"/>


</LinearLayout>

提前致谢。

【问题讨论】:

  • PlayerActivity.java 的第 63 行是什么?
  • 保存按钮抛出异常?或检索按钮?
  • 第 63 行是 saveBtn.setOnClickListener(new View.OnClickListener() {。保存按钮上会抛出异常,但如果我删除 savebtn onclicklistner.retreive 按钮也会抛出异常
  • 点击按钮或对话框显示按钮时抛出异常>?
  • 点击对话框显示按钮时抛出异常

标签: android android-activity nullpointerexception


【解决方案1】:

您正在调用findViewById(),这是Activity 上的一个方法。 DialogActivity 不是同一 Window 的一部分。您想在 Dialog 实例上调用 findViewById()

d.findViewById(R.id.saveBtn)

【讨论】:

  • 谢谢。有用。下次处理实例时会更加小心。
  • 没问题。很高兴能提供帮助。
猜你喜欢
  • 1970-01-01
  • 2021-06-03
  • 1970-01-01
  • 2018-04-03
  • 2020-10-31
  • 2018-09-07
  • 1970-01-01
  • 1970-01-01
  • 2020-05-05
相关资源
最近更新 更多