簡體   English   中英

無法在onPostExecute中更新android listview

[英]Can't update android listview in onPostExecute

我在onCreate方法中有這個:

String[] myStringArray = {"a","b","c","a","b","c","a","b","c","a","b","c","a","b","c","a","b","c"};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_top_jokes);        

    new loadJson().execute();

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
            android.R.layout.simple_list_item_1, myStringArray);

    ListView listView = (ListView) findViewById(R.id.topJokesList);
    listView.setAdapter(adapter);

    listView.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            // When clicked, show a toast with the TextView text
            Toast.makeText(getApplicationContext(),
            ((TextView) view).getText(), Toast.LENGTH_SHORT).show();
        }
    });

}

上面的代碼使用myStringArray的內容填充listView,現在一切正常。 當我調用new loadJson().execute(); 它執行正常,這是方法的代碼:

public class loadJson extends AsyncTask<Void, Integer, String>{

@Override
protected String doInBackground(Void... params) {
    URL u;
    StringBuffer buffer = new StringBuffer();
    try {
    u = new URL("https://website.com/content/showContent.php");
    URLConnection conn = u.openConnection();
    BufferedReader in = new BufferedReader(
                            new InputStreamReader(
                                conn.getInputStream()));

    String inputLine;
    while ((inputLine = in.readLine()) != null) 
        buffer.append(inputLine);
    in.close();

    }catch(Exception e){
        e.printStackTrace();
    }
    return buffer.toString();
}

protected void onPostExecute(String buffer) {
    JSONArray jsonArray = new JSONArray();
    try {
        jsonArray = new JSONArray(buffer);
    } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println("JSONarray: " + jsonArray);
    String[] newArray = null;
    for (int i = 0; i < jsonArray.length(); i++) {
        try {

        newArray[i] = jsonArray.getJSONObject(i).toString();
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    myStringArray = newArray;
 }

}

正如您所看到的,我正在使用提取到newArray的新值更新myStringArray的硬編碼內容。 現在我無法看到新內容。 我知道它在那里,但我怎么能告訴當前的活動:“嘿,我更新你的陣列,請顯示它!”

我知道我錯過了一些非常小的東西,但作為初學者,我無法發現它。

您切換了數組的引用,您應該做的是在適配器實例上使用clearaddAll (將適配器實例傳遞給AsyncTask以訪問它)。

在您的onPostExecute中,您可以嘗試以下操作:

ListView listView = (ListView) findViewById(R.id.topJokesList);
listView.getAdapter().notifyDataSetChanged();
protected void onPostExecute(String buffer) {
JSONArray jsonArray = new JSONArray();
try {
    jsonArray = new JSONArray(buffer);
} catch (JSONException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
System.out.println("JSONarray: " + jsonArray);
String[] newArray = null;
for (int i = 0; i < jsonArray.length(); i++) {
    try {

    newArray[i] = jsonArray.getJSONObject(i).toString();
    } catch (JSONException e) {
        e.printStackTrace();
    }
}
myStringArray = newArray;

}

在上面的代碼中,您正在使用一些實際駐留在工作線程(doInBackgroud())方法中的代碼,因此請將此代碼剪切並粘貼到doInBackgound方法中。 然后將此代碼保存在onPostExecute方法中,並在oncreate方法之前聲明listview和arrayadapter,即Global

listView = (ListView) findViewById(R.id.topJokesList);
listView.getAdapter().notifyDataSetChanged();

我希望這能幫到您...

我找到了這個問題的答案,因為我自己正在尋找答案。 這里有一些接近的答案,但是他們遺漏了一些永遠不會讓你得到答案的作品。

首先在AsyncTask類中添加兩個成員變量:

private ListView listView;
private Activity activity;

接下來,向您的AsyncTask類添加一個構造函數,該類接受一個Activity:

  public loadJson(Activity activity) {
        this.activity = activity;
    }

現在,當您新建AsyncTask類並調用execute()時,您將添加對調用它的Activity的引用(在構造AsyncTask類時傳入值)。

new loadJson(this).execute(param);

最后,在AsyncTask中,您將編寫postExecute()的代碼,如下所示:

protected void onPostExecute(String output) {
        listView = (ListView) activity.findViewById(R.id.targetListView);
        ArrayAdapter<String> adapter = (ArrayAdapter<String>)listView.getAdapter();
        adapter.add(output);
        adapter.notifyDataSetChanged();
    }

您必須引用您的Activity,以便可以調用findViewById。 請注意,targetListView是ListView的id,它位於原始Activity上。

我們已將該Activity發送到AsyncTask的構造函數中,因此它可用。 現在您可以獲取適配器並將值添加到您並調用notifyDataSetChanged(),以便它在您的UI上更新。

我在我的解決方案中使用此代碼,效果很好。

在更新數組列表內容之后,您可以從數組切換到ArrayList並調用adapter.notifyDataSetChanged(但是不要創建新的ArrayList實例,update必須與提供給ArrayAdapter的引用相同)。

或者在AsyncTask.onPostExecute中重復以下代碼(來自onCreate):

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

您需要:A。使用Strings.xml文件B.將字符串從一個更改為另一個 - 例如

<string name="example1">hi</string>
<string name="example2">hello</string>

在strings.xml文件中,然后在Main類中:

label.setText("@string/example2");

當字符串是example1時。 如果這沒有幫助,我不知道會是什么......

您可以在asynctask構造函數中添加適配器:

在您的活動中:

    LoadJson lj = new Json(adapter);
    lj.execute();

你可以在LoadJson中聲明:

private  ArrayAdapter<String> mAdapter;

在構造函數中,您從活動中獲取適配器:

public LoadJson(ArrayAdapter<String> adapter){
      mAdapter = adapter;
}

所以在你的postExecute中,你可以更新適配器。 希望能幫助到你!

將“loadJson”類作為ListActivity類的子類(或者Activity或您使用的任何活動)

只需將Adapter的引用添加到AsyncTask中:

public class loadJson extends AsyncTask<Void, Integer, String>{

    ArrayAdapter<String> adapter;

    public loadJson(ArrayAdapter<String> adapter) {
        this.adapter = adapter;
    }

    //...

    protected void onPostExecute(String buffer) {
        if (this.adapter != null) {
            // update adapter
        }
    }

}

然后

new loadJson(adapter).execute();  

現在您可以在onPostExecute更新您的Adapter

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM