我有大约 15,000 行的数据库表,我想将其显示在 ListView 中。我想显示前 100 个,当用户向下滚动到最后一个项目时,应该加载下一个 100 个(依此类推......)。我已经在 OnScrollListener() 上实现,它调用负责加载更多项目的 AsyncTask。我遇到的问题是,在将更多行添加到游标后,我的 SimpleCursorAdapter 没有更新。我试过 adapter.notifyDataSetChanged();但这没有任何作用。
这是列表监听器:
myListView.setOnScrollListener(new OnScrollListener(){
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int lastInScreen = firstVisibleItem + visibleItemCount;
if(resultCursor != null){
if(lastInScreen == totalItemCount && isLoadingMore == false){
isLoadingMore = true;
loadedPage ++;
new LoadBooks().execute();
}
}
}
public void onScrollStateChanged(AbsListView view, int scrollState) {}
});
这是我的 AsyncTask 类:
private class LoadBooks extends AsyncTask<String, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(FullIndex.this);
@Override
protected void onPreExecute() {
this.dialog.setMessage("Loading books...");
this.dialog.show();
}
@Override
protected Void doInBackground(String... arg0) {
try{
resultCursor = dbHelper.fetchBooks(0, loadedPage * LIMIT_RESULTS);
}catch(Exception e){
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(final Void unused){
if(resultCursor != null){
if(adapter == null){
startManagingCursor(resultCursor);
String[] from = new String[]{"name"};
int[] to = new int[]{R.id.book_item_tbx};
getListView().setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
adapter = new SimpleCursorAdapter(FullIndex.this, R.layout.book_item, resultCursor, from, to);
setListAdapter(adp);
}else{
adapter.notifyDataSetChanged();
}
}
if(dialog != null && dialog.isShowing()){
dialog.dismiss();
}
isLoadingMore = false;
}
}
新行已添加到 resultCursor 但列表未更新,我错过了什么?
最佳答案
我将发布一个代码,该代码用于在滚动事件中每条记录填充 10 条记录。
/**
* Called when the activity is first created.
*
* @param savedInstanceState
* the saved instance state
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_checkin_checkout_history);
Thread thread = new Thread() {
public void run() {
synchronized (this) {
fetchHistory(0);
handler.post(new Runnable() {
public void run() {
pd.dismiss();
displayUI();
};
});
}
}
};
thread.start();
}
/**
* Display the check in check out history list.
*/
private void displayUI() {
if ((checkInCheckOutHistoryList != null)
&& (checkInCheckOutHistoryList.size() > 0)) {
historyArrayList = new ArrayList<HashMap<String, String>>();
histroyListAdapter = new SimpleAdapter(
ViewCheckInCheckOutHistory.this, historyArrayList,
R.layout.multi_colummn_list_text_style_small, new String[] {
"assetTag", "gif" , "action", "actionTime"},
new int[] { R.id.list_content_column1,
R.id.list_content_imagecolumn,
R.id.list_content_column3,
R.id.list_content_column4});
// To add more items to list view on scroll event.
historyListView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view,
int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
int lastInScreen = firstVisibleItem + visibleItemCount;
if ((lastInScreen == totalItemCount) && !(loadingMore) && (lastInScreen < totalHistoryItemCount)) {
if (!firstInstance) {
openSlider();
}
fetchHistory(lastInScreen);
Thread thread = new Thread(null, loadMoreListItems);
thread.start();
}
}
});
}
}
// Runnable to load the items
private Runnable loadMoreListItems = new Runnable() {
@Override
synchronized public void run() {
// Set flag so we cant load new items 2 at the same time
loadingMore = true;
HashMap<String, String> historyObjectMap;
for (CheckInCheckOutHistory checkOutHistoryObj : checkInCheckOutHistoryList) {
historyObjectMap = new HashMap<String, String>();
historyObjectMap.put("assetTag",
checkOutHistoryObj.getAssetTag());
historyObjectMap.put("action", checkOutHistoryObj.getAction());
historyObjectMap.put("actionTime",
checkOutHistoryObj.getActionDate());
if (checkOutHistoryObj.getAction().equals("Checked out")) {
historyObjectMap.put("gif", R.drawable.radio_button_yellow
+ "");
} else {
historyObjectMap.put("gif", R.drawable.radio_button_green
+ "");
}
historyArrayList.add(historyObjectMap);
}
runOnUiThread(returnRes);
}
};
// Since we cant update our UI from a thread this Runnable takes care of
// that!
private Runnable returnRes = new Runnable() {
@Override
public void run() {
// Add the new items to the adapter
if (historyArrayList != null && historyArrayList.size() > 0) {
histroyListAdapter.notifyDataSetChanged();
}
if (firstInstance) {
historyListView.setAdapter(histroyListAdapter);
firstInstance = false;
}
historyListLayout.setVisibility(View.VISIBLE);
// Done loading more.
loadingMore = false;
if ((slidingDrawer.isOpened()) && (!loadingMore)) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
slidingDrawer.close();
slidingDrawer.setVisibility(View.GONE);
}
}, 1000);
}
}
};
fetchHistory(int count) 是我用来设置 totalHistoryItemCount 和 checkInCheckOutHistoryList 值的方法。
希望这会有所帮助。
关于Android:无限滚动 - ListView 和 Cursor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6573489/
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
当我写下面的代码时:x=[1,2,3]x我得到这个输出:[1,2,3,[...]][1,2,3,[...]][1,2,3,[...]]我不应该只得到[1,2,3,[1,2,3]]吗?解释是什么? 最佳答案 这没什么奇怪的。数组的第四个元素就是数组本身,所以当你求第四个元素时,你得到的是数组,当你求第四个元素的第四个元素时,你得到的是数组,当你求第四个元素时,你得到的是数组。第四个元素的第四个元素的第四个元素的元素......你得到了数组。就这么简单。唯一有点不寻常的是Array#to_s检测到这样的递归,而不是进入无限循环,而是返回
因此,我们的页面中有以下代码:OnOff这是2个单选按钮。'开和关'。“关闭”是默认值。使用Watir-webdriver和Ruby,我们想要选择“打开”单选按钮。我们这样做:browser.radio(:id=>"HasRegistration_true").set但在这样做时,我们得到以下错误:`WebElement.clickElement':Elementcannotbescrolledintoview:[objectHTMLInputElement](Selenium::WebDriver::Error::MoveTargetOutOfBoundsError)我们知道Sele
我在使用Arel聚契约(Contract)一查询中的2列时遇到了问题。当我运行它时,在railsdev-server崩溃之前,整个服务器会卡住一分钟。我怀疑是无限循环:)。也许我误解了Arel的整个概念,如果有人能看一下,我将不胜感激。这个查询的预期结果是这样的:[{:user_id=>1,:sum_account_charges=>300,:sum_paid_debts=>1000},...]a_account_charges=Table(:account_charges)a_paid_debts=Table(:paid_debts)a_participants=Table(:exp
我下面有一个ruby脚本,它无限地打印从1开始的数字。如何通过终端中的中断(如“Ctrl+C”或键“q”)使脚本停止无限执行?a=0while(a)putsaa+=1#thecodeshouldquitifaninterruptofacharacterisgivenend在每次迭代中,不应询问用户输入。 最佳答案 使用Kernel.trap为Ctrl-C安装信号处理程序:#!/usr/bin/rubyexit_requested=falseKernel.trap("INT"){exit_requested=true}while!
运行有问题或需要源码请点赞关注收藏后评论区留言一、利用ContentResolver读写联系人在实际开发中,普通App很少会开放数据接口给其他应用访问。内容组件能够派上用场的情况往往是App想要访问系统应用的通讯数据,比如查看联系人,短信,通话记录等等,以及对这些通讯数据及逆行增删改查。首先要给AndroidMaifest.xml中添加响应的权限配置 下面是往手机通讯录添加联系人信息的例子效果如下分成三个步骤先查出联系人的基本信息,然后查询联系人号码,再查询联系人邮箱代码 ContactAddActivity类packagecom.example.chapter07;importandroid
1.前言 在10.0的系统rom定制化开发中,在系统中有多个launcher的时候,会在开机进入launcher的时候弹窗launcher列表,让用户选择进入哪个launcher,这样显得特别的不方便所以产品开发中,要求用RoleManager的相关api来设置默认Launcher,但是在设置完默认Launcher以后,在安装一款Launcher的时候,默认Launcher就会失效,在系统设置的默认应用中Launcher选项就为空,点击home键的时候会弹出默认Launcher列表,让选择进入哪个默认Launcher.所以需要从安装Launcher的流程来分析相关的设置。来解决问题设置默认La
编辑:(已解决)实际上它可能是因为无限循环而引发的我正在编码,在添加一个方法后我得到了这个:user_name@the_computer:/media/ECC3-C3B0/Prog/mts/src/mts$raketest--trace**Invoketest(first_time)**Executetest/home/user_name/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:stackleveltoodeep(SystemStackError)rakeabo
我和我的friend们正在做一些基本的Ruby练习来感受这门语言,我们遇到了一个我们还无法理解的有趣行为。基本上,我们正在创建一个tree只有一个类的数据类型,node,它只包含一个值和一个包含零个或多个nodes的数组.我们正在使用rspec的autospec测试运行程序。有一次,我们开始编写测试以禁止无限递归(循环树结构)。这是我们的测试:it"breaksonacircularreference,whichwewillfixlater"dotree1=Node.new1tree2=Node.new1tree2.add_childtree1tree1.add_childtree2(