无法使用asynctask获取自定义列表适配器以填充listview

时间:2016-09-09 18:46:59

标签: java android listview android-asynctask

我正在尝试填充对象的ArrayList并使用这些对象来填充ListView。我的Asynctask可以获取json数据,我可以解析它并生成我需要的对象,但我的ListView不会填充。当我在适配器运行之前检查我的ArrayList是否有任何对象时,我可以看到它没有。我想知道为什么我的ListView没有填充。

这是我的代码:(对不起,如果它很乱,有些地方我还没有更新)

public class MovieDisplayFragment extends Fragment{

private ArrayList<Movie> movieList = new ArrayList<Movie>();
private MovieAdapter movieAdapter;
ListView listView;

public MovieDisplayFragment(){
}

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

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

    movieAdapter = new MovieAdapter(getActivity(), movieList);
    listView = (ListView) rootView.findViewById(R.id.listview_data);
    listView.setAdapter(movieAdapter);

    if(movieList.size() > 0) {
        Log.e("Hello", "1");
    }

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long l){
            Movie movie = movieAdapter.getItem(position);
            Intent i = new Intent(getActivity(), DetailActivity.class)
                    .putExtra(Intent.EXTRA_TEXT, "Hello");
            startActivity(i);
        }
    });

    return rootView;
}

private void updateMovieData(){
    getMovieData movieData = new getMovieData();
    movieData.execute();
}

@Override
public void onStart(){
    super.onStart();
    updateMovieData();
}

public class getMovieData extends AsyncTask<Void, Void, List<Movie>> {

    private final String LOG_CAT = getMovieData.class.getSimpleName();

    private List<Movie> getMovieData(String movieJsonStr) throws JSONException {

        final String MOV_ITEMS = "results";
        final String MOV_TITLE = "original_title";
        final String MOV_DATE = "release_date";
        final String MOV_SYNOPSIS = "overview";
        final String MOV_VOTE = "vote_average";
        final String MOV_POSTER_URL = "poster_path";

        JSONObject movieJson = new JSONObject(movieJsonStr);
        JSONArray movieArray = movieJson.getJSONArray(MOV_ITEMS);

        Log.e("Hello", "2");

        for (int i = 0; i < movieArray.length(); i++) {

            JSONObject movie = movieArray.getJSONObject(i);

            movieList.add(new Movie(movie.getString(MOV_TITLE), movie.getString(MOV_DATE),
                    movie.getString(MOV_SYNOPSIS), movie.getString(MOV_VOTE), movie.getString(MOV_POSTER_URL)));

        }

        return movieList;
    }

    protected List<Movie> doInBackground(Void... params) {

        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;

        String movieJsonStr = null;

        try {

            final String BASE_URL = "http://api.themoviedb.org/3/genre/10751/movies?api_key=358f3b44734f7e6404f2d01a62d3c176&include_all_movies=true&include_adult=true";
            Uri builtUri = Uri.parse(BASE_URL).buildUpon().build();
            URL url = new URL(builtUri.toString());

            Log.v(LOG_CAT, "Built URI " + builtUri.toString());

            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            InputStream inputStream = urlConnection.getInputStream();
            StringBuffer buffer = new StringBuffer();
            if (inputStream == null){
                movieJsonStr = null;
            }
            reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            while((line = reader.readLine()) != null){
                buffer.append(line + "\n");
            }

            if (buffer.length() == 0){
                movieJsonStr = buffer.toString();
            }
            movieJsonStr = buffer.toString();

            Log.v(LOG_CAT, "Movie String: " + movieJsonStr);
        } catch (IOException e) {
            Log.e("Fragment", "Error", e);
            movieJsonStr = null;

        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (final IOException e) {
                    Log.e("PlaceholderFragment", "Error closing stream", e);
                }
            }
        }

        try {
            return getMovieData(movieJsonStr);
        } catch (JSONException e) {
            Log.e(LOG_CAT, e.getMessage(), e);
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(List<Movie> movies){
        if(movies != null){
            movieAdapter.clear();
            for(Movie movieData : movies){
                movieAdapter.add(movieData);
            }
        }
    }
}

}

3 个答案:

答案 0 :(得分:1)

将这两行放在Async中的onPostExecute()中。

movieAdapter = new MovieAdapter(getActivity(), movieList);
listView.setAdapter(movieAdapter);

AsyncTask在后台线程中运行。它在几秒钟后从json获取数据。但是在创建片段后几毫秒就会调用适配器。

因此,当您设置适配器时,Json中的数据将不存在。

在onPostExecute中调用它解决了这个问题,因为在从服务器检索Json数据后设置了adatpter!

希望它有所帮助。

答案 1 :(得分:0)

在执行后看起来,您正在清除适配器用于填充列表视图的列表,然后将新项添加到列表中。但是,为了在发生这种情况后更新视图,您需要调用notifyDataSetChanged();更新列表后

@Override
protected void onPostExecute(List<Movie> movies){
    if(movies != null){
        movieAdapter.clear();
        for(Movie movieData : movies){
            movieAdapter.add(movieData);
        }
        movieAdapter.notifyDataSetChanged();
    }
}

答案 2 :(得分:0)

在填充movieList()之前,您正在打印movieList(movieList.size())的大小。它永远不会在调试器中打印“Hello”“1”。 asynctask将填充movieList中的数据,比onCreateView()中的movieList.size()检查代码要晚得多

无论如何,经过以下代码

for(Movie movieData : movies)
{
   movieAdapter.add(movieData);
}

你需要插入这一位:

listView.setAdapter(movieAdapter);

您正在填充适配器,但未在getMovieData Asynctask中的onPostExecute()中将其设置为listView。