Jorge
Jorge

Reputation: 615

Populate Android ListView with items from MySQL using Spinner

I am an Android programming newbie and the problem stated in the title has been disturbing me.
I have a Groceries table in a MySQL database in my localhost:

id----name---------type
1     apple        fruit
2     banana       fruit
3     lettuce      vegetable
4     apricot      fruit
5     cauliflower  vegetable

I also have a Spinner and a ListView in my Android application. The Spinner has entries of a string array with the items, fruit & vegetable.
I want when the user selects the type from the Spinner as either fruit or vegetable, the ListView will be populated with the names of the corresponding type from MySQL.

Here is what I have done so far.

MainActivity class:

package com.example.mine.application;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Spinner;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

public Spinner groceryTypes;
public ListView groceries;

public static List<String> arrayGroceries;
ArrayAdapter<String> adapterGroceries;

@Override
protected void onCreate(Bundle savedInstanceState) {

    groceryTypes = (Spinner) findViewById(R.id.groceryTypes_spinner);
    groceries = (ListView) findViewById(R.id.groceries_listView);

    arrayGroceries = new ArrayList<>();
    adapterGroceries = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, arrayGroceries);
    groceries.setAdapter(adapterGroceries);

    groceryTypes.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            BackgroundWorker backgroundWorker = new BackgroundWorker(MainActivity.this);
            backgroundWorker.execute(groceryTypes.getItemAtPosition(position).toString());
            adapterGroceries.notifyDataSetChanged();
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            //TODO Auto-generated method stub
        }
    });
}

BackgroundWorker class:

package com.example.mine.application;
import android.content.Context;
import android.os.AsyncTask;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

public class BackgroundWorker extends AsyncTask<String, Void, String> {
Context context;

BackgroundWorker(Context ctx){
    context = ctx;
}

@Override
protected String doInBackground(String... params) {
    String groceries_URL = "http://10.0.2.2/groceries.php";
    String groceryType = params[0];
    try {
        URL url = new URL(groceries_URL);
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        httpURLConnection.setRequestMethod("POST");
        httpURLConnection.setDoOutput(true);
        httpURLConnection.setDoInput(true);

        OutputStream outputStream = httpURLConnection.getOutputStream();
        BufferedWriter bufferedWriter = new BufferedWriter
                (new OutputStreamWriter(outputStream, "UTF-8"));
        String post_data = URLEncoder.encode("grocery_type", "UTF-8")+"="+URLEncoder.encode(groceryType, "UTF-8");
        bufferedWriter.write(post_data);
        bufferedWriter.flush();
        bufferedWriter.close();
        outputStream.close();

        InputStream inputStream = httpURLConnection.getInputStream();
        BufferedReader bufferedReader = new BufferedReader
                (new InputStreamReader(inputStream, "iso-8859-1"));

        MainActivity.arrayGroceries.clear();
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            MainActivity.arrayGroceries.add(line);
        }
        bufferedReader.close();
        inputStream.close();
        httpURLConnection.disconnect();

        return null;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}
}

Here is my groceries.php:

<?php
require "conn.php";

$grocery_type = $_POST["grocery_type"];
$qry = "SELECT name FROM groceries WHERE type LIKE '$grocery_type';";

$result = mysqli_query($conn, $qry);

while($row = mysqli_fetch_row($result)) {
    echo $row[1];
}

mysqli_free_result($result);

$conn->close();
?>

I think the problem is how I handle multiple items from the query but any explanation and help to accomplish this shall be greatly valued.

Upvotes: 0

Views: 494

Answers (1)

Gary Bak
Gary Bak

Reputation: 4798

Assuming that you are getting the correct data from your server and you are populating the array of groceries, you need to add an onPostExecute to your BackgroundWorker AsyncTask and notify the adapterGroceries that the data has changed.

You do this after the AysncTask.execute() but it does not do any good there, the execute() returns immediately and the notify runs but there is nothing to update yet. It needs to run after the data returns.

Upvotes: 1

Related Questions