当我第二次运行Dialog Box时,我的Android App崩溃了

时间:2014-01-23 00:52:26

标签: java android eclipse dialog

您好我正在尝试创建一个应用程序,该应用程序将有一个按钮,可以从对话框中输入4个不同的玩家名称,并将输入分配给单独的文本视图。

我希望可以单击按钮,弹出对话框,输入名称,它将显示为player1,然后再次点击同一按钮并输入player2。问题是我第二次无法打开对话框。

代码:

package com.example.russianroullette;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.text.Editable;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class PlayersTab extends FragmentActivity {

    int amtPlayers = 0;//number of players currently active
    String name = "";//name input from Dialog Box

    String player1Name = "";//actual name used for player1
    String player2Name = "";//actual name used for player2
    String player3Name = "";//actual name used for player3
    String player4Name = "";//actual name used for player4

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.players_tab);

        final TextView player1 = (TextView) findViewById(R.id.textView2);//Player1 TextView
        final TextView player2 = (TextView) findViewById(R.id.textView3);//Player2 TextView
        final TextView player3 = (TextView) findViewById(R.id.textView4);//Player3 TextView
        final TextView player4 = (TextView) findViewById(R.id.textView5);//player4 TextView

        final EditText input = new EditText(this);// Set an EditText view to get user input


        final Button addPlayerButton = (Button) findViewById(R.id.add1Button);

        player1.setText("P1: ");//updates the TextView with P1 name
        player2.setText("P2: ");//updates the TextView with P2 name
        player3.setText("P3: ");//updates the TextView with P3 name
        player4.setText("P4: ");//updates the TextView with P4 name

        //Creates AlertDialog
        final AlertDialog.Builder alert = new AlertDialog.Builder(this);

        alert.setTitle("Enter Player's Name");//Title of AlertDialog
        alert.setView(input);//The EditText
        alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                Editable value = input.getText();//gets the input
                name = value.toString();//sets name as the user input from the Dialog Box

                playerId = ("Player " + amtPlayers + ": " + name);// puts all of the variables into a simple string to be used by the TextViews   
                switch(amtPlayers){
                    case 1: player1Name = (name);
                            player1.setText(player1Name);
                            break;
                    case 2: player2Name = (name);//the actual name used for player2
                            player2.setText(player2Name);
                            break;
                    case 3: player3Name = (name);//the actual name used for player3
                            player3.setText(player3Name);
                            break;
                    case 4: player4Name = (name);//the actual name used for player4
                            player4.setText(player4Name);
                            break;
                    default:    //code that asks the user which name to replace
                                break;
                }

            }
        });

        alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
            // Canceled.
            amtPlayers--;//puts the amtPlayers back 1
            }
        });
        //Ends AlertDialog Creation

        addPlayerButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Code that adds new Player.
                amtPlayers++;
                alert.show();


            }
        });



        });
        //Code

    }
}

logcat的:

01-22 19:48:58.376: E/AndroidRuntime(1284): FATAL EXCEPTION: main
01-22 19:48:58.376: E/AndroidRuntime(1284): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
01-22 19:48:58.376: E/AndroidRuntime(1284):     at android.view.ViewGroup.addViewInner(ViewGroup.java:3378)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at android.view.ViewGroup.addView(ViewGroup.java:3249)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at android.view.ViewGroup.addView(ViewGroup.java:3225)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at com.android.internal.app.AlertController.setupView(AlertController.java:401)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at com.android.internal.app.AlertController.installContent(AlertController.java:241)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at android.app.AlertDialog.onCreate(AlertDialog.java:336)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at android.app.Dialog.dispatchOnCreate(Dialog.java:351)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at android.app.Dialog.show(Dialog.java:256)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at android.app.AlertDialog$Builder.show(AlertDialog.java:932)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at com.example.russianroullette.PlayersTab$5.onClick(PlayersTab.java:124)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at android.view.View.performClick(View.java:4084)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at android.view.View$PerformClick.run(View.java:16966)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at android.os.Handler.handleCallback(Handler.java:615)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at android.os.Handler.dispatchMessage(Handler.java:92)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at android.os.Looper.loop(Looper.java:137)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at android.app.ActivityThread.main(ActivityThread.java:4745)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at java.lang.reflect.Method.invokeNative(Native Method)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at java.lang.reflect.Method.invoke(Method.java:511)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-22 19:48:58.376: E/AndroidRuntime(1284):     at dalvik.system.NativeStart.main(Native Method)

感谢您的帮助!

编辑:我相信我必须以某种方式重新启动DialogBox?

3 个答案:

答案 0 :(得分:2)

在功能中创建alertview,并确保在创建alertview时它是一个新的。

-(void)showAlert {
       final AlertDialog.Builder alert = new AlertDialog.Builder(this);

        alert.setTitle("Enter Player's Name");//Title of AlertDialog
        alert.setView(input);//The EditText
        alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                Editable value = input.getText();//gets the input
                name = value.toString();//sets name as the user input from the Dialog Box

                playerId = ("Player " + amtPlayers + ": " + name);// puts all of the variables into a simple string to be used by the TextViews   
                switch(amtPlayers){
                    case 1: player1Name = (name);
                            player1.setText(player1Name);
                            break;
                    case 2: player2Name = (name);//the actual name used for player2
                            player2.setText(player2Name);
                            break;
                    case 3: player3Name = (name);//the actual name used for player3
                            player3.setText(player3Name);
                            break;
                    case 4: player4Name = (name);//the actual name used for player4
                            player4.setText(player4Name);
                            break;
                    default:    //code that asks the user which name to replace
                                break;
                }

            }
        });
        alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
            // Canceled.
            amtPlayers--;//puts the amtPlayers back 1
            }
        });
alert.show();

}

答案 1 :(得分:0)

问题在于您的EditText已绑定到上一个对话框。

一个快速的解决方法是: 在onCreate()之前定义Context和Builder

    Context ctx;
AlertDialog.Builder alert;

在onCreate()中初始化它们:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(...);
    ctx = this.getApplicationContext();


    final Button addPlayerButton = (Button) findViewById(...);
    alert  = new Builder(this);
    // Creates AlertDialog
            ......

}

将addPlayerButton onClick更改为:

        addPlayerButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // Code that adds new Player.
            showDialog();

        }
    });


protected void showDialog() {
    input = new EditText(ctx);
    alert.setView(input);
    alert.show();
}

答案 2 :(得分:0)

我修改了你的代码,请试试这个。

  public class PlayersTab extends FragmentActivity {
 private  AlertDialog.Builder alert = null;
int amtPlayers = 0;//number of players currently active
String name = "";//name input from Dialog Box
private TextView player1 ,player2,player3, player4;
String player1Name = "";//actual name used for player1
String player2Name = "";//actual name used for player2
String player3Name = "";//actual name used for player3
String player4Name = "";//actual name used for player4
 private EditText input ;
 private Button addPlayerButton;
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.players_tab);

   player1 = (TextView) findViewById(R.id.textView2);//Player1 TextView
    player2 = (TextView) findViewById(R.id.textView3);//Player2 TextView
     player3 = (TextView) findViewById(R.id.textView4);//Player3 TextView
    player4 = (TextView) findViewById(R.id.textView5);//player4 TextView

    input = new EditText(this);// Set an EditText view to get user input


    addPlayerButton = (Button) findViewById(R.id.add1Button);

    player1.setText("P1: ");//updates the TextView with P1 name
    player2.setText("P2: ");//updates the TextView with P2 name
    player3.setText("P3: ");//updates the TextView with P3 name
    player4.setText("P4: ");//updates the TextView with P4 name


    //Ends AlertDialog Creation

    addPlayerButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //Code that adds new Player.
             amtPlayers++;

             //You should create dialog after you click, in your earlier code, it was always there.
    alert = new AlertDialog.Builder(this);

    alert.setTitle("Enter Player's Name");//Title of AlertDialog
    alert.setView(input);//The EditText
    alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            Editable value = input.getText();//gets the input
            name = value.toString();//sets name as the user input from the Dialog Box

            playerId = ("Player " + amtPlayers + ": " + name);// puts all of the variables into a simple string to be used by the TextViews   
            switch(amtPlayers){
                case 1: player1Name = (name);
                        player1.setText(player1Name);
                        break;
                case 2: player2Name = (name);//the actual name used for player2
                        player2.setText(player2Name);
                        break;
                case 3: player3Name = (name);//the actual name used for player3
                        player3.setText(player3Name);
                        break;
                case 4: player4Name = (name);//the actual name used for player4
                        player4.setText(player4Name);
                        break;
                default:    //code that asks the user which name to replace
                            break;
            }

        }
    });

    alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
        // Canceled.
        amtPlayers--;//puts the amtPlayers back 1
        }
    });  
      alert.show();
        }
    });

我仍然建议您使用DialogFragment,这是使用所有类型对话框的正确方法。

例如,您可以参考此tutorial