ListView不显示数据库中的项目

时间:2018-01-25 19:24:13

标签: java android listview android-arrayadapter

我尝试了很多方法但是我得到了空白布局。我改变了很多行,但结果总是一样的。我应该重写代码并尝试不同的东西。我在 youtube 上关注了一些视频,但是没有人有正确的解决方案。我不认为这是因为数组得到了null结果。任何人都知道可能出现的问题:

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();
    }
}

}

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

在原始帖子中,您已在添加数据之前设置了适配器。但我也怀疑你遇到了问题: String[] data = new String[0];

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

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

您还需要检查ArrayList<String>是否适合您的Adapter类。如果不是只是根据需要进行更改。

请改为:

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();
        }
    }
}

免责声明我在文本编辑器中执行此操作,并且无法指望某些语法或方法名称的“自动更正” - 因此您需要检查它。 我还会在代码中更改其他一些内容,但我希望尽可能地保留原始内容。

答案 2 :(得分:0)

在将所有值存储到adapter.notifyDataSetChanged();

后,只需添加array即可进行任何更改
  

删除adapter.notifyDataSetChanged();中的此行Oncreate   当你的arraylist值得到时,必须使用notifyDataSetChanged()   改变。

 @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();
    }