Android 单击“更新回收视图”按钮
我的Android应用程序中还有一个问题或bug。对不起,我是Android开发新手,但这是我的激情所在,我会坚持下去 无论如何,我的代码在CustomAdapter类中的方法调用中崩溃了 这是正在崩溃的CustomAdapter类: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
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);