How do I load the content of a Spinner into a TextView?

0

What I want to do is that when I load the content that exists inside the Spinner I am loaded in a textview, this is the code where all the data of the spinner is executed, as extra data is connected to a MySQL database.

class DataParser : AsyncTask
{
    Context c;
    private Spinner sp;
    private String jsonData;
    JavaList<string> spacecrafts=new JavaList<string>(); 
    private ProgressDialog pd;

    public DataParser(Context c, Spinner sp, string jsonData)
    {
        this.c = c;
        this.sp = sp;
        this.jsonData = jsonData;
    }

    protected override void OnPreExecute()
    {
        base.OnPreExecute();

        pd = new ProgressDialog(c);
        pd.SetTitle("Cargando información");
        pd.SetMessage("Por favor espere");
        pd.Show();

    }

    protected override Object DoInBackground(params Object[] @params)
    {
        return this.ParseData();
    }

    protected override void OnPostExecute(Object result)
    {
        base.OnPostExecute(result);

        pd.Dismiss();

        if (Integer.ParseInt(result.ToString()) == 0)
        {
            Toast.MakeText(c,"No se puede analizar",ToastLength.Short).Show();
        }
        else
        {
            ArrayAdapter<string> adapter=new ArrayAdapter<string>(c,Android.Resource.Layout.SimpleListItem1,spacecrafts);
            sp.Adapter = adapter;

            sp.ItemSelected += sp_ItemSelected;
        }
    }

    void sp_ItemSelected(object sender, AdapterView.ItemSelectedEventArgs e)
    {
        Toast.MakeText(c, spacecrafts[e.Position], ToastLength.Short).Show();

    }

    private int ParseData()
    {
        try
        {
            JSONArray ja=new JSONArray(jsonData);
            JSONObject jo = null;

            spacecrafts.Clear();

            for (int i = 0; i < ja.Length(); i++)
            {
                jo = ja.GetJSONObject(i);

                String name = jo.GetString("nomb_ingrediente");

                spacecrafts.Add(name);

            }

            return 1;


        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }

        return 0;
    }
}

And here is the MainActivity

public class MainActivity : Activity
{
    private Spinner sp;
    private String urlAddress = "localhost:7777/carpeta/buscar.php";

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        sp = FindViewById<Spinner>(Resource.Id.sp);
        TextView text = FindViewById<TextView>(Resource.Id.textView1);
        Button downloadBtn = FindViewById<Button>(Resource.Id.downloadBtn);
        downloadBtn.Click += downloadBtn_Click;


    }

    void downloadBtn_Click(object sender, EventArgs e)
    {
        new Downloader(this, urlAddress, sp).Execute();
    }
}

I just want to load the spinner in the textview that appears here, thank you very much

    
asked by alexander 09.07.2018 в 07:20
source

1 answer

0

You can try using the C # asynchronous programming which is an advantage and more powerful than AsyncTask to execute tasks without blocking the main thread.

In the asynchronous methods of C # there are two keywords or keywords .

  

async : Use the modifier async to specify that a method,   A lambda expression or an anonymous method is asynchronous. If it is used   this modifier in a method or an expression, reference is made to   same as asynchronous method.

     

await : The operator await applies to a task in a method   asynchronous to suspend the execution of the method until it is   Complete the expected task. The task represents the work in progress.

This means that everything that is after the await will be processed, after the result is obtained. Therefore, there are several ways to wait for this result without stopping the other main thread processes.

For example, you can run a Task to perform tasks in second flat and if you compare it with an asynchronous task (AsyncTask), you would have the following:

Example in C #

private async void ParseDataAsync(){

    // OnPreExecute

    // Do in Background, se especifica con el operador await, debe ser una tarea asincrona, por ende se puede correr un Task
    await Task.Run(() => {
         // Aqui ejecutas lo que estara en background

    });

    // OnPostExecute
}

And to call it, you would do the following:

If you are in an asynchronous method:

await ParseDataAsync();

If you are not in an asynchronous method:

You must return Task in the method and use the method GetAwaiter() of Task , for example:

private async Task ParseDataAsync() {
    . . . 
}

and you would call it like this:

ParseDataAsync().GetAwaiter();

If you want to return a value in an asynchronous method:

You must return Task<> and specify the generic parameter within <> . For example, return a int :

private async Task<int> ParseDataAsync() {
        . . . 
       return 0;
}

And to get the result:

If you are in an asynchronous method:

int x = await ParseDataAsync();

If you are not in an asynchronous method:

int x = ParseDataAsync().GetAwaiter().GetResult();

You can see more in the official documentation about the C # asynchronous programming and the Tasks , you will be very helpful in Xamarin Android. This is an example of what happens in an asynchronous method. This is what happens in an asynchronous C # task:

This means that everything after the await is at risk. In the case of Android with the Activitys, you must take into account that when executing actions in the UI, such as hiding or showing a progressbar, you must make the respective validations with the life cycle that creates it. For example if you put after await you will throw a Toast , you must be sure that your activity or context that creates it is not destroyed. A serious test case, execute an asynchronous task when starting an activity and quickly close / destroy it. The asynchronous task will remain in the background and when the result arrives, when launching the Toast with a destroyed context, this will throw an error, therefore you must take into account that you have to validate your context with a if(!(Context as Activity).IsDestroyed ?? true)) before performing the UI actions that involve the parent Activity.

Your solution to your question:

MainActivity.cs

public class MainActivity : Activity
{
    private Spinner sp;
    private String urlAddress = "localhost:7777/carpeta/buscar.php";
    private ProgressDialog pd;
    private JavaList<string> spacecrafts = new JavaList<string>(); 

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        sp = FindViewById<Spinner>(Resource.Id.sp);
        TextView text = FindViewById<TextView>(Resource.Id.textView1);
        Button downloadBtn = FindViewById<Button>(Resource.Id.downloadBtn);
        downloadBtn.Click += downloadBtn_Click;


    }

    private async void downloadBtn_Click(object sender, EventArgs e)
    {
        // La llamada a tu Downloader
        new Downloader(this, urlAddress, sp).Execute();

        // Aqui debes obtener el resultado jsonData antes de llamar este metodo      // Puedes convertir tu Downloader a una tarea asincrona de C# si es un AsyncTask
        await ParseDataAsync();
    }

    private async void ParseDataAsync(){
        // OnPreExecute
        ShowProgressDialog();

        int result = 0;
        // Do in Background
        await Task.Run(() => {
             // Aqui ejecutas lo que estara en background
             result = ParseData();
        });

       // OnPostExecute
       DismissDialog();
       BindData(result);
       SetTextViewInfo();
    }

    private void ShowProgressDialog(){

        if(pd == null){
            pd = new ProgressDialog(c);
            pd.SetTitle("Cargando información");
            pd.SetMessage("Por favor espere");
        }

        pd.Show();
    }

    private int ParseData(string jsonData)
    {
        try
        {
            JSONArray ja = new JSONArray(jsonData);
            JSONObject jo = null;

            spacecrafts.Clear();

            for (int i = 0; i < ja.Length(); i++)
            {
                jo = ja.GetJSONObject(i);
                String name = jo.GetString("nomb_ingrediente");
                spacecrafts.Add(name);
            }

            return 1;

        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }

        return 0;
    }

    private void DismissDialog(){
        pd?.Dismiss(); // Dismiss si pd no es null
    }

    private void BindData(int result){


        if (Integer.ParseInt(result.ToString()) == 0)
        {
            Toast.MakeText(Application.Context, "No se puede analizar",ToastLength.Short).Show();
        }
        else
        {
            ArrayAdapter<string> adapter = new ArrayAdapter<string>(c,Android.Resource.Layout.SimpleListItem1, spacecrafts);
            sp.Adapter = adapter;

            // Elimina el evento anterior si existe para evitar duplicarlo
            sp.ItemSelected -= sp_ItemSelected;

            // Agrega el nuevo evento de itemSelected
            sp.ItemSelected += sp_ItemSelected;
        }
    }

    private void sp_ItemSelected(object sender, AdapterView.ItemSelectedEventArgs e)
    {
        Toast.MakeText(Application.Context, spacecrafts[e.Position], ToastLength.Short).Show();

    }

    private void SetTextViewInfo(){
        // En este nivel ya tienes la informacion en la lista spacecrafts
        // Creas un string info y vas agregando la informacion de las listas con un foreach
        // Haces en tu textview .Text = info; y listo

    }
}
    
answered by 09.07.2018 в 10:09