Android 选项卡式视图直到触摸才会更新

Android Tabbed View Not Updating Until Touch

我有一个 android 应用程序,它的选项卡式布局包含一个列表视图。从服务器检索信息后,我正在尝试更新列表。但是,在触摸屏幕之前,列表不会更新。所有信息都是正确的,但无论我等多久,列表都不会显示在屏幕上,直到我点击它。有谁知道如何解决这个问题?

Tab1.java

import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by hp1 on 21-01-2015.
 */

//NEW
public class Tab1 extends Fragment {
    MainActivity mainActivity;
    List<Post> postList;
    public static NewAdapter newAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v =inflater.inflate(R.layout.tab_1,container,false);

        return v;
    }

    @Override
    public void onStart() {
        super.onStart();
        postList = new ArrayList<Post>();

        try {
            //get data from azure
            mainActivity = (MainActivity) getActivity();

            //set lists
            ListView newListView = (ListView) mainActivity.findViewById(R.id.newListView);
            newAdapter = new NewAdapter(mainActivity, postList);
            newListView.setAdapter(newAdapter);
        }catch(Exception e){

        }

        //get the posts loaded asynchronously
        retrievePosts();
    }

    public void retrievePosts(){
        AsyncTask<Void,Void,Void> task = new AsyncTask<Void,Void,Void>(){
            @Override
            protected Void doInBackground(Void... params) {
                try {
                    postList= mainActivity.postTable.execute().get();
                    Log.e("TAG",postList.get(0).text);
                    newAdapter.updateList(postList);
                } catch (final Exception e) {
                }
                return null;
            }
        };

        runAsyncTask(task);
    }

    private AsyncTask<Void, Void, Void> runAsyncTask(AsyncTask<Void, Void, Void> task) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            return task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        } else {
            return task.execute();
        }
    }
}

NewAdapter.java

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

public class NewAdapter extends BaseAdapter {
    List<Post> postList;
    Context context;
    LayoutInflater inflater;

    public NewAdapter(MainActivity mainActivity, List<Post> myPostList) {
        postList=myPostList;
        context=mainActivity;
        inflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return postList.size();
    }

    @Override
    public Object getItem(int position) {
        return postList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        PostCell postCell=new PostCell();
        View cellView = inflater.inflate(R.layout.post_cell, null);

        postCell.textView=(TextView) cellView.findViewById(R.id.textView1);
        postCell.textView.setText(postList.get(position).text);

        cellView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context, "You Clicked "+postList.get(position).text, Toast.LENGTH_LONG).show();
            }
        });

        return cellView;
    }

    public List<Post> updateList(List<Post> myPostList){
        postList = myPostList;
        notifyDataSetChanged();
        return postList;
    }

    public List<Post> addToList(Post post){
        postList.add(post);
        notifyDataSetChanged();
        return postList;
    }
}

编辑:最终答案 - 这是我解决问题的最终代码。 Bnydev 对这个问题的看法是正确的,但我还需要更改一些其他内容。

public void retrievePosts(){
        //NOTE: must have a return type for an async task to run onpostexecute, which
        //is executed on the ui thread so the screen can be updated

        AsyncTask<Void,Void,Boolean> task = new AsyncTask<Void,Void,Boolean>(){
            @Override
            protected Boolean doInBackground(Void... params) {
                try {
                    postList= mainActivity.postTable.execute().get();
                } catch (final Exception e) {
                    e.printStackTrace();
                }
                return true;
            }
            protected void onPostExecute(Boolean reult) {
                newAdapter.updateList(postList);
            }
        };

        task.execute();
    }

在 Tab1.java 中,您有方法 retrievePosts(),其中包含一个 AsyncTask。在这个 AsyncTask 的 doInBackground() 中,你调用 newAdapter.updateList(),在 updateList() 中,你调用 notifyDataSetChanged()

文档here says, that notifyDataSetChanged() refreshs the UI. But as far as I know, refreshing the UI should only be possible from the UI thread, not from any background thread. You could try to call newAdapter.updateList() in onPostExecute() within the AsyncTask, see the example heredoInBackground() 在后台线程上执行,onPostExecute() 在 UI 线程上执行。

public void retrievePosts(){
    AsyncTask<Void,Void,Void> task = new AsyncTask<Void,Void,Void>(){
        @Override
        protected Void doInBackground(Void... params) {
            try {
                postList= mainActivity.postTable.execute().get();
                Log.e("TAG",postList.get(0).text);
            } catch (final Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        protected void onPostExecute() {
            newAdapter.updateList(postList);
        }
    };

    runAsyncTask(task);
}

PS:我不认为捕获所有异常而不像 e.printStackTrace()