我试图让我的ListView在达到列表底部后添加更多项目。我一直遇到的问题是列表冻结一旦到达底部而不是更新视图。在EndlessScrollListenener中,我检查最后一项是否可见,如果是,我们在列表帖子中添加更多帖子。然后我做一个notifyDataSetChanged()但它不工作。有什么帮助吗?
这是我的习惯 EndlessScrollListener 类:
import java.util.ArrayList;
import java.util.List;
import sukh.app.ireddit.PostsFragment.PostAdapter;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ArrayAdapter;
public class EndlessScrollListener implements OnScrollListener {
List<Post> posts;
PostsHolder postsHolder;
ArrayAdapter<Post> postAdapter;
private int count, incrementSize;
public EndlessScrollListener() {
}
public EndlessScrollListener(List<Post> posts, PostsHolder postsHolder, ArrayAdapter<Post> adapter){
this.posts = posts;
this.postsHolder = postsHolder;
this.postAdapter = adapter;
count = incrementSize = adapter.getCount();
}
public void onScroll(AbsListView view, int firstVisible, int visibleCount, int totalCount) {
// TODO Auto-generated method stub
boolean loadMore =
firstVisible + visibleCount >= totalCount;
if(loadMore) {
count += incrementSize; // or any other amount
new Thread(){
public void run(){
posts.addAll(postsHolder.fetchMorePosts());
}
}.start();
postAdapter.notifyDataSetChanged();
}
}
@Override
public void onScrollStateChanged(AbsListView arg0, int arg1) {
// TODO Auto-generated method stub
}
}
我的 PostFragment 类
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
/**
* While this looks like a lot of code, all this class
* actually does is load the posts in to the listview.
*/
public class PostsFragment extends Fragment{
ListView postsList;
ArrayAdapter<Post> adapter;
Handler handler;
String subreddit;
List<Post> posts;
PostsHolder postsHolder;
public PostsFragment(){
handler=new Handler();
posts=new ArrayList<Post>();
}
public static Fragment newInstance(String subreddit){
PostsFragment pf=new PostsFragment();
pf.subreddit=subreddit;
pf.postsHolder=new PostsHolder(pf.subreddit);
return pf;
}
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.posts
, container
, false);
postsList=(ListView)v.findViewById(R.id.posts_list);
return v;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initialize();
}
private void initialize(){
// This should run only once for the fragment as the
// setRetainInstance(true) method has been called on
// this fragment
if(posts.size()==0){
// Must execute network tasks outside the UI
// thread. So create a new thread.
new Thread(){
public void run(){
posts.addAll(postsHolder.fetchPosts());
// UI elements should be accessed only in
// the primary thread, so we must use the
// handler here.
handler.post(new Runnable(){
public void run(){
createAdapter();
}
});
}
}.start();
}else{
createAdapter();
}
}
/**
* This method creates the adapter from the list of posts
* , and assigns it to the list.
*/
private void createAdapter(){
// Make sure this fragment is still a part of the activity.
if(getActivity()==null) return;
adapter=new PostAdapter(posts);
postsList.setAdapter(adapter);
postsList.setOnScrollListener(new EndlessScrollListener(posts, postsHolder, adapter));
}
protected class PostAdapter extends ArrayAdapter<Post> {
public int incrementSize
, count = 0;
public PostAdapter(List<Post> posts){
super(getActivity(), R.layout.post_item, posts);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = getActivity().getLayoutInflater().inflate(R.layout.post_item, null);
}
Post thePost = getItem(position);
TextView postTitleTextView = (TextView) convertView.findViewById(R.id.post_title);
postTitleTextView.setText(thePost.getTitle());
TextView postDetailsTextView = (TextView) convertView.findViewById(R.id.post_details);
postDetailsTextView.setText(thePost.getDetails());
TextView postScoreTextView = (TextView) convertView.findViewById(R.id.post_score);
postScoreTextView.setText(thePost.getScore());
return convertView;
}
}
}
我的 PostsHolder 类:
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import android.util.Log;
/**
* This is the class that creates Post objects out of the Reddit
* API, and maintains a list of these posts for other classes
*/
public class PostsHolder {
/**
* We will be fetching JSON data from the API.
*/
private final String URL_TEMPLATE=
"http://www.reddit.com/r/SUBREDDIT_NAME/"
+".json"
+"?after=AFTER";
String subreddit;
String url;
String after;
PostsHolder(String sr){
subreddit=sr;
after="";
generateURL();
}
/**
* Generates the actual URL from the template based on the
* subreddit name and the 'after' property.
*/
private void generateURL(){
url=URL_TEMPLATE.replace("SUBREDDIT_NAME", subreddit);
url=url.replace("AFTER", after);
}
/**
* Returns a list of Post objects after fetching data from
* Reddit using the JSON API.
*
* @return
*/
ArrayList<Post> fetchPosts(){
String raw=RemoteData.readContents(url);
ArrayList<Post> list=new ArrayList<Post>();
try{
JSONObject data=new JSONObject(raw)
.getJSONObject("data");
JSONArray children=data.getJSONArray("children");
//Using this property we can fetch the next set of
//posts from the same subreddit
after=data.getString("after");
for(int i=0;i<children.length();i++){
JSONObject cur=children.getJSONObject(i)
.getJSONObject("data");
Post p = new Post();
p.title=cur.optString("title");
p.url=cur.optString("url");
p.numComments=cur.optInt("num_comments");
p.points=cur.optInt("score");
p.author=cur.optString("author");
p.subreddit=cur.optString("subreddit");
p.permalink=cur.optString("permalink");
p.domain=cur.optString("domain");
p.id=cur.optString("id");
if(p.title!=null)
list.add(p);
}
}catch(Exception e){
Log.e("fetchPosts()",e.toString());
}
return list;
}
/**
* This is to fetch the next set of posts
* using the 'after' property
* @return
*/
List<Post> fetchMorePosts(){
generateURL();
return fetchPosts();
}
}
答案 0 :(得分:0)
添加帖子后,您应该通知postAdapter.notifyDataSetChanged();
。现在Thread
runnable
可以在postAdapter.notifyDataSetChanged()
之后结束。