Android 单击“更新回收视图”按钮

Android 单击“更新回收视图”按钮,android,android-recyclerview,adapter,Android,Android Recyclerview,Adapter,我的Android应用程序中还有一个问题或bug。对不起,我是Android开发新手,但这是我的激情所在,我会坚持下去 无论如何,我的代码在CustomAdapter类中的方法调用中崩溃了 这是正在崩溃的CustomAdapter类: public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder> { private ArrayList<UserInfo> ar

我的Android应用程序中还有一个问题或bug。对不起,我是Android开发新手,但这是我的激情所在,我会坚持下去

无论如何,我的代码在CustomAdapter类中的方法调用中崩溃了

这是正在崩溃的CustomAdapter类:

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder> {
private ArrayList<UserInfo> arrayList = new ArrayList<UserInfo>();
float ratings;

public CustomAdapter(ArrayList<UserInfo> arrayList){
    this.arrayList = arrayList;
}

@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.userslayout, parent, false);
    CustomViewHolder customViewHolder = new CustomViewHolder(view);
    return customViewHolder;
}

@Override
public void onBindViewHolder(final RecyclerViewHolder holder, int position) {
    final UserInfo userInfo = arrayList.get(position);
    holder.username.setText(userInfo.getMusicName());
    holder.forename.setText(userInfo.getMusicCategory());
    holder.surname.setText(userInfo.getFileType());
    // THE APP CRASHES WHEN I CLICK THIS BUTTON. THINGS UPDATE IN THE 
    // DATABASE - BUT THE RECYCLERVIEW CRASHES AND THE APP CRASHES
    holder.buttonRefresh.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String pressed = Integer.toString(userInfo.getPressedName());
            UserListRecycler userListRecycler = new UserListRecycler();
            UserListRecycler.UserPressedAsync userPressedAsync = userListRecycler.new UserPressedAsync();
            userPressedAsync.execute(username, pressed);
        }
    });
}
这是我的
PopulateUsers
类-通过
REST

public class PopulateUsers extends AsyncTask<String, String, String> {
    static ArrayList<UserInfo> list;
    UserAdapter adapter;
    RecyclerView recyclerView;

public PopulateUsers(ArrayList<UserInfo> list, UserAdapter adapter, RecyclerView recyclerView) {
    this.list = new ArrayList<UserInfo>(); 
    this.adapter = new UserAdapter();
    this.list = list;
    this.adapter = adapter;
    this.recyclerView = recyclerView;
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected String doInBackground(String... params) {
    // `REST` Activity happens here
}

@Override
protected void onPostExecute(String s) {
    try {
        list.clear();  
        JSONArray jsonArray = new JSONArray(s);
        for (int i = 0; i < jsonArray.length(); i++) {
            String forename = jsonArray.getJSONObject(i).getString("forename");
            String surname = jsonArray.getJSONObject(i).getString("surname");
            String nationality = jsonArray.getJSONObject(i).getString("nationality");
            UserInfo userInfo = new UserInfo(forename, surname, nationality);
            list.add(userInfo);
        }
        recyclerView.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    } catch (JSONException e) {
        e.printStackTrace();
    }
}
}

如果有人能帮我解决这个问题的话,这对我来说真的很有意义,事实上,我可以睡上一觉。这是一只可怕的虫子

该错误主要是因为您正在访问recyclerview,而其适配器尚未实例化。这是因为在后台设置时,在主线程中显示recyclerview。在您的情况下,两个线程不同步,因此当您单击按钮时,recyclerview尚未正确设置,因此会出现空指针异常

我建议您找到一个解决方法来显示数据,然后在显示之前设置您的recyclerview

使用asynctask进行web调用确实不是一个好主意,您通常必须使用诸如Reformation、gson、rxandroid等库,但由于您才刚刚开始,所以必须使用asynctask

我建议您在主线程中执行
recyclerView.setAdapter(adapter)
,就像在
onCreate
中一样,因为您没有显示recyclerView所需的数据,所以您必须先用伪数据进行设置,或者最好不要显示它,首先显示进度条,告知用户尚未完成加载


如果按照我的建议进行操作,则不必在asynctask中调用
recyclerView.setAdapter(adapter)
,只需通知它您有更改,这当然是您的
适配器。notifyDataSetChanged()

recyclerView.setAdapter(adapter)

你打了两次电话。为什么不把它留在
onCreateView
中,并从
postExecute
中删除它呢?只需将
适配器.notifyDataSetChanged()
留在postExecute中,并将其从onCreateView中删除即可。这有区别吗

我正在使用库凌空来完成这些任务,而且它相当容易使用。看起来也比
ASyncTask
更整洁。也许你可以试一试

请查看该页面:

如果克隆
Volley库
(下载文件夹),请通过
New>Import MODULE>path to library
将其导入Android Studio。然后,您需要将
编译项目(':volley')
放在应用程序的
构建梯度下的dependencies下-因此它看起来像这样:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:support-v4:23.1.1'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
    compile project(':volley')
}
这就是我从php服务下载
JSON
的方法:

  public void downloadEvents(String urlService) {


    RequestQueue requestQueue = Volley.newRequestQueue(getActivity()); //getActivity because I'm calling it from a fragment, if called in Activity, use 'this'
    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest
            (Request.Method.GET, urlService, null, new Response.Listener<JSONArray>() {

                @Override
                public void onResponse(JSONArray response) {

                    try {


                        for (int i = 0; i < response.length(); i++) {
                            JSONObject eventJson = response.getJSONObject(i);

                            String title = eventJson.getString("EventTitle");
                            String body = eventJson.getString("EventBody");
                            double price = Double.parseDouble(eventJson.getString("EventPrice"));
                            String date = eventJson.getString("EventDate");
                            String time = eventJson.getString("EventTime");
                            String place = eventJson.getString("EventPlace");
                            String organ = eventJson.getString("Organization");

                            Event event = new Event(title, body, price, date, time, durationStr, place, organ);
                            theEvents.add(event);
                            rAdapter.notifyItemInserted(i);
                        }


                        if (swipeRefreshLayout.isRefreshing()) {
                            swipeRefreshLayout.setRefreshing(false);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }


                }


            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.e("VOLLEY ERROR", "" + error);

                }
            }
            );

    requestQueue.add(jsonArrayRequest); //important to add that otherwise the download wont be initiated.
}
变成

 JsonObjectRequest jsonObjectRequest = new JsonObjectRequest 
            (Request.Method.GET, urlService, null, new Response.Listener<JSONObject>() {

下载方法只是通知适配器。

那么我该如何修复这个可怕的错误呢?我真的睡不着,我不停地把头撞在墙上。你有没有办法修复我的代码?当然,这是在到处移动一行,你的json从哪里来?来自api的
json
内容很好。我的数据库更新了,但是应用程序崩溃了,因为这个该死的
recyclerview
!!!!!!请问,你能告诉我在我的代码或类中放哪一行吗?这意味着很多我如何使用截击,有没有办法将我的代码转换成截击?我给了你一个几乎完整的截击教程。我希望这是直截了当的,对你有帮助。我(目前)使用这种方法的方式是设置数据,使列表和适配器位于同一个类(片段)中。这就是为什么我只是添加到列表中,并像那样通知我的适配器。谢谢,但是什么是
Event Event=新事件(标题、正文、价格、日期、时间、持续时间、地点、器官)?另外,如果我把截击代码放在一个单独的类中,它会工作吗?我认为它应该工作,但当我尝试它时,我遇到了各种各样的问题,它不工作,所以我把它放在同一个类中。哦,对不起,事件只是我自己的数据类型类。它与您的userInfo类完全相同。你做的和我一样-你创建一个userInfo对象并将其添加到列表中。您可以看到,您在onPostExecute中所做的与Volley中的onResponse方法相对应,只需将json数据放入变量中并在那里创建您的userInfo对象即可。您好,我尝试了您的方法,但它仍然会在
RequestQueue RequestQueue=Volley.newRequestQueue(getActivity())上出现
null指针异常
  public void downloadEvents(String urlService) {


    RequestQueue requestQueue = Volley.newRequestQueue(getActivity()); //getActivity because I'm calling it from a fragment, if called in Activity, use 'this'
    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest
            (Request.Method.GET, urlService, null, new Response.Listener<JSONArray>() {

                @Override
                public void onResponse(JSONArray response) {

                    try {


                        for (int i = 0; i < response.length(); i++) {
                            JSONObject eventJson = response.getJSONObject(i);

                            String title = eventJson.getString("EventTitle");
                            String body = eventJson.getString("EventBody");
                            double price = Double.parseDouble(eventJson.getString("EventPrice"));
                            String date = eventJson.getString("EventDate");
                            String time = eventJson.getString("EventTime");
                            String place = eventJson.getString("EventPlace");
                            String organ = eventJson.getString("Organization");

                            Event event = new Event(title, body, price, date, time, durationStr, place, organ);
                            theEvents.add(event);
                            rAdapter.notifyItemInserted(i);
                        }


                        if (swipeRefreshLayout.isRefreshing()) {
                            swipeRefreshLayout.setRefreshing(false);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }


                }


            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.e("VOLLEY ERROR", "" + error);

                }
            }
            );

    requestQueue.add(jsonArrayRequest); //important to add that otherwise the download wont be initiated.
}
 JsonArrayRequest jsonArrayRequest = new JsonArrayRequest
            (Request.Method.GET, urlService, null, new Response.Listener<JSONArray>() {
 JsonObjectRequest jsonObjectRequest = new JsonObjectRequest 
            (Request.Method.GET, urlService, null, new Response.Listener<JSONObject>() {
        recyclerView = (RecyclerView) fragmentView.findViewById(R.id.rv);
    LinearLayoutManager llm = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(llm);
    theEvents = new ArrayList<>();
    rAdapter = new RecyclerAdapter(theEvents, recyclerView);
    recyclerView.setAdapter(rAdapter);