简体   繁体   English

RecyclerView显示相同的项目

[英]RecyclerView shows the same items

I am trying to implement RecyclerView, showing the data from JSONArray. 我正在尝试实现RecyclerView,以显示JSONArray中的数据。 Parsing works perfect, but RecyclerView shows in every item the information that must be only in the last item. 解析工作完美,但是RecyclerView在每个项目中显示必须仅在最后一个项目中的信息。 There is the screenshot to make it clear. 有屏幕截图可以清楚地说明。

Here is my code: 这是我的代码:

MainActivity.java 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 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();
}

Log from MainActivity shows information as it should be (no equal lines). 来自MainActivity的日志按原样显示信息(无相等的行)。

Log from RecyclerAdapter shows that every songName is the same. RecyclerAdapter的日志显示每个songName都相同。

You are overriding the same DataSongs instance every iteration. 您每次迭代都覆盖相同的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);
        }

Note that the new keyword is only called once. 请注意, new关键字仅被调用一次。
The resulting list will contain the same object multiple times, and it's attributes are set to the last song in the list. 产生的列表将多次包含相同的对象,并且其属性设置为列表中的最后一首歌曲。

Simply move the creation of songData inside of the loop 只需在循环移动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);
        }
        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);
        }

The problem is not in RecyclerView related, it's in creating object .DataSongs object has been created only once , you have to create it every time you receive data from JSON array.So,create it inside for loop : 问题不在于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);
        }
DataSongs songData = new DataSongs(); 

for循环中的这一行代码每次都需要创建一个新的json对象来解决此问题

Try this 尝试这个

 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();
    }

You were creating the object outside the loop, as a result, there was only one object created 您正在循环外创建对象,因此,仅创建了一个对象

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();
            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM