Передача строковых значений из настраиваемого диалогового окна в другое действие

Пользовательский диалог используется для ввода данных пользователем, а затем эти значения передаются другому действию с использованием getter методов.

Но когда я передаю значения методу, который выводит строковые значения в файл CSV, shipName, analystName и т. д., значения отображаются как пустые в файле, подобном этому, " ", хотя я ввел значения в диалоговом окне.

Я отладил проблему, просматривая значения String в окне выражения меню отладки, shipName и analystName, но значения никогда не обновляются в окне выражения.

Из этого я понимаю, что метод i, через который передаются входные данные, неверен.

Кто-нибудь знает, почему выводимые значения пусты?

Этот класс диалога используется:

package ie.gmi.computing;



import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.renderscript.Sampler;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MyMessageDialog {

    private Context context;
    private EditText shipText, scientistNameText , scientistEmailText , volumeText , colourText ;

    private String shipString, scientistNameString , scientistEmailString , volumeString , colourString ;



    public AlertDialog displayMessage(Context context, String title, String message){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(title);
        builder.setMessage(message);
        LayoutInflater inflater = LayoutInflater.from(context);
        final View v = inflater.inflate(R.layout.custom_view, null);
        builder.setView(v);
        shipText = (EditText)v.findViewById(R.id.shipNameEditText);
        scientistNameText = (EditText)v.findViewById(R.id.scientistEditText);
        scientistEmailText = (EditText)v.findViewById(R.id.emailEditText);
        volumeText = (EditText)v.findViewById(R.id.volumeEditText);
        colourText  = (EditText)v.findViewById(R.id.colourEditText);
        builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {



            }
        });
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });
        AlertDialog dialog= builder.create();
        dialog.show();
        Button tb = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
        tb.setOnClickListener(new CustomListener(dialog));

        return dialog;
    }


    //getter/setters to allow access to string values
    //in SearchResult class
    public EditText getShipText() {
        return shipText;
    }



    public void setShipText(EditText shipText) {
        this.shipText = shipText;
    }



    public EditText getScientistNameText() {
        return scientistNameText;
    }



    public void setScientistNameText(EditText scientistNameText) {
        this.scientistNameText = scientistNameText;
    }



    public EditText getScientistEmailText() {
        return scientistEmailText;
    }


    public void setScientistEmailText(EditText scientistEmailText) {
        this.scientistEmailText = scientistEmailText;
    }



    public String getShipString() {
        return shipString;
    }


    public void setShipString(String shipString) {
        this.shipString = shipString;
    }


    public String getScientistNameString() {
        return scientistNameString;
    }


    public void setScientistNameString(String scientistNameString) {
        this.scientistNameString = scientistNameString;
    }


    public String getScientistEmailString() {
        return scientistEmailString;
    }


    public void setScientistEmailString(String scientistEmailString) {
        this.scientistEmailString = scientistEmailString;
    }


    public String getVolumeString() {
        return volumeString;
    }


    public void setVolumeString(String volumeString) {
        this.volumeString = volumeString;
    }


    public String getColourString() {
        return colourString;
    }


    public void setColourString(String colourString) {
        this.colourString = colourString;
    }


    public EditText getVolumeText() {
        return volumeText;
    }



    public void setVolumeText(EditText volumeText) {
        this.volumeText = volumeText;
    }



    public EditText getColourText() {
        return colourText;
    }



    public void setColourText(EditText colourText) {
        this.colourText = colourText;
    }



    @SuppressLint("NewApi")
    class CustomListener implements View.OnClickListener {
        private final Dialog dialog;
        public CustomListener(Dialog dialog) {
            this.dialog = dialog;
        }
        @SuppressLint("NewApi")
        @Override
        public void onClick(View v) {


            if(shipText.getText().toString().isEmpty() && !shipText.getText().toString().equals(null)){
                shipText.setError("The Field is required");

            }else if(scientistNameText.getText().toString().isEmpty() && !scientistNameText.getText().toString().equals(null)){
                scientistNameText.setError("The Field is required");
            }else if(scientistEmailText.getText().toString().isEmpty() && !scientistEmailText.getText().toString().equals(null)){
                scientistEmailText.setError("The Field is required");
            }else if(volumeText.getText().toString().isEmpty() && !volumeText.getText().toString().equals(null)){
                volumeText.setError("The Field is required");
            }else if(colourText.getText().toString().isEmpty() && !colourText.getText().toString().equals(null)){
                colourText.setError("The Field is required");
            }else{
                shipText.setError(null);
                scientistNameText.setError(null);
                scientistEmailText.setError(null);
                volumeText.setError(null);
                colourText.setError(null);


                shipString = shipText.getText().toString();
                scientistNameString = scientistNameText.getText().toString();
                scientistEmailString = scientistEmailText.getText().toString();
                volumeString = volumeText.getText().toString();
                colourString = colourText.getText().toString();


                Toast.makeText(dialog.getContext(), "The Values you get from : " +
                        "\n Ship name value: " + shipText.getText().toString() +
                        "\n Scientist name value: " + scientistNameText.getText().toString() +
                        "\n email value: " + scientistEmailText.getText().toString() +
                        "\n sample volume value: " + volumeText.getText().toString() +
                        "\n sample colour value: " + colourText.getText().toString() , Toast.LENGTH_SHORT).show();

                dialog.dismiss();
            }
        }
    }
}

И вот как я получаю значения в своем классе SearchResult, когда я нажимаю кнопку настроек:

public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.action_settings:

            MyMessageDialog dialog =new MyMessageDialog(); 
            dialog.displayMessage(SearchResult.this, "Sample Info", "Required");



            // store / use the values here
            shipName = dialog.getShipString();
            analystName = dialog.getScientistNameString();
            analystEmail = dialog.getScientistEmailString();
            sampleVolume = dialog.getVolumeString();
            sampleColour = dialog.getColourString();
            longitudeValue = String.valueOf(lng);
            latitudeValue = String.valueOf(lat);
            sampleMaterial = message;

            return true;

        default:
          return super.onOptionsItemSelected(item);
        } 
    } 

person Brian J    schedule 10.01.2015    source источник


Ответы (3)


Ваше диалоговое окно отображается асинхронно; то есть выполнение кода в onOptionsItemSelected() не приостанавливается после вызова dialog.displayMessage(), поэтому геттеры возвращают начальные значения для этих полей, которые во всех случаях равны нулю. Вы должны создать интерфейс, который Activity реализует для получения обратного вызова после того, как эти поля установлены в методе onClick() вашего CustomListener, а затем обновить переменные Activity.

В классе диалога мы создаем интерфейс. Например:

public class MyMessageDialog {
    public interface DialogCallback {
        public void onValuesSet();
    }
    ...
}

Обязательно сохраните ссылку на Context:

public AlertDialog displayMessage(Context context, String title, String message){
    this.context = context;
    ...
}

И в конце метода onClick() после установки значений полей:

((DialogCallback) context).onValuesSet();

Активность должна реализовать созданный нами интерфейс, диалоговое окно должно быть членом класса, а поля будут установлены в методе обратного вызова интерфейса:

public class SearchResult extends Activity 
    implements MyMessageDialog.DialogCallback {
    ...
    MyMessageDialog dialog;

    @Override
    public void onValuesSet()
    {
        shipName = dialog.getShipString();
        analystName = dialog.getScientistNameString();
        ...
    }
    ...
}
person Mike M.    schedule 10.01.2015
comment
М, не могли бы вы показать пример кода реализации этого кода? - person Brian J; 10.01.2015
comment
@BrianJ Конечно. Однако это займет у меня секунду; Я сейчас на телефоне. - person Mike M.; 10.01.2015
comment
Я добавил вышеуказанное решение в свой проект, но я получаю исключение нулевого указателя в этой строке, когда нажимаю «ОК». dialog.displayMessage(SearchResult.this, "Sample Info", "Required"); Возможно, я неправильно реализовал ваше решение. Вот как я реализовал код в обоих классах: hastebin.com/uzirotijiv.avrasm hastebin.com/ugirunukod.avrasm Есть ли у вас какие-либо идеи относительно того, где я ошибся с решением? ` - person Brian J; 11.01.2015
comment
@BrianJ Вам нужно сохранить ссылку на Context в методе displayMessage(): this.context = context; - person Mike M.; 11.01.2015
comment
Не вызовет ли это конфликт со строкой в ​​методе, AlertDialog.Builder builder = new AlertDialog.Builder(context);. Я только что добавил эту предложенную вами строку и проверю, спасибо - person Brian J; 11.01.2015
comment
@BrianJ Нет. В этом методе context — в отличие от this.context — по-прежнему будет ссылаться на переменную параметра, но на самом деле это не имеет значения, так как они оба будут ссылаться на один и тот же объект (т. е. после присваивания). - person Mike M.; 11.01.2015

Кто-нибудь знает, почему выводимые значения пусты?

Поскольку все операторы получения данных из диалогового класса выполняются после dialog.displayMessage в разделе параметров меню.

Как получить данные от MyMessageDialog по нажатию кнопки Ok?

1. Вместо получения EditText из MyMessageDialog измените тип возврата всех методов получения/установки на String..

2. Создайте прослушиватель событий, используя interface для получения события оповещения о закрытии при нажатии кнопки Ok в действии. вы можете создать прослушиватель событий как:

Прослушиватель пользовательских событий Android

3. вызвать все методы установки при нажатии кнопки Ok предупреждения. после вызова всех методов установки вызовите метод прослушивания событий для выполнения события в действии после окончания оповещения.:

      @Override
        public void onClick(DialogInterface dialog, int which) {
             setShipText(shipText.getText().toString());
             setScientistNameText(shipText.getText().toString());
             ....
             //..close alert and call event listener method
        }
person ρяσѕρєя K    schedule 10.01.2015

Похоже, ваши геттеры на самом деле не вызывают метод getText() для каждого представления EditText. Измените их так, как они делают (например, scientistNameText.getText()).

PS И, да, Майк М действительно может написать об асинхронности, усугубляющей проблему. Другим подходом к этому было бы добавить что-то вроде этого в код для каждого представления EditText:

myEditTextView.addTextChangedListener(new TextWatcher() {

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                int count) {
            // TODO Auto-generated method stub

        }

        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub

            //Set the variable here that you call in your getter. Use `getText()` to get the string (e.g., myGetterVariable = myEditTextView.getText().


        }
    }
person JASON G PETERSON    schedule 10.01.2015