ListView 不显示数据库中的任何项目

ListView shows no items from database

我尝试了很多方法,但还是一片空白 layout.I 改了很多行,但结果总是一样。我应该重写代码并尝试不同的东西吗?我在 youtube 上关注了一些 videos 但没有人有正确的 solution.I 不要认为这是因为数组得到空结果。任何人都知道可能出了什么问题:

AirportTransportActivity

public class AirportTransportActivity extends AppCompatActivity {

ListView listView;
ArrayAdapter<String> adapter;
String[] data = new String[0];
JSONObject jsonObject = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_airport_transport);

    //Get airport details
    Intent intent = getIntent();
    String getairport = intent.getStringExtra("airport");

    final TextView textViewAirport = (TextView) findViewById(R.id.tvairport);
    textViewAirport.setText(getairport);

    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitNetwork().build());


    //List view setup
    listView = (ListView) findViewById(R.id.lvairport);

    //Get airport transport
    new RetrieveTask().execute();

    //Adapter
    adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data);
    listView.setAdapter(adapter);

}

private class RetrieveTask extends AsyncTask<Void, Void, String> {

    @Override
    protected String doInBackground(Void... voids) {
        String strUrl = "http://my database";
        URL url = null;
        StringBuffer sb = new StringBuffer();

        try {
            url = new URL(strUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            InputStream iStream = connection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(iStream));
            String line = "";

            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }

            reader.close();
            iStream.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return sb.toString();
    }

    @Override
    protected void onPostExecute(String result) {

        try {

            JSONArray jsonArray = new JSONArray(result);

            data = new String[jsonArray.length()];

            for (int i = 0; i < jsonArray.length(); i++) {
                jsonObject = jsonArray.getJSONObject(i);
                data[i] = jsonObject.getString("airporttransportname");

            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
adapter.notifyDataSetChanged();
    }
}

}

您正在设置 data 数组并在您的异步任务有机会完成之前调用 notifyDataSetChanged()。您需要在异步任务的 onPostExecute() 方法中设置适配器和 notifyDataSetChanged()

明确一点,当您调用 asyncTask.execute() 时,它会启动异步任务,然后立即继续执行其余代码。因此,当您在列表视图适配器中设置 data 数组时,asyncTask 甚至还没有完成,您的数组项仍然为空。

在您原来的 post 中,您在添加数据之前设置了适配器。但我也怀疑您遇到以下问题: String[] data = new String[0];

所以我改成了 ArrayList<String> data = new ArrayList<>();

我也稍微改变了你的AsyncTask。现在您可以在后台线程中完成大部分解析。当 doInBackground 成功时,只需将 onPostExecute 中的更改通知适配器。

您还需要检查 ArrayList<String> 是否适合您的适配器 class。如果不只是根据需要更改它。

改为这样做:

public class AirportTransportActivity extends AppCompatActivity {

private static final String TAG = AirportTransportActivity.class.getSimpleName();

ListView listView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_airport_transport);

    //Get airport details
    Intent intent = getIntent();
    String getairport = intent.getStringExtra("airport");

    final TextView textViewAirport = (TextView) findViewById(R.id.tvairport);
    textViewAirport.setText(getairport);

    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitNetwork().build());


    //List view setup
    listView = (ListView) findViewById(R.id.lvairport);

    //Get airport transport
    new RetrieveTask().execute();
}

private class RetrieveTask extends AsyncTask<Void, Void, String> {

    @Override
    protected String doInBackground(Void... voids) {
        String strUrl = "http://my database";
        URL url = null;
        StringBuffer sb = new StringBuffer();

        try {
            url = new URL(strUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            InputStream iStream = connection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(iStream));
            String line = "";

            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }

            reader.close();
            iStream.close();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return toString();
    }

    @Override
    protected void onPostExecute(String result) {
        if(result.isEmpty()) return;
        try{
            ArrayList<String> data = new ArrayList<>();
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data);

            JSONArray jsonArray = new JSONArray(result);
            int len = jsonArray.length();
            Log.e(TAG, "Lenth of json array = " + len)

            for (int i = 0; i < len; i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                // I add the optString variation just in case the data is corrupt
                String s = jsonObject.optString("airporttransportname", "?");
                data.add(s);
            }
            listView.setAdapter(adapter);            
        }
        catch(JSONException e){
            e.printStackTrace();
        }
    }
}

免责声明 我是在文本编辑器中完成的,无法指望 "auto-correct" 的某些语法或方法名称——因此您需要检查它。 我会在您的代码中更改其他一些内容,但我想尽可能使其接近原始代码。

无需更改任何内容,只需在将所有值存储到 array

后添加 adapter.notifyDataSetChanged();

Remove this line adapter.notifyDataSetChanged();in Oncreate ,You have to use notifyDataSetChanged() when your arraylist values is getting changed.

 @Override
    protected void onPostExecute(String result) {

        try {

            JSONArray jsonArray = new JSONArray(result);

            data = new String[jsonArray.length()];

            for (int i = 0; i < jsonArray.length(); i++) {
                jsonObject = jsonArray.getJSONObject(i);
                data[i] = jsonObject.getString("airporttransportname");

            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        adapter.notifyDataSetChanged();
    }