我正在寻找一种方法来将onScroll侦听器强加到我的listview中。我已经阅读了很多关于使用的内容:
notifyDataSetChanged();
但是,老实说,我无法弄清楚如何将其实现到我的工作代码中。
目前,我使用PHP(JSON Response)从MySQL数据库中将一堆记录放入listview。一切正常,但我想限制首次启动活动时返回的记录数(我知道这是用PHP脚本中的SQL语句完成的),然后当用户滚动加载旧帖子并附加它们时到当前列表视图。我查看过NUMEROUS个例子,但是找不到与我目前的结构有关的任何例子。
这是我目前的代码:(LiveFeed.java)
public class LiveFeed extends SherlockListActivity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Used To Put Dark Icons On Light Action Bar
boolean isLight = ThemeList.THEME == R.style.Theme_Sherlock;
// Build Action Bar
menu.add("Refresh")
.setIcon(isLight ? R.drawable.ic_refresh : R.drawable.ic_refresh_inverse).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add("+ Add Post")
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
return true;
}
// Define Menu Item Actions
@Override
public boolean onOptionsItemSelected(MenuItem item) {
String menuItemTitle = item.getTitle().toString();
if(menuItemTitle.equals("Refresh")){
// Clear ArrayList
posts.clear();
// Re-Run AsyncTask
new FeedTask().execute();
}
if(menuItemTitle.equals("+ Add Post")){
Intent intent = new Intent(this, AddPost.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
return true;
}
private ArrayList<Feed> posts = new ArrayList<Feed>();
// Define JSON Nodes
private static final String TAG_ID = "id";
private static final String TAG_POST = "post";
private static final String TAG_TIME = "post_time";
@Override
public void onCreate(Bundle savedInstanceState) {
setTheme(ThemeList.THEME);
super.onCreate(savedInstanceState);
// Load All Posts
new FeedTask().execute();
// Get ListView
ListView lv = getListView();
// Selecting Single List Item Starts EditPost Activity
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// getting values from selected ListItem
String pid = ((TextView) view.findViewById(R.id.postid)).getText().toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(), EditPost.class);
// sending Post Id To EditPost Activity
in.putExtra(TAG_ID, pid);
// starting new activity and expecting some response back
startActivityForResult(in, 100);
}
});
}
// Response from Edit Product Activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// If Result Code 100 (edited/deleted post) - Reload Screen
if (resultCode == 100) {
Intent intent = getIntent();
finish();
startActivity(intent);
}
}
// AsyncTask To Pull In All Posts And Build ListView
private class FeedTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog progressDialog;
protected void onPreExecute() {
progressDialog = ProgressDialog.show(LiveFeed.this,"", "Loading. Please wait...", true);
}
@Override
protected Void doInBackground(Void... arg0) {
try {
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://www.mysite.com/android/login/get_posts.php");
HttpResponse httpResponse = httpClient.execute(httpPost);
String result = EntityUtils.toString(httpResponse.getEntity());
JSONArray jArray = new JSONArray(result);
JSONObject json_data = null;
for (int i = 0; i < jArray.length(); i++) {
json_data = jArray.getJSONObject(i);
Feed feed = new Feed();
feed.id = json_data.getString(TAG_ID);
feed.post = json_data.getString(TAG_POST);
feed.post_time = json_data.getString(TAG_TIME);
posts.add(feed);
}
}
catch (Exception e){
Log.e("ERROR", "Error loading JSON", e);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
setListAdapter(new FeedListAdaptor(LiveFeed.this, R.layout.feed, posts));
}
}
private class FeedListAdaptor extends ArrayAdapter<Feed> {
private ArrayList<Feed> posts;
public FeedListAdaptor(Context context, int textViewResourceId, ArrayList<Feed> items) {
super(context, textViewResourceId, items);
this.posts = items;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.feed, null);
}
Feed o = posts.get(position);
TextView ht = (TextView) v.findViewById(R.id.postid);
TextView tt = (TextView) v.findViewById(R.id.toptext);
TextView bt = (TextView) v.findViewById(R.id.bottomtext);
ht.setText(o.id);
tt.setText(o.post);
bt.setText(o.post_time);
return v;
}
}
// Define Variables Used To Build Feed
public class Feed {
String id;
String post;
String post_time;
}
}
提取结果的PHP脚本:(get_posts.php)
include('config.php');
$q=mysql_query("SELECT f.id, f.post, DATE_FORMAT(f.post_time, '%b %D, %Y %r') AS post_time, f.updated, u.firstname, u.lastname FROM feed f
INNER JOIN users u ON u.id=f.user__id WHERE archived='0' ORDER BY f.id DESC");
while($row=mysql_fetch_assoc($q))
$output[]=$row;
print json_encode($output);
mysql_close();
我正在考虑在初始帖子中传递一个起始编号来告诉PHP脚本要撤回多少结果。然后在每次在滚动期间获取结果时,返回下一个数字以用作从onScroll()调用的下一个SQL查询中的LIMIT。 (现在我的SQL查询没有设置任何LIMIT。)
我希望有人可以帮助我!
答案 0 :(得分:1)
我目前正在做类似的事情。您可以将setOnScrollListener用于ListView并按如下方式实现:
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
boolean isLastItemVisible = firstVisibleItem + visibleItemCount == totalItemCount;
if (isLastItemVisible) {
listOverscrolled();
}
}
比listOverscrolled方法做类似的事情:
if (!isLoadingData()) {
setLoadingData(true);
loadData();
}
并在loadData方法中启动加载数据的新AsyncTask。 我所做的是将最后下载的记录的id附加到url查询和SQL查询添加条件WHERE id&gt; last_id。每次请求更多记录时,以相同的顺序返回它们非常重要。
所以在你的情况下,它会是这样的:
lastId = feedListAdapter.get(feedListAdapter.count());
... and in AsyncTask ...
HttpPost httpPost = new HttpPost("http://www.mysite.com/android/login/get_posts.php?lastid=" + lastId);
比在OnPostExecute中你可以做类似的事情:
setLoading(false);
feedListAdapter.addAll(feeds);
feedListAdapter.notifyDataSetChanged();
当然必须先创建适配器。