【问题标题】:My Android App crashes when i run a DialogBox for the second time当我第二次运行对话框时,我的 Android 应用程序崩溃了
【发布时间】:2014-01-23 00:52:26
【问题描述】:

您好,我只是想制作一个应用程序,该应用程序将有一个按钮,该按钮将从对话框中获取 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)

感谢您的帮助!

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

【问题讨论】:

    标签: java android eclipse dialog


    【解决方案1】:

    在函数中创建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();
    
    }
    

    【讨论】:

      【解决方案2】:

      问题在于您的 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();
      }
      

      【讨论】:

        【解决方案3】:

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

          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

        【讨论】:

          猜你喜欢
          • 2015-05-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多