我想开发一个网站的Android应用程序。我从json阅读网站帖子并在每10个帖子中显示它在RecyclerView中,当用户在RecyclerView上滚动显示更多10个帖子并结束时!在这个项目中我使用okHTTP v3,Glide和RecyclerView!
Json链接: JSON LINK
我可以加载前10个帖子,但是当在RecyclerView上滚动并显示其他10个帖子时,请告诉我这个错误:
04-27 15:34:33.599 3249-3249/com.tellfa.colony E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.tellfa.colony, PID: 3249
java.lang.IndexOutOfBoundsException: Invalid index 11, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.tellfa.colony.Activities.Main_page$1$1.run(Main_page.java:95)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5349)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
主要活动代码:
public class Main_page extends AppCompatActivity {
private static final long RIPPLE_DURATION = 250;
private Toolbar toolbar;
private RelativeLayout root;
private ImageView menu_image;
private RecyclerView main_recyclerView;
private MainAdapter2 mAdaper;
private List<MainDataModel> dataModels = new ArrayList<MainDataModel>();
private List<MainDataModel> dataModelsArray;
private Context context;
protected Handler handler;
private RelativeLayout loadLayout;
private LinearLayoutManager mLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_page);
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this);
}
handler = new Handler();
context = getApplicationContext();
loadLayout = (RelativeLayout) findViewById(R.id.main_empty_layout);
toolbar = (Toolbar) findViewById(R.id.main_toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(null);
}
LoadData();
mLayoutManager = new LinearLayoutManager(this);
// Menu
root = (RelativeLayout) findViewById(R.id.main_root);
View guillotineMenu = LayoutInflater.from(this).inflate(R.layout.menu_layout, null);
root.addView(guillotineMenu);
menu_image = (ImageView) toolbar.findViewById(R.id.toolbar_logo);
new GuillotineAnimation.GuillotineBuilder(guillotineMenu, guillotineMenu.findViewById(R.id.menu_layout_image), menu_image)
.setStartDelay(RIPPLE_DURATION)
.setActionBarViewForAnimation(toolbar)
.setClosedOnStart(true)
.build();
// RecyclerView and setData
main_recyclerView = (RecyclerView) findViewById(R.id.main_recycler);
main_recyclerView.setHasFixedSize(true);
main_recyclerView.setLayoutManager(mLayoutManager);
mAdaper = new MainAdapter2(this, main_recyclerView, dataModels);
main_recyclerView.setAdapter(mAdaper);
mAdaper.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore() {
dataModels.add(null);
mAdaper.notifyItemInserted(dataModels.size() - 1);
dataModelsArray = new ArrayList<MainDataModel>();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
dataModels.remove(dataModels.size() - 1);
mAdaper.notifyItemRemoved(dataModels.size());
int start = dataModels.size();
int end = start + 10;
for (int i = start + 1; i <= end; i++) {
dataModels.add(new MainDataModel(dataModelsArray.get(i).getId(),
dataModelsArray.get(i).getTitle(),
dataModelsArray.get(i).getContent(),
dataModelsArray.get(i).getThumbnail()));
mAdaper.notifyItemInserted(dataModels.size());
}
mAdaper.setLoaded();
}
}, 1000);
}
});
}
@Subscribe
public void onEvent(List<MainDataModel> mainInfoModels) {
mAdaper.add(mainInfoModels);
if (dataModels.isEmpty()) {
main_recyclerView.setVisibility(View.GONE);
loadLayout.setVisibility(View.VISIBLE);
} else {
main_recyclerView.setVisibility(View.VISIBLE);
loadLayout.setVisibility(View.GONE);
}
}
private void LoadData() {
MainDataInfo dataInfo = new MainDataInfo();
// here getMainDataInfo() should return the server response
dataInfo.getMainDataInfo(this);
}
}
AsyncTask代码:
public class MainDataInfo {
private Context mContext;
private String ServerAddress = ServerIP.getIP();
public void getMainDataInfo(Context context) {
mContext = context;
new getInfo().execute(ServerAddress + "page=1");
}
private class getInfo extends AsyncTask<String, Void, String> {
EventBus bus = EventBus.getDefault();
private String ou_response;
private List<MainDataModel> infoModels;
@Override
protected void onPreExecute() {
CustomProcessDialog.createAndShow(mContext);
infoModels = new ArrayList<>();
}
@Override
protected String doInBackground(String... params) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(ServerAddress + "page=1")
.cacheControl(CacheControl.FORCE_NETWORK)
.build();
Response response;
try {
response = client.newCall(request).execute();
ou_response = response.body().string();
response.body().close();
if (ou_response != null) {
try {
JSONObject postObj = new JSONObject(ou_response);
JSONArray postsArray = postObj.optJSONArray("posts");
infoModels = new ArrayList<>();
for (int i = 0; i <= infoModels.size(); i++) {
JSONObject postObject = (JSONObject) postsArray.get(i);
JSONObject images=postObject.optJSONObject("thumbnail_images");
JSONObject imagesPair=images.optJSONObject("medium");
int id = postObject.getInt("id");
String title = postObject.getString("title");
String content = postObject.getString("content");
String thumbnail = imagesPair.getString("url");
Log.d("Data", "Post id: " + id);
Log.d("Data", "Post title: " + title);
Log.d("Data", "Post title: " + thumbnail);
//Use the title and id as per your requirement
infoModels.add(new MainDataModel(id, title, content, thumbnail));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
return ou_response;
}
@Override
protected void onPostExecute(String result) {
CustomProcessDialog.dissmis();
if (result != null) {
bus.post(infoModels);
}
}
}
}
用于加载更多数据我使用接口类:OnLoadMoreListener
注意:请不要给我负面的积分,帮助我,我真的需要你的帮助!谢谢所有&lt; 3我该如何解决?
答案 0 :(得分:0)
更改此代码
mAdaper.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore() {
dataModels.add(null);
mAdaper.notifyItemInserted(dataModels.size() - 1);
dataModelsArray = new ArrayList<MainDataModel>();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
dataModels.remove(dataModels.size() - 1);
mAdaper.notifyItemRemoved(dataModels.size());
int start = dataModels.size();
int end = start + 10;
for (int i = start + 1; i <= end; i++) {
dataModels.add(new MainDataModel(dataModelsArray.get(i).getId(),
dataModelsArray.get(i).getTitle(),
dataModelsArray.get(i).getContent(),
dataModelsArray.get(i).getThumbnail()));
mAdaper.notifyItemInserted(dataModels.size());
}
mAdaper.setLoaded();
}
}, 1000);
}
});
到
mAdaper.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore() {
dataModels.add(null);
mAdaper.notifyItemInserted(dataModels.size() - 1);
LoadData(pageNumber);
}
});
并更改此方法:
@Subscribe
public void onEvent(List<MainDataModel> mainInfoModels) {
mAdaper.add(mainInfoModels);
if (dataModels.isEmpty()) {
main_recyclerView.setVisibility(View.GONE);
loadLayout.setVisibility(View.VISIBLE);
} else {
main_recyclerView.setVisibility(View.VISIBLE);
loadLayout.setVisibility(View.GONE);
}
}
于: int pageNumber = 1; @订阅 public void onEvent(List mainInfoModels){
if(dataModels.size()>0){
dataModels.remove(dataModels.size() - 1);
mAdaper.notifyItemRemoved(dataModels.size());
mAdaper.setLoaded();
}
mAdaper.add(mainInfoModels);
mAdapter.notifyDataSetChanged();
pageNumber++;
if (dataModels.isEmpty()) {
main_recyclerView.setVisibility(View.GONE);
loadLayout.setVisibility(View.VISIBLE);
} else {
main_recyclerView.setVisibility(View.VISIBLE);
loadLayout.setVisibility(View.GONE);
}
}
这只是我理解的概述:你没有对dataModelsArray做任何事情。 看看这个希望这有帮助。因为你没有提供所有代码
编辑: 对于你的第二个答案,你说10个帖子被重复显示,因为你没有传递页码:
更改此方法:
public void getMainDataInfo(Context context) {
mContext = context;
new getInfo().execute(ServerAddress + "page=1");
}
为:
public void getMainDataInfo(Context context, int pageNumber) {
mContext = context;
new getInfo().execute(ServerAddress + "page="+pageNumber);
}
将此方法更改为:
private void LoadData() {
MainDataInfo dataInfo = new MainDataInfo();
// here getMainDataInfo() should return the server response
dataInfo.getMainDataInfo(this);
}
到
private void LoadData(int pageNumber) {
MainDataInfo dataInfo = new MainDataInfo();
// here getMainDataInfo() should return the server response
dataInfo.getMainDataInfo(this, pageNumber);
}
将LoadData()更改为LoadData(pageNumber)
在您的活动类中创建一个整数,在获得响应时递增它,并将递增的pageNumber传递给此方法。
谢谢希望它解决你的问题。接受它作为答案,因为其他人可以得到想法。
答案 1 :(得分:0)
尝试此代码:
并删除Don不使用您的MainDataInfo类。我已经在Main_Page.java中实现了它。
你的Main_Page.java:
public class Main_page extends AppCompatActivity {
private static final long RIPPLE_DURATION = 250;
private Toolbar toolbar;
private RelativeLayout root;
private ImageView menu_image;
private RecyclerView main_recyclerView;
private MainAdapter2 mAdaper;
private List<MainDataModel> dataModels = new ArrayList<MainDataModel>();
protected Handler handler;
private RelativeLayout loadLayout;
private LinearLayoutManager mLayoutManager;
private int pageCount = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_page);
handler = new Handler();
loadLayout = (RelativeLayout) findViewById(R.id.main_empty_layout);
toolbar = (Toolbar) findViewById(R.id.main_toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(null);
}
LoadData(pageCount);
mLayoutManager = new LinearLayoutManager(Main_page.this);
// Menu
root = (RelativeLayout) findViewById(R.id.main_root);
View guillotineMenu = LayoutInflater.from(Main_page.this).inflate(R.layout.menu_layout, null);
root.addView(guillotineMenu);
menu_image = (ImageView) toolbar.findViewById(R.id.toolbar_logo);
new GuillotineAnimation.GuillotineBuilder(guillotineMenu, guillotineMenu.findViewById(R.id.menu_layout_image), menu_image)
.setStartDelay(RIPPLE_DURATION)
.setActionBarViewForAnimation(toolbar)
.setClosedOnStart(true)
.build();
// RecyclerView and setData
main_recyclerView = (RecyclerView) findViewById(R.id.main_recycler);
main_recyclerView.setHasFixedSize(true);
main_recyclerView.setLayoutManager(mLayoutManager);
mAdaper.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore() {
dataModels.add(null);
mAdaper.notifyItemInserted(dataModels.size() - 1);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
dataModels.remove(dataModels.size() - 1);
mAdaper.notifyItemRemoved(dataModels.size());
LoadData(++pageCount);
}
}, 1000);
}
});
}
/*
@Subscribe
public void onEvent(List<MainDataModel> mainInfoModels) {
mAdaper.add(mainInfoModels);
if (dataModels.isEmpty()) {
main_recyclerView.setVisibility(View.GONE);
loadLayout.setVisibility(View.VISIBLE);
} else {
main_recyclerView.setVisibility(View.VISIBLE);
loadLayout.setVisibility(View.GONE);
}
}*/
private void LoadData(int pageNumber) {
new APIInfoAsyncTask().execute(ServerAddress + "page=" + pageNumber);
}
private class APIInfoAsyncTask extends AsyncTask<String, Void, List<MainDataModel>> {
private String ou_response;
@Override
protected void onPreExecute() {
CustomProcessDialog.createAndShow(Main_page.this);
}
@Override
protected List<MainDataModel> doInBackground(String... params) {
OkHttpClient client = new OkHttpClient();
List<MainDataModel> responseData = new ArrayList<>();
Request request = new Request.Builder()
.url(ServerAddress + "page=1")
.cacheControl(CacheControl.FORCE_NETWORK)
.build();
Response response;
try {
response = client.newCall(request).execute();
ou_response = response.body().string();
response.body().close();
if (ou_response != null) {
try {
JSONObject postObj = new JSONObject(ou_response);
JSONArray postsArray = postObj.optJSONArray("posts");
infoModels = new ArrayList<>();
for (int i = 0; i <= infoModels.size(); i++) {
JSONObject postObject = (JSONObject) postsArray.get(i);
JSONObject images = postObject.optJSONObject("thumbnail_images");
JSONObject imagesPair = images.optJSONObject("medium");
int id = postObject.getInt("id");
String title = postObject.getString("title");
String content = postObject.getString("content");
String thumbnail = imagesPair.getString("url");
Log.d("Data", "Post id: " + id);
Log.d("Data", "Post title: " + title);
Log.d("Data", "Post title: " + thumbnail);
//Use the title and id as per your requirement
responseData.add(new MainDataModel(id, title, content, thumbnail));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
return responseData;
}
@Override
protected void onPostExecute(List<MainDataModel> result) {
CustomProcessDialog.dissmis();
dataModels.addAll(result);
mAdaper = new MainAdapter2(Main_page.this, main_recyclerView, dataModels);
main_recyclerView.setAdapter(mAdaper);
}
}
}
使用您的适配器类而不进行任何编辑,并且不要使用EventBus。