Предаване на низови стойности от персонализиран диалогов прозорец към друга дейност

Използва се персонализиран диалогов прозорец за приемане на въведени от потребителя данни и след това тези стойности се предават на друга дейност с помощта на getter методи.

Но когато предам стойностите на метод, който извежда стойностите на низа към CSV файл, shipName, analystName и т.н., стойностите се показват като празни във файла по този начин, " " въпреки че съм въвел стойностите в диалоговия прозорец.

Отстраних грешките на проблема, като наблюдавах стойностите на низа в прозореца на израза на менюто за отстраняване на грешки, 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(), така че гетърите връщат първоначалните стойности за тези полета, което е нула във всички случаи. Трябва да създадете интерфейс, който дейността изпълнява, за да получите обратно извикване, след като тези полета са зададени в метода onClick() на вашия CustomListener, и след това да актуализирате променливите на дейността.

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

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

Не забравяйте да запазите препратка към контекста:

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
Добавих горното решение към моя проект, но получавам изключение за нулев указател на този ред, когато се щракне върху OK, dialog.displayMessage(SearchResult.this, "Sample Info", "Required"); може да не съм внедрил вашето решение правилно..ето как внедрих кода и в двата класа: hastebin.com/uzirotijiv.avrasm hastebin.com/ugirunukod.avrasm Имате ли представа къде сбърках с решението? ` - person Brian J; 11.01.2015
comment
@BrianJ Трябва да запазите препратка към контекста в метода 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, променете типа на връщане на метода getter/setter на 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