RecyclerView显示相同的项目

Gle*_*rin 0 java android recycler-adapter android-recyclerview

我正在尝试实现RecyclerView,显示来自JSONArray的数据.解析工作完美,但RecyclerView在每个项目中显示必须仅在最后一项中的信息.屏幕截图清楚地表明了这一点.

这是我的代码:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
}
Run Code Online (Sandbox Code Playgroud)

从MainActivity记录显示应该是的信息(没有相等的行).

来自RecyclerAdapter的日志显示每个songName都是相同的.

Rob*_*bCo 6

每次迭代都会覆盖相同的DataSongs实例.

        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);
        }
Run Code Online (Sandbox Code Playgroud)

请注意,new关键字只调用一次.
结果列表将多次包含相同的对象,并且其属性将设置为列表中的最后一首歌曲.

只需在循环移动songData的创建即可

        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);
        }
Run Code Online (Sandbox Code Playgroud)