问题
I'm having a tough time understanding the documentation for endless adapter
I tried following these quick steps by Commonsware to no avail: How can I use a custom adapter with the cwac-endless adapter?
So, first, you get your custom adapter working correctly on its own. Then, you create your EndlessAdapter subclass (with your implementation of cacheInBackground(), etc.), wrap your custom adapter in an instance of your EndlessAdapter subclass, and put your instance of your EndlessAdapter subclass in your ListView
I have three java classes. My activity, my regular adapter (that works before I tried to integrate endless adapter), and I have a subclassed endless adapter. I'm sure I'm just doing something small that is making this not trigger properly. My app does NOT crash, and it SHOWS my "Loading" view, it just never updates, and seems to load a lot of stuff afterwards because the gui really slows down. I'm probably stuck in some kind of loop. Any ideas?
My main activity:
package com.eghdk.myapp.gui;
import java.util.ArrayList;
import android.annotation.TargetApi;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.koushikdutta.async.future.FutureCallback;
import com.koushikdutta.ion.Ion;
import com.eghdk.myapp.R;
import com.eghdk.myapp.adapters.MyAdapter;
import com.eghdk.myapp.adapters.MyEndlessAdapter;
import com.eghdk.myapp.util.AppUtil;
public class MyBlog extends ListActivity {
String content;
String Url;
String title;
ArrayList<String> titles;
ArrayList<String> urls;
ArrayList<String> contents;
MyAdapter adapter;
int page = 1;
int count = 20;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_blog);
// Show the Up button in the action bar.
setupActionBar();
titles = new ArrayList<String>();
urls = new ArrayList<String>();
contents = new ArrayList<String>();
adapter = new MyAdapter(this, titles);
loadDataFromWeb(page, count);
}
}
/**
* Set up the {@link android.app.ActionBar}, if the API is available.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_my_blog, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
public void loadDataFromWeb(int page, int count) {
//I'm using Koushs Ion library to do Async Json calls.
Ion.with(
MyBlog.this,
"http://myblog.com/api/get_posts/?page=" + page + "&count="
+ count).asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
@Override
public void onCompleted(Exception e, JsonObject result) {
String status = result.getAsJsonPrimitive("status")
.getAsString();
if (!status.equals("ok")) {
Log.e("TAG", "api doesn't exist");
Log.e("TAG", "api doesn't");
}
JsonArray jsonPostArray = result
.getAsJsonArray("posts");
for (JsonElement jsonElementPost : jsonPostArray) {
JsonObject jsonPost = jsonElementPost
.getAsJsonObject();
int ID = jsonPost.get("id").getAsInt();
title = jsonPost.get("title").getAsString();
titles.add(title);
content = jsonPost.get("content").getAsString();
contents.add(content);
at = jsonPost.getAsJsonArray("attachments")
.get(0).getAsJsonObject();
Url = at.get("url").getAsString();
urls.add(Url);
}
// Log.d("TAG", ID + "");
done();
}
});
}
private void done() {
MyEndlessAdapter endless = new MyEndlessAdapter(adapter, this);
setListAdapter(endless);
}
}
MyAdapter.java:
package com.eghdk.myapp.adapters;
import java.util.ArrayList;
import android.R;
import android.content.Context;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class MyAdapter extends BaseAdapter {
ArrayList<String> titles;
Context context;
LayoutInflater mInflater;
public MyAdapter(Context context, ArrayList<String> list) {
titles = list;
this.context = context;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return titles.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if (convertView == null) {
convertView = mInflater.inflate(
android.R.layout.simple_list_item_1, parent, false);
}
((TextView) convertView.findViewById(R.id.text1)).setText(Html
.fromHtml(titles.get(position)));
return convertView;
}
}
EndlessAdapter:
package com.eghdk.myapp.adapters;
import java.util.ArrayList;
import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.TextView;
import com.commonsware.cwac.endless.EndlessAdapter;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.koushikdutta.async.future.FutureCallback;
import com.koushikdutta.ion.Ion;
public class MyEndlessAdapter extends EndlessAdapter { ArrayList tempList = new ArrayList(); protected String title; protected ArrayList titles; protected String content; protected String atUrl; ArrayAdapter oldadapter; int page = 1, count = 20; Context context;
public MyEndlessAdapter(ListAdapter wrapped, Context ctx) {
super(wrapped);
context = ctx;
titles = new ArrayList<String>();
oldadapter = (ArrayAdapter) wrapped;
// TODO Auto-generated constructor stub
}
@Override
protected void appendCachedData() {
// TODO Auto-generated method stub
oldadapter.addAll(titles);
}
@Override
protected View getPendingView(ViewGroup parent) {
// TODO Auto-generated method stub
TextView view = new TextView(context);
view.setText("LOADING");
return view;
}
@Override
protected boolean cacheInBackground() throws Exception {
Ion.with(
context,
"http://myblog.com/api/get_posts/?page=" + page + "&count="
+ count).asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
@Override
public void onCompleted(Exception e, JsonObject result) {
if (result == null) {
Log.e("TAG", "server crash");
Log.e("TAG", " crash");
}
String status = result.getAsJsonPrimitive("status")
.getAsString();
if (!status.equals("ok")) {
Log.e("TAG", "api doesn't exist");
Log.e("TAG", "api doesn't");
} else {
}
JsonArray jsonPostArray = result
.getAsJsonArray("posts");
int i = 0;
for (JsonElement jsonElementPost : jsonPostArray) {
Log.d("", i + "");
i++;
JsonObject jsonPost = jsonElementPost
.getAsJsonObject();
int ID = jsonPost.get("id").getAsInt();
String url = jsonPost.get("url").getAsString();
title = jsonPost.get("title").getAsString();
titles.add(title);
content = jsonPost.get("content").getAsString();
String date = jsonPost.get("date").getAsString();
try {
JsonObject cat = jsonPost
.getAsJsonArray("categories").get(0)
.getAsJsonObject();
String catTitle = cat.get("title")
.getAsString();
} catch (Exception e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
JsonObject author = jsonPost
.getAsJsonObject("author");
String name = author.get("name").getAsString();
JsonObject at = null;
try {
at = jsonPost.getAsJsonArray("attachments")
.get(0).getAsJsonObject();
atUrl = at.get("url").getAsString();
String atMime = at.get("mime_type")
.getAsString();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
atUrl = "";
}
}
// Log.d("TAG", ID + "");
// done();
}
});
return true;
}
}
回答1:
I'm sure I'm just doing something small that is making this not trigger properly.
Let's review the major headings of the "Usage" section of the documentation:
Constructors: you are calling the constructor on your
EndlessAdapter
subclassPlaceholder: you have implemented
getPendingView()
on yourEndlessAdapter
subclassThe Loading: you have implemented
cacheInBackground()
on yourEndlessAdapter
subclass, and while your implementation is strange (threeArrayList<String>
rather than oneArrayList<WhateverYourActualModelObjectShouldBe>
?), it probably worksThe Attaching: BZZZT -- your
appendCachedData()
does not do anythingThe Threading: your code should be fine, so long as you are not trying to use other
AsyncTasks
at the same time, or if yourandroid:targetSdkVersion
is under 13The Overriding: your code should be fine
So, I would recommend that you go back to The Attaching, read through that section, and peek at the demo app's implementation. Yours may be more complicated, as you chose to use BaseAdapter
rather than ArrayAdapter
, despite your data model being an array.
来源:https://stackoverflow.com/questions/21213657/endlessadapter-not-updating-with-updates-in-android-cwac-endlessadapter