Android 如何在recyclerview gridlayout中使用notifydatasetchanged

Android 如何在recyclerview gridlayout中使用notifydatasetchanged,android,android-asynctask,android-recyclerview,adapter,Android,Android Asynctask,Android Recyclerview,Adapter,我是android新手,正在尝试更新udacity nanodegree项目流行电影应用程序中的gridlayout 我正在使用AsyncTask下载数据并解析数据,更新recyclerview并在onPostExecute中设置适配器 这是我的AsyncTask类 private class getJson extends AsyncTask<String, Void, String>{ @Override protected String doInBackgro

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



    }
}
    private List<Movie> movieList = new ArrayList<>();
    private RecyclerView recyclerView;
    private MoviesAdapter mAdapter; 
一次创建

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()
,但我不知道在哪里使用它

另外,请告诉我处理分拣的更好方法

这就是我所做的:

  • 我将适配器的实例化和适配器的设置移动到onCreate
  • OnPostExecute()中调用
    notfiydatasetchanged()

  • 每次调用
    AsyncTask
    ,我的arraylist都会被新元素填充,因此适配器会填充所有图像。在解析
    onPostexecute()中的json之前,我是
    list.clear()

  • 对于http请求,我建议使用。 适配器在您想要的选项上描述排序函数,调用它,最后
    notifydatasetchanged()

    比如说

    void sort(String sortBy) {
        // your sort
        notifydatasetchanged();
    }
    

    如果要使用排序,只需调用对
    适配器进行排序的方法,将数据设置到其中。

    在活动的
    onCreate
    中设置
    适配器

        adapter = new MainRecyclerViewAdapter(MainActivity.this, list);
        recyclerView.setAdapter(adapter);
    
    使用字段存储列表

    调用
    AsyncTask
    onPostExecute()
    中的
    notifydatasetchanged()
    (就像您正在做的那样),但不要在那里重新分配
    适配器。

    就像这样,尝试以下操作:

    @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();
    
        }
    }
    
    @覆盖
    创建时受保护的void(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    recyclerView=(recyclerView)findViewById(R.id.main\u recyclerView);
    layoutManager=新的GridLayoutManager(MainActivity.this,2);
    recyclerView.setLayoutManager(layoutManager);
    适配器=新的MainRecycleServiceAdapter(MainActivity.this,列表);
    recyclerView.setAdapter(适配器);
    }
    私有类getJson扩展异步任务{
    @凌驾
    受保护的字符串背景(字符串…字符串){
    字符串结果=”;
    网址;
    HttpURLConnection HttpURLConnection=null;
    试一试{
    url=新url(字符串[0]);
    httpURLConnection=(httpURLConnection)url.openConnection();
    InputStream in=httpURLConnection.getInputStream();
    InputStreamReader reader=新的InputStreamReader(in);
    int data=reader.read();
    while(数据!=-1){
    当前字符=(字符)数据;
    结果+=电流;
    data=reader.read();
    }
    }捕获(java.io.ioe异常){
    e、 printStackTrace();
    }
    返回结果;
    }
    @凌驾
    受保护的void onPostExecute(字符串s){
    super.onPostExecute(s);
    jsonString=s;
    Log.i(“结果”,jsonString);
    JSONObject JSONObject=null;
    试一试{
    jsonObject=新的jsonObject(jsonString);
    JSONArray JSONArray=jsonObject.getJSONArray(“结果”);
    对于(int i=0;i

    请尝试一下,并让我知道它是否有效。

    您正在使用
    异步任务
    从远程服务器下载电影。下载和解析完成后,创建适配器并将其设置为
    RecyclerView

    recyclerView.setAdapter(mAdapter);
    
    根据您的实现,无需在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 {
                //...
            }
        }
    }
    
    活动{
    阵列列表数据;
    MainRecycleServiceAdapter适配器
    onCreate(){
    recyclerView=(recyclerView)findViewById(R.id.main\u recyclerView);
    recyclerView.setHasFixedSize(true);
    layoutManager=新的GridLayoutManager(MainActivity.this,2);
    recyclerView.setLayoutManager(layoutManager);
    适配器=新的MainRecycleServiceAdapter(MainActivity.this);
    recyclerView.setAdapter(适配器);
    }
    异步任务{
    /.....
    onPostExecute{
    //下载完成
    adapter.notifyDataSetChanged()
    }
    }
    主循环水泵{
    //...
    观众{
    //...
    }
    }
    }
    
    以下是您需要做的一切

    看看我的例子

    这些是全局变量

    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();
            }
    
    
    
        }
    }
    
        private List<Movie> movieList = new ArrayList<>();
        private RecyclerView recyclerView;
        private MoviesAdapter mAdapter; 
    
    2.创建我的列表的新实例

    mAdapter = new MoviesAdapter(movieList);
    
    3.设置我的回收视图

    recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    
            RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
            recyclerView.setLayoutManager(mLayoutManager);
            recyclerView.setItemAnimator(new DefaultItemAnimator());
    
    4.将适配器设置为my
    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()根据需要设置数据

    那罗吉怎么样