我是Android的新手,并尝试更新udacity nanodegree项目的热门电影应用中的gridlayout
。
我正在使用AsyncTask
下载数据并解析数据,更新recyclerview
并在onPostExecute
中设置适配器。
这是我的AsyncTask类
private class getJson extends AsyncTask<String, Void, String>{
@Override
protected String doInBackground(String... strings) {
String result = "";
URL url;
HttpURLConnection httpURLConnection = null;
try {
url = new URL(strings[0]);
httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream in = httpURLConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while ( data != -1 ){
char current = (char) data;
result += current;
data = reader.read();
}
} catch (java.io.IOException e) {
e.printStackTrace();
}
return result;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
jsonString = s;
Log.i("result", jsonString);
JSONObject jsonObject = null;
if(!list.isEmpty())
list.clear();
try {
jsonObject = new JSONObject(jsonString);
JSONArray jsonArray = jsonObject.getJSONArray("results");
for( int i = 0; i < jsonArray.length() && i < 10; i++ ){
JSONObject currObject = jsonArray.getJSONObject(i);
String posterurl = preUrl + currObject.getString("backdrop_path");
Log.i("poster", posterurl);
String url = preUrl + currObject.getString("poster_path");
String overview = currObject.getString("overview");
String title = currObject.getString("original_title");
String release_date = (currObject.getString("release_date"));
String votes = (currObject.getString("vote_average"));
list.add(new MovieDetails(url,overview, title, release_date, votes, posterurl));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
这是我的适配器类
public class MainRecyclerViewAdapter extends RecyclerView.Adapter<MainRecyclerViewAdapter.ViewHolder> {
ArrayList<MovieDetails> data;
Context context;
public MainRecyclerViewAdapter(Context context, ArrayList<MovieDetails> data ){
this.data = data;
this.context = context;
}
@Override
public MainRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item, parent, false);
MainRecyclerViewAdapter.ViewHolder viewHolder = new MainRecyclerViewAdapter.ViewHolder(v);
return viewHolder;
}
@Override
public void onBindViewHolder(MainRecyclerViewAdapter.ViewHolder holder, int position) {
Picasso.with(context).load(data.get(position).getImageUrl()).into(holder.movie_thumbnail);
//holder.movie_thumbnail.setImageResource(R.mipmap.ic_launcher);
}
@Override
public int getItemCount() {
return data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
ImageView movie_thumbnail;
private Context context;
@Override
public void onClick(View view) {
Toast.makeText(context,data.get(getPosition()).getTitle(),Toast.LENGTH_LONG).show();
Intent intent = new Intent(context, DetailsActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("list", (Serializable) data);
intent.putExtras(bundle);
intent.putExtra("index", getAdapterPosition());
context.startActivity(intent);
}
public ViewHolder(View itemView) {
super(itemView);
context = itemView.getContext();
itemView.setOnClickListener(this);
movie_thumbnail = (ImageView) itemView.findViewById(R.id.movies_item_thumbnail);
}
}
}
这就是我根据投票或受欢迎程度处理排序的方式
@Override
public boolean onOptionsItemSelected(MenuItem item) {
getJson gJson = new getJson();
switch (item.getItemId()){
case R.id.rating :
gJson.execute(top_rated);
return true;
case R.id.popularity : gJson.execute(popular);
return true;
default: return super.onOptionsItemSelected(item);
}
}
onCreate
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar myToolbar = (Toolbar) findViewById(R.id.main_toolbar);
setSupportActionBar(myToolbar);
getJson getJson = new getJson();
getJson.execute(popular);
recyclerView = (RecyclerView)findViewById(R.id.main_recyclerview);
recyclerView.setHasFixedSize(true);
layoutManager = new GridLayoutManager(MainActivity.this,2);
recyclerView.setLayoutManager(layoutManager);
adapter = new MainRecyclerViewAdapter(MainActivity.this, list);
recyclerView.setAdapter(adapter);
}
我想要使用notifydatasetchanged()
,但我无法想象使用 。
另请告诉我更好的方式来处理排序。
这就是我所做的:
在notfiydatasetchanged()
onPostexeute()
每次我调用AsyncTask
时,我的arraylist都会填充新的元素,因此适配器正在填充所有图像。在解析list.clear()
onPostexecute()
醇>
答案 0 :(得分:1)
对于 http-requests ,我建议您使用 retrofit 。
适配器描述了所需选项的排序功能,调用它并最终$('.chicken').each(function () {
$(this).css('background-image', $(this).css('background-image').replace(".jpg", "@2x.jpg"));
});
例如
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="chicken" style="background-image: url('monkey.jpg');"></div>
<div class="chicken" style="background-image: url('donkey.jpg');"></div>
<div class="chicken" style="background-image: url('kitten.jpg');"></div>
<div class="chicken" style="background-image: url('lollol.jpg');"></div>
当您想使用排序时,只需调用排序 notifydatasetchanged();
的方法,将数据设置到其中。
答案 1 :(得分:1)
在活动的adapter
中设置onCreate
。
adapter = new MainRecyclerViewAdapter(MainActivity.this, list);
recyclerView.setAdapter(adapter);
使用字段存储您的列表。
拨打notifydatasetchanged()
的{{1}}中的onPostExecute()
(就像您正在做的那样),但不要重新分配AsyncTask
那里。
答案 2 :(得分:1)
就像Cory Roy suggested一样,试试这个:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView)findViewById(R.id.main_recyclerview);
layoutManager = new GridLayoutManager(MainActivity.this, 2);
recyclerView.setLayoutManager(layoutManager);
adapter = new MainRecyclerViewAdapter(MainActivity.this, list);
recyclerView.setAdapter(adapter);
}
private class getJson extends AsyncTask<String, Void, String>{
@Override
protected String doInBackground(String... strings) {
String result = "";
URL url;
HttpURLConnection httpURLConnection = null;
try {
url = new URL(strings[0]);
httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream in = httpURLConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while ( data != -1 ){
char current = (char) data;
result += current;
data = reader.read();
}
} catch (java.io.IOException e) {
e.printStackTrace();
}
return result;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
jsonString = s;
Log.i("result", jsonString);
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(jsonString);
JSONArray jsonArray = jsonObject.getJSONArray("results");
for( int i = 0; i < jsonArray.length() && i < 10; i++ ){
JSONObject currObject = jsonArray.getJSONObject(i);
String posterurl = preUrl + currObject.getString("backdrop_path");
Log.i("poster", posterurl);
String url = preUrl + currObject.getString("poster_path");
String overview = currObject.getString("overview");
String title = currObject.getString("original_title");
String release_date = (currObject.getString("release_date"));
String votes = (currObject.getString("vote_average"));
list.add(new MovieDetails(url,overview, title, release_date, votes, posterurl));
}
} catch (JSONException e) {
e.printStackTrace();
}
adapter.notifyDataSetChanged();
}
}
请尝试一下,让我知道它是否有效。
答案 3 :(得分:1)
您使用AsyncTask
从远程服务器下载电影。下载和解析结束后,您可以创建适配器并将其设置为RecyclerView
根据您的实现,无需在postExecute()
上调用notifyDataSetChanged()
上述方法的一个缺点是,每次AsyncTask
执行时都会创建一个新的适配器实例。
尝试下面的内容
Activity {
ArrayList<MovieDetails> data;
MainRecyclerViewAdapter adapter
onCreate() {
recyclerView = (RecyclerView)findViewById(R.id.main_recyclerview);
recyclerView.setHasFixedSize(true);
layoutManager = new GridLayoutManager(MainActivity.this,2);
recyclerView.setLayoutManager(layoutManager);
adapter = new MainRecyclerViewAdapter(MainActivity.this);
recyclerView.setAdapter(adapter);
}
AsyncTask {
/.....
onPostExecute{
// Download completed
adapter.notifyDataSetChanged()
}
}
MainRecyclerViewAdapter {
//...
ViewHolder {
//...
}
}
}
答案 4 :(得分:1)
以下是您需要做的所有事情,
看看我的例子
这些是全球变量
private List<Movie> movieList = new ArrayList<>();
private RecyclerView recyclerView;
private MoviesAdapter mAdapter;
让我们转到onCreate
1.初始化回收视图
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
2.创建我的列表的新实例
mAdapter = new MoviesAdapter(movieList);
3.设置我的回收视图
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
4.将适配器设置为我的recycleView
recyclerView.setAdapter(mAdapter);
5.调用加载数据的方法。
setMyData();
让我们转到setMyData
方法
1.从某种方式获取数据..可能是断断续续的
2.将它们添加到我的列表中
movieList.add(movie); // i have not added the lines where i add data to my movie list think it has 10 elements now
3.在我添加所有数据后,我执行了
mAdapter.notifyDataSetChanged();
所以每次有变化我都可以调用setMyData();
它根据需要设置数据。
那个逻辑怎么样?
故意没有添加Adapter类,如果你需要那个,请告诉我
提示:您的异步任务应该执行setMyData()
方法的操作吗?现在看。
好的,你需要第二次更新你的数据!完成异步任务,
layoutManager = new GridLayoutManager(MainActivity.this,2);
啊,当你打电话给你的异步任务时,你一次又一次地调用这一行...人们建议你在onPostExecute
中 notifyDataSet ,(它有效但是..)想想,新的对象也被创建了棕褐色!调用你的asyncTask 10次..现在比较我创建我的对象的地方,是否继续增加..现在你会看到出了什么问题!
p.s我的LayoutManager实例不在我的setMyData()
方法中,而在我的onCreate