我正在尝试填充对象的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);
}
}
}
}
}
答案 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。