Android ListView 在数据下载之前加载 - 必须重新启动 View

标签 android listview httprequest android-arrayadapter

我正在我的一个类中使用新的 Runnable httprequest 数据加载。我使用该类在我的一个 Activity 中填充 ListView,但问题是 View 在数据加载之前加载。我尝试移动初始化所​​有 View 的初始化方法,但没有任何反应。每次加载应用程序时,我都必须重新加载主视图,因为 ListView 中没有条目。 LoadReportList() 是创建持有 http 请求方法的类实例的方法。

 public class HomeActivity extends Activity {

private ArrayList<Report> reportList = null;

ListView listview;

private final boolean DEBUG = true;

private MyCustomArrayAdapter adapter = null;

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

@Override
protected void onResume()
{
    super.onResume();
    loadReportList();
    initialize();
}

/**
 * This method initializes all the components needed for the activity
 */
private void initialize()
{
    /* Get a reference of the listview in our xml view */
    listview = (ListView) findViewById(R.id.reportsList);

    adapter = new MyCustomArrayAdapter(this, R.layout.single_listview_row);

    try{
        // Populate the list, through the adapter   
        for(final List_Item entry : getListEntries()) {
            adapter.add(entry);
            if(DEBUG)Log.i("HomeActivity","in adding List_Item entries to the adapter");
        }
    }catch(Exception e){
        Log.i("In initialize() HomeActivity","Could not load the list with entries");

        loadReportList();
    }

    listview.setAdapter(adapter);

    listview.setOnItemClickListener(new OnItemClickListener(){  
        public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {

            /* Class to assist us in loading the activity */
            Class editClass = null;
            try {
                editClass = Class.forName(".DetailsActivity");
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            /* create bundle to pass the ID of the deck that was clicked */
            Bundle reportPassed = new Bundle();
            //reportPassed.putInt("Report", reportList.get(4).getId());
            reportPassed.putSerializable("report", reportList.get(position));

            /* Start the new intent and also pass a bundle that will contain the name of the card that was clicked */
            Intent ourIntent = new Intent(HomeActivity.this, editClass);
            ourIntent.putExtras(reportPassed);//passing the bundle to the activity
            //start the activity
            startActivity(ourIntent);
        }
    });
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.home, menu);
    return true;
}

/* Create the list of objects of type List_Item, in our case it will be Decks */
private List<List_Item> getListEntries(){

    /* Create an ArrayList of List_Items */
    final ArrayList<List_Item> entries = new ArrayList<List_Item>();

    if(reportList == null || reportList.isEmpty())
        loadReportList();

    /* Create the rows for the ListView by adding them into the ArrayList "entries".
     * reportList is a global ArrayList<Report> that we populate by a method call to the class JsonParser.
     * Look above.
     * */
    for(int i = 0; i < reportList.size(); i++) {
        if(DEBUG)Log.i("getListEntries HomeActivity","Passing through reportlistEntries");
        entries.add(
                new List_Item(((Report)reportList.get(i)).getType(), Integer.toString(((Report)reportList.get(i)).getId()), ((Report)reportList.get(i)).getId())
                );
    }
    return entries;
}

//This method loads the reportList arraylist with all Report objects
void loadReportList(){
    try {
        reportList = new JsonParser().getArrayList();
    } catch (UnsupportedEncodingException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IllegalStateException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (JSONException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
}

}

这是我的 HTTP 请求:

//The constructor simply calls the getHttpResponse()
    public JsonParser() throws UnsupportedEncodingException, IllegalStateException,  IOException, JSONException
{
    getHttpResponse();
}
/*
 *  This method returns an HttpResponse
 */
public void getHttpResponse(){
    Log.i("getHttpResponse", "Right after declaring HttpResponse response");      
    new Thread(new Runnable() {
        public void run() {
            runRequest();
        }
      }).start();
}

void runRequest()
{
    HttpResponse response = null;
    HttpClient client = new DefaultHttpClient();
    HttpGet request = new HttpGet();
    try {
        request.setURI(new URI("http://....../report_data.json"));
        response = client.execute(request);
    } catch (URISyntaxException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    if(response!= null)
        Log.i(response.toString(), "testing response.toString()");

    //call to populate the list
    try {
        populateList(response);
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalStateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

最佳答案

您可以利用 Android SDK 的 AsyncTask 类来代替 java 线程。您可以在 onPreExecute 方法中显示进度对话框,在 doInBackground 方法中完成所有繁重的工作(在您的情况下是 http 内容)并填充您的列表并关闭 onPostExecute 方法中的进度对话框。您可以创建一个内部类,例如扩展 AsyncTask 方法的 Task 并从 onCreate 或 onResume 调用它,无论什么适合您,就像这样。

new Task().execute();

AsyncTask 之所以被命名为“Painless threading”,是因为它的存在是为了让我们的生活更轻松。重用用于此类任务的已实现代码是一种很好的做法。

您可以在 StackOverflow 中找到许多关于 AsyncTasks 使用的话题,例如 progressDialog in AsyncTask

关于Android ListView 在数据下载之前加载 - 必须重新启动 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16267390/

相关文章:

python-3.x - 如何将 PyQt5 pyqtSlot 连接到 QML ListView 信号 "activated"?

listview - SwiftUI - NavigationLink 的目的地创建具有额外空间的 View

ios - 如何成功传递字符串数组作为参数 alamofire

php - 请求的来源

android - 适用于 iOS 和 Android 的网络延迟、电池和负载模拟工具

android - 在 RecyclerView 中使用 Urls 显示包含图像的 ParseFile

java - 按存在于另一个数组列表中的 ListView 排序

node.js - 使用 UTF-8 的 Axios setRequestHeader 方法

java - 在 Android 中使用 firestore 仅使用用户名和密码进行身份验证

java - 无法比较警报对话框编辑文本和我的字符串中的值