我正在尝试实现RecyclerView,显示来自JSONArray的数据。解析工作完美,但RecyclerView在每个项目中显示必须仅在最后一项中的信息。 There is the screenshot to make it clear.
这是我的代码:
MainActivity.java
public class MainActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
new parseTask().execute();
}
private class parseTask extends AsyncTask<Void, Void, String> {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String resultJson = "";
ProgressDialog pdLoading = new ProgressDialog(MainActivity.this, R.style.MyDialogStyle);
@Override
protected void onPreExecute() {
super.onPreExecute();
pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();
}
@Override
protected String doInBackground(Void... params) {
try {
URL url = new URL("http://songo.eu.pn/db_GetFromSongs.php");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
resultJson = buffer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return resultJson;
}
@Override
protected void onPostExecute(String strJson) {
super.onPostExecute(strJson);
List<DataSongs> data = new ArrayList<>();
JSONObject dataJsonObj = null;
try {
dataJsonObj = new JSONObject(strJson);
JSONArray songs = dataJsonObj.getJSONArray("Songs");
DataSongs songData = new DataSongs();
for (int i = 0; i < songs.length(); i++) {
JSONObject song = songs.getJSONObject(i);
songData.songName = song.getString("song");
songData.songGenreID = song.getString("GenreID");
songData.songUserID = song.getString("UserID");
data.add(songData);
Log.e("songo", "SongName: " + data.get(i).songName);
}
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mAdapter = new RecyclerAdapter(MainActivity.this, data, mRecyclerView);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(MainActivity.this);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setLayoutManager(mLayoutManager);
} catch (JSONException e) {
e.printStackTrace();
}
pdLoading.dismiss();
}
}
RecyclerAdapter.java
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private Context context;
private LayoutInflater inflater;
List<DataSongs> data = Collections.emptyList();
public RecyclerAdapter(Context context, List<DataSongs> data, RecyclerView recyclerView) {
this.context = context;
inflater = LayoutInflater.from(context);
this.data = data;
this.recyclerView = recyclerView;
}
class ViewHolder extends RecyclerView.ViewHolder{
TextView tv_songName;
TextView tv_songGenreID;
TextView tv_songUserID;
public ViewHolder(View itemView) {
super(itemView);
tv_songName = (TextView) itemView.findViewById(R.id.tv_songName);
tv_songGenreID = (TextView) itemView.findViewById(R.id.tv_songGenreID);
tv_songUserID = (TextView) itemView.findViewById(R.id.tv_songUserID);
}
}
// Создает новые views (вызывается layout manager-ом)
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v=inflater.inflate(R.layout.recycler_item, parent,false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
DataSongs current = data.get(position);
holder.tv_songName.setText(current.songName);
holder.tv_songGenreID.setText(current.songGenreID);
holder.tv_songUserID.setText(current.songUserID);
Log.e("songo", "SongName: " + data.get(position).songName);
}
@Override
public int getItemCount() {
return data.size();
}
MainActivity的日志显示应该是的信息(没有相等的行)。
来自RecyclerAdapter的日志显示每个songName都是相同的。
答案 0 :(得分:6)
每次迭代都会覆盖相同的DataSongs实例。
int *
请注意, 新 关键字只会被调用一次 结果列表将多次包含相同的对象,并且它的属性将设置为列表中的最后一首歌。
只需在循环
中移动songData 的创建 DataSongs songData = new DataSongs();
for (int i = 0; i < songs.length(); i++) {
JSONObject song = songs.getJSONObject(i);
songData.songName = song.getString("song");
songData.songGenreID = song.getString("GenreID");
songData.songUserID = song.getString("UserID");
data.add(songData);
Log.e("songo", "SongName: " + data.get(i).songName);
}
答案 1 :(得分:2)
dataJsonObj = new JSONObject(strJson);
JSONArray songs = dataJsonObj.getJSONArray("Songs");
DataSongs songData = new DataSongs();
for (int i = 0; i < songs.length(); i++) {
JSONObject song = songs.getJSONObject(i);
songData.songName = song.getString("song");
songData.songGenreID = song.getString("GenreID");
songData.songUserID = song.getString("UserID");
data.add(songData);
Log.e("songo", "SongName: " + data.get(i).songName);
}
问题不在于与RecyclerView相关,它在创建对象.DataSongs对象只创建了一次,每次从JSON数组接收数据时都必须创建它。所以,在for循环中创建它:
dataJsonObj = new JSONObject(strJson);
JSONArray songs = dataJsonObj.getJSONArray("Songs");
for (int i = 0; i < songs.length(); i++) {
JSONObject song = songs.getJSONObject(i);
DataSongs songData = new DataSongs();
songData.songName = song.getString("song");
songData.songGenreID = song.getString("GenreID");
songData.songUserID = song.getString("UserID");
data.add(songData);
Log.e("songo", "SongName: " + data.get(i).songName);
}
答案 2 :(得分:1)
DataSongs songData = new DataSongs();
你的for循环中的这行代码需要每次创建新的json对象来解决这个问题
答案 3 :(得分:1)
试试这个
try {
dataJsonObj = new JSONObject(strJson);
JSONArray songs = dataJsonObj.getJSONArray("Songs");
DataSongs songData = null;
for (int i = 0; i < songs.length(); i++) {
songData = new DataSongs();
JSONObject song = songs.getJSONObject(i);
songData.songName = song.getString("song");
songData.songGenreID = song.getString("GenreID");
songData.songUserID = song.getString("UserID");
data.add(songData);
Log.e("songo", "SongName: " + data.get(i).songName);
}
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mAdapter = new RecyclerAdapter(MainActivity.this, data, mRecyclerView);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(MainActivity.this);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setLayoutManager(mLayoutManager);
} catch (JSONException e) {
e.printStackTrace();
}
答案 4 :(得分:0)
您正在循环外创建对象,因此,只创建了一个对象
public class MainActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
new parseTask().execute();
}
private class parseTask extends AsyncTask<Void, Void, String> {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String resultJson = "";
ProgressDialog pdLoading = new ProgressDialog(MainActivity.this, R.style.MyDialogStyle);
@Override
protected void onPreExecute() {
super.onPreExecute();
pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();
}
@Override
protected String doInBackground(Void... params) {
try {
URL url = new URL("http://songo.eu.pn/db_GetFromSongs.php");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
resultJson = buffer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return resultJson;
}
@Override
protected void onPostExecute(String strJson) {
super.onPostExecute(strJson);
List<DataSongs> data = new ArrayList<>();
JSONObject dataJsonObj = null;
try {
dataJsonObj = new JSONObject(strJson);
JSONArray songs = dataJsonObj.getJSONArray("Songs");
for (int i = 0; i < songs.length(); i++) {
JSONObject song = songs.getJSONObject(i);
/**
* you were wrong here
*/
DataSongs songData = new DataSongs();
songData.songName = song.getString("song");
songData.songGenreID = song.getString("GenreID");
songData.songUserID = song.getString("UserID");
data.add(songData);
Log.e("songo", "SongName: " + data.get(i).songName);
}
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mAdapter = new RecyclerAdapter(MainActivity.this, data, mRecyclerView);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(MainActivity.this);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setLayoutManager(mLayoutManager);
} catch (JSONException e) {
e.printStackTrace();
}
pdLoading.dismiss();
}
}