我正在上一门在线课程并为自学而制作一个Android应用程序。在这个应用程序中,我想在gridView中显示电影海报的缩略图。现在我的问题是如何将movies arrayList
传递给asyncTask
的自定义适配器。我可以用onPostExecute
方法实现一些目标。我的意思是如何在asyncTask的onPostExecute
方法中异步设置适配器的数据源?
这是我的代码。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FetchMovies mMovies = new FetchMovies(this);
mMovies.execute("popularity.desc");
GridView gridView= (GridView) findViewById(R.id.gridview);
gridView.setAdapter(new CustomAdapter(this,new ArrayList<MovieContract>()));
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Toast.makeText(MainActivity.this, "" + position,
Toast.LENGTH_SHORT).show();
}
});
}}
public class CustomAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<MovieContract> movie_list;
public CustomAdapter(Context context, ArrayList<MovieContract> movie_list) {
mContext = context;
this.movie_list= movie_list;
}
@Override
public int getCount() {
return movie_list.size();
}
@Override
public MovieContract getItem(int position) {
return movie_list.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setPadding(8, 8, 8, 8);
Picasso.with(mContext).load("http://image.tmdb.org/t/p/w500/" + movie_list.get(position).getMovie_poster()).into(imageView);
} else {
imageView = (ImageView) convertView;
}
// imageView.setImageResource(mThumbIds[position]);
return imageView;
}}
public class FetchMovies extends AsyncTask<String,Void,ArrayList<MovieContract>> {
private CustomAdapter customAdapter;
private Context context;
private ArrayList<MovieContract> mMovie_list = new ArrayList<>();
private MovieContract mMovieContract;
private String poster_path;
public final String LOG_Tag=FetchMovies.class.getSimpleName();
public FetchMovies(Context context) {
this.context = context;
}
@Override
protected ArrayList doInBackground(String[] params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String MoviesJsonStr = null;
String Api_key= "xxxxxxxxxxxxxxxxxxxxxx";
try {
final String Movies_base="http://api.themoviedb.org/3/discover/movie?";
final String Sort_param="sort_by";
final String ApiKey_param="api_key";
final String Image_Size="w500";
Uri MovieUriBuilder=Uri.parse(Movies_base).buildUpon()
.appendQueryParameter(Sort_param,params[0])
.appendQueryParameter(ApiKey_param, Api_key)
.build();
Log.v(LOG_Tag, "URI Builder" + MovieUriBuilder.toString());
URL url= new URL(MovieUriBuilder.toString());
urlConnection=(HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream= urlConnection.getInputStream();
StringBuffer buffer= new StringBuffer();
if(inputStream==null){
MoviesJsonStr=null;
}
reader= new BufferedReader(new InputStreamReader(inputStream));
String Result;
while ((Result=reader.readLine())!=null){
buffer.append(Result + '\n');
}
if (buffer.length() == 0) {
MoviesJsonStr = null;
}
MoviesJsonStr = buffer.toString();
Log.v(LOG_Tag,"Forecast Jason String " + MoviesJsonStr);
}
catch (IOException e){
Log.e("FetchMovies", "Error ", e);
MoviesJsonStr=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 ParseMoviesJsonString(MoviesJsonStr);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
private ArrayList<MovieContract> ParseMoviesJsonString(String movieJsonStr ) throws JSONException{
final String json_result="results";
final String json_poster_path="poster_path";
final String json_original_title="original_title";
final String json_title="title";
final String json_releaseDate="release_date";
final String json_overview="overview";
final String json_vote_average="vote_average";
ArrayList<MovieContract> movie_list= new ArrayList<>();
JSONObject MovieJson = new JSONObject(movieJsonStr);
JSONArray MovieArray = MovieJson.getJSONArray(json_result);
String[] resultStrs = new String[MovieArray.length()];
for(int i = 0; i < MovieArray.length(); i++) {
//JSONObject Movieobject = MovieArray.getJSONObject(i);
JSONObject result_movie=MovieArray.getJSONObject(i);
MovieContract movie = new MovieContract();
movie.setTitle(result_movie.getString(json_original_title));
movie.setMovie_poster(result_movie.getString(json_poster_path));
movie.setPlot_synopsis(result_movie.getString(json_overview));
movie.setRelease_date(result_movie.getString(json_releaseDate));
movie.setVote_average(result_movie.getString(json_vote_average));
movie_list.add(movie);
}
for (MovieContract result : movie_list){
Log.v(LOG_Tag," preparing data " + result.getMovie_poster() + " " +result.getPlot_synopsis() );
}
return movie_list;
}
@Override
protected void onPostExecute(ArrayList<MovieContract> Movie_list) {
}}
答案 0 :(得分:4)
将ActivityAdapter声明为活动中的实例变量:
private CustomAdapter customAdapter;
创建适配器并以这种方式设置RecyclerView适配器:
customAdapter = new CustomAdapter(this,new ArrayList<MovieContract>());
gridView.setAdapter(customAdapter);
为CustomAdapter创建更新数据方法:
public void updateMovies(ArrayList<MovieContract> movie_list) {
this.movie_list= movie_list;
}
然后在onPostExecute:
customAdapter.updateMovies(movie_list);
customAdapter.notifyDataSetChanged();
答案 1 :(得分:1)
我总是这样做,以使异步任务更有用
在异步任务类中创建一个Object
OnResult onresult;
在您的异步任务中创建一个接口
public interface OnResult{
public void onfinishprogress(ArrayList<> resultlist);
}
//create a method in async task
public void setOnResult(OnResult onresult)
{
this.onresult=onresult;
}
在你的onPostExecute(..)中设置结果
onPostExecute(ArrayList<MovieContract> Movie_list){
if(this.onresult!=null)
this.onresult.onfinishprogress(Movie_list);
}
现在来了如何在MainActivity中获得结果
FetchMovies fmv=FetchMovies();
fmv.execute(url);
//now get the result from the interface created above
fmv.setOnResult(new OnResult(){
onfinishprogress(ArrayList<> resultlist)
{
//here you get the resultlist which you passed up there.
gridView.setAdapter(customAdapter);
}
});