为什么在加载模型后实例化适配器时为什么需要使用notifyDataSetChanged()?

问题描述 投票:0回答:1

[目标:使用齐射导入JSON并设置回收器视图以显示一长串我从JSON解析的口袋妖怪列表(我正在制作一个Pokedex)。

代码摘要:自定义适配器(称为PokemonAdapter),但实际上是在做普通的适配器事情;它只是指定如何膨胀新视图以及要设置的文本。我的MainActivity是我遇到麻烦的地方。在onCreate中,我first加载了JSON数据集,then将适配器对象设置为新的PokemonAdapter。我的代码已编译,在运行时未产生错误,但也未产生列表。那是我了解notifyDataSetChanged()方法的时候。我不明白为什么会那么重要,但也看不出来为什么会那么疼,所以我尝试了一下,就奏效了。

我有点困惑。我想知道是否有人可以解释为什么即使我在加载数据后设置了适配器也需要更新适配器。是因为我最初在加载方法用法的上方声明了适配器吗?我是OOP的新手,所以我对声明和实例化有些困惑。

public class MainActivity extends AppCompatActivity {

    private List<Pokemon> pokemonDB = new ArrayList<>();
    private RequestQueue queue;

    /** RECYCLER VIEW */

    /* Obtain handles for Recycler View components*/
    private RecyclerView recyclerView;
    private RecyclerView.Adapter adapter;
    private RecyclerView.LayoutManager layoutManager;

    /** METHODS */

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        loadPokemon();

        /* Setting up the Recycler View*/
        // Link it to XML doc to inflate recycler object
        recyclerView = findViewById(R.id.recycler_view);
        // initialize layout manager and use setter method
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        // Initialize a new adapter using the PokemonAdapter class and use setter method
        adapter = new PokemonAdapter(pokemonDB);
        recyclerView.setAdapter(adapter);
    }

    /* Load JSON from Poke API using volley protocol */
    public void loadPokemon() {

        //Instantiate the RequestQueue
        queue = Volley.newRequestQueue(this);
        String url = "https://pokeapi.co/api/v2/pokemon/?limit=151";

        // request a JSON response from the provided URL
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
                (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONArray jsonResultsArray = response.getJSONArray("results");

                    for (int i = 0; i < jsonResultsArray.length(); i++) {
                        JSONObject pokemonResult = jsonResultsArray.getJSONObject(i);
                        String pokemonName = pokemonResult.getString("name");
                        String pokemonUrl = pokemonResult.getString("url");
                        // Now, add this data to a pokemon object in the pokemonDB array list
                        pokemonDB.add(new Pokemon(pokemonName, pokemonUrl));
                    }
                    //this notifies the adapter that the data has changed
                    adapter.notifyDataSetChanged();
                }
                catch (JSONException e) {
                    Log.e("cs50", "Error parsing JSON pokedex objects.");
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("cs50", "error retrieving JSON pokedex database.");
            }
        }
        );

        // Add the request to the queue
        queue.add(jsonObjectRequest);
    }
}
android-volley recycler-adapter android-adapter
1个回答
1
投票

加载数据可能需要一段时间。因此,可能在下载数据之前设置了回收站视图适配器,并且没有要显示的项目。因此,在获取所有数据之后,我们必须在响应侦听器中使用notifyDataSetChanged()方法,以更新回收者视图。

© www.soinside.com 2019 - 2024. All rights reserved.