使用扩展BaseAdapter的自定义适配器刷新ListView(Refresh ListView with custom adapter that extends BaseAdapter)
我正在使用
ListView
,它由扩展BaseAdapter
自定义适配器填充。 使用AsyncTask
从外部服务器获取数据,AsyncTask
onPostExecute方法调用ListActivity上的方法,该方法将适配器设置为显示数据
ListView
还实现OnScrollListener
以在滚动时获取数据并添加到底部。我有一个带有自定义视图的
ActionBar
(Toolbar
),其中包含EditText
字段和单击Button
,同样,调用相同的AsyncTask
以从Toolbar
传递查询值来获取新数据。问题是,当单击工具栏上的按钮时,我希望
ListView
填充全新数据替换旧值,而是在列表底部附加新数据(就像调用OnClickListener
)。当然主要的打击是使用
NotifyDataSetChange
,我也使用它但不值得。我的方法来设置适配器
public void setBusinesses(ArrayList<BusinessListData> businesses) { imgFetcher = new BusinessListIconTask(this); layoutInflator = LayoutInflater.from(this); if (this.businesses == null || adapter == null) { this.businesses = new ArrayList<>(); adapter = new BusinessListDataAdapter(this, imgFetcher, layoutInflator, this.businesses); businessList.setAdapter(adapter); } this.businesses.addAll(businesses); adapter.notifyDataSetChanged(); /* Activates when scrolling to bottom of list */ businessList.setOnScrollListener(new OnScrollListener() { public int currentScrollState; public int currentFirstVisibleItem; public int currentVisibleItemCount; public int totalItemCount; public int lastItem; boolean isLoading = false; public void onScrollStateChanged(AbsListView view, int scrollState) { this.currentScrollState = scrollState; this.isScrollCompleted(); } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { this.currentFirstVisibleItem = firstVisibleItem; this.currentVisibleItemCount = visibleItemCount; this.totalItemCount = totalItemCount; this.lastItem = firstVisibleItem + visibleItemCount; } private void isScrollCompleted() { if (this.lastItem == this.totalItemCount) { /*** In this way I detect if there's been a scroll which has completed ***/ if (!isLoading) { isLoading = true; getScrollData(metroTxt, metroLoc, metroId); } } else { businessList.removeFooterView(footerView); } } }); }
使用搜索字段设置自定义工具栏
void showCustomView(String metroTxt, String metroLoc, String metroId) { LayoutInflater mInflater = LayoutInflater.from(this); if (mCustomView == null) mCustomView = mInflater.inflate(R.layout.custom_action_bar, null); mToolbar.removeView(mCustomView); mToolbar.addView(mCustomView); Log.d("I'm inside custom view", "txt" + metroTxt); abKeyword = (CustomAutoCompleteTextView) mCustomView .findViewById(R.id.ab_keyword); abLocation = (CustomAutoCompleteTextView) mCustomView .findViewById(R.id.ab_location); ab_search = (Button) mCustomView .findViewById(R.id.ab_search); abKeyword.append(metroTxt); abLocation.setVisibility(View.GONE); ab_search.setVisibility(View.GONE); abKeyword.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus || !abKeyword.getText().toString().isEmpty() || !abLocation.getText().toString().isEmpty()) { abLocation.setVisibility(View.VISIBLE); ab_search.setVisibility(View.VISIBLE); } else { abLocation.setVisibility(View.GONE); ab_search.setVisibility(View.GONE); } } }); abKeyword.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable editable) { // TODO Auto-generated method stub } public void beforeTextChanged(CharSequence s, int start, int count, int after) { // TODO Auto-generated method stub } public void onTextChanged(CharSequence s, int start, int before, int count) { String newText = s.toString(); BusinessInfoSuggestionTask autocompleteTask = new BusinessInfoSuggestionTask(BusinessResultListActivity.this); String acType = "keyword"; if (s.length() >= 1) { abLocation.setVisibility(View.VISIBLE); ab_search.setVisibility(View.VISIBLE); autocompleteTask.execute(newText, acType, cActivity); } else { abLocation.setVisibility(View.GONE); ab_search.setVisibility(View.GONE); } } }); ab_search.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); String abKey = abKeyword.getText().toString(); String abLoc = abLocation.getText().toString(); String abId = ""; getBusinesses(abKey, abLoc, abId); Log.d("I'm clicked", "button on toolbar clicked"); } }); }
从服务器获取数据的方法
/* Get Businesses data from server */ private void getBusinesses(String metroTxt, String metroLoc, String metroId) { // TODO Auto-generated method stub String first = "first"; BusinessListApiTask spTask = new BusinessListApiTask( BusinessResultListActivity.this); try { spTask.execute(metroTxt, metroLoc, metroId, first); } catch (Exception e) { spTask.cancel(true); } } /* Fetch more data on scroll */ private void getScrollData(String metroTxt, String metroLoc, String metroId) { // TODO Auto-generated method stub String first = "next"; BusinessListApiTask spTask = new BusinessListApiTask( BusinessResultListActivity.this); try { spTask.execute(metroTxt, metroLoc, metroId, first); //Call AsyncTask to fetch data from server } catch (Exception e) { spTask.cancel(true); } }
I'm using
ListView
which is populated by custom adapter that extendsBaseAdapter
. Data is fetched from external server withAsyncTask
and onPostExecute method ofAsyncTask
calls a method onListActivity
that sets adapter to display data
ListView
also implementsOnScrollListener
to fetch data on scroll and add to bottom.I've an
ActionBar
(Toolbar
) with custom view which containsEditText
fields andButton
on click of which, again, sameAsyncTask
is called to fetch new data with query values passed fromToolbar
.Problem is, when button on toolbar is clicked I want the
ListView
to be populated with entirely new data replacing the old values but instead new data is appended at the bottom of list ( as ifOnClickListener
is called).I checked Link1, Link2 but none seem to help
And of course main strike would be to use
NotifyDataSetChange
and I'm using that too but not worth it.My method to set adapter
public void setBusinesses(ArrayList<BusinessListData> businesses) { imgFetcher = new BusinessListIconTask(this); layoutInflator = LayoutInflater.from(this); if (this.businesses == null || adapter == null) { this.businesses = new ArrayList<>(); adapter = new BusinessListDataAdapter(this, imgFetcher, layoutInflator, this.businesses); businessList.setAdapter(adapter); } this.businesses.addAll(businesses); adapter.notifyDataSetChanged(); /* Activates when scrolling to bottom of list */ businessList.setOnScrollListener(new OnScrollListener() { public int currentScrollState; public int currentFirstVisibleItem; public int currentVisibleItemCount; public int totalItemCount; public int lastItem; boolean isLoading = false; public void onScrollStateChanged(AbsListView view, int scrollState) { this.currentScrollState = scrollState; this.isScrollCompleted(); } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { this.currentFirstVisibleItem = firstVisibleItem; this.currentVisibleItemCount = visibleItemCount; this.totalItemCount = totalItemCount; this.lastItem = firstVisibleItem + visibleItemCount; } private void isScrollCompleted() { if (this.lastItem == this.totalItemCount) { /*** In this way I detect if there's been a scroll which has completed ***/ if (!isLoading) { isLoading = true; getScrollData(metroTxt, metroLoc, metroId); } } else { businessList.removeFooterView(footerView); } } }); }
setting custom toolbar with search fields
void showCustomView(String metroTxt, String metroLoc, String metroId) { LayoutInflater mInflater = LayoutInflater.from(this); if (mCustomView == null) mCustomView = mInflater.inflate(R.layout.custom_action_bar, null); mToolbar.removeView(mCustomView); mToolbar.addView(mCustomView); Log.d("I'm inside custom view", "txt" + metroTxt); abKeyword = (CustomAutoCompleteTextView) mCustomView .findViewById(R.id.ab_keyword); abLocation = (CustomAutoCompleteTextView) mCustomView .findViewById(R.id.ab_location); ab_search = (Button) mCustomView .findViewById(R.id.ab_search); abKeyword.append(metroTxt); abLocation.setVisibility(View.GONE); ab_search.setVisibility(View.GONE); abKeyword.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus || !abKeyword.getText().toString().isEmpty() || !abLocation.getText().toString().isEmpty()) { abLocation.setVisibility(View.VISIBLE); ab_search.setVisibility(View.VISIBLE); } else { abLocation.setVisibility(View.GONE); ab_search.setVisibility(View.GONE); } } }); abKeyword.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable editable) { // TODO Auto-generated method stub } public void beforeTextChanged(CharSequence s, int start, int count, int after) { // TODO Auto-generated method stub } public void onTextChanged(CharSequence s, int start, int before, int count) { String newText = s.toString(); BusinessInfoSuggestionTask autocompleteTask = new BusinessInfoSuggestionTask(BusinessResultListActivity.this); String acType = "keyword"; if (s.length() >= 1) { abLocation.setVisibility(View.VISIBLE); ab_search.setVisibility(View.VISIBLE); autocompleteTask.execute(newText, acType, cActivity); } else { abLocation.setVisibility(View.GONE); ab_search.setVisibility(View.GONE); } } }); ab_search.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); String abKey = abKeyword.getText().toString(); String abLoc = abLocation.getText().toString(); String abId = ""; getBusinesses(abKey, abLoc, abId); Log.d("I'm clicked", "button on toolbar clicked"); } }); }
Methods to fetch data from server
/* Get Businesses data from server */ private void getBusinesses(String metroTxt, String metroLoc, String metroId) { // TODO Auto-generated method stub String first = "first"; BusinessListApiTask spTask = new BusinessListApiTask( BusinessResultListActivity.this); try { spTask.execute(metroTxt, metroLoc, metroId, first); } catch (Exception e) { spTask.cancel(true); } } /* Fetch more data on scroll */ private void getScrollData(String metroTxt, String metroLoc, String metroId) { // TODO Auto-generated method stub String first = "next"; BusinessListApiTask spTask = new BusinessListApiTask( BusinessResultListActivity.this); try { spTask.execute(metroTxt, metroLoc, metroId, first); //Call AsyncTask to fetch data from server } catch (Exception e) { spTask.cancel(true); } }
原文:https://stackoverflow.com/questions/28715238
最满意答案
将数据作为对象发送:
$.ajax({ url : ROOT_PATH + "/requirements/" + req_id + "/edit", type : "get", data : {req_info : req_info, someVar : variable} success : function(data) { .... } });
Send the data along as an object:
$.ajax({ url : ROOT_PATH + "/requirements/" + req_id + "/edit", type : "get", data : {req_info : req_info, someVar : variable} success : function(data) { .... } });
相关问答
更多-
通过本地客户端程序获取服务器mysql数据库信息[2023-04-27]
ajax -
从JavaScript中的ajax调用将数组作为参数传递给控制器(Pass an array as parameter to a controller from an ajax call in JavaScript)[2022-01-04]
如果你正在从$.ajax正确地传递一个整型数组(即你的docsArray应该像[15,18,25,30,42,49]那样的值),那么你应该尝试: [Authorize] public ActionResult DeleteDocuments(int[] docsArray) { //int id; //string[] arrayDocs = JsonConvert.DeserializeObject(docsToDelete); try { foreach ... -
如何从ajax调用传递的php访问数组中的所有元素?(How to access all elements in an array from php that is passed by an ajax call?)[2023-01-30]
您需要做的是将JavaScript数组转换为JSON,然后通过该JSON发送。 在PHP方面,您应该将JSON解码回数组。 最后,您应该在将数组重新编码为JSON之后再将其重新编码。 在您的客户端更改一行: data: {testData : JSON.stringify(data)}, 在您的服务器端执行: $myArray = json_decode($_POST["testData"]); header('Content-Type: application/json'); echo json_enc ... -
将数据作为对象发送: $.ajax({ url : ROOT_PATH + "/requirements/" + req_id + "/edit", type : "get", data : {req_info : req_info, someVar : variable} success : function(data) { .... } }); Send the data along as an object: $.ajax({ url ...
-
您不需要对数据对象进行字符串化,默认的Model Binder将处理JSON对象绑定而无需进行字符串化。 submit: function () { var data = { "ReqDepartment": (viewModel.reqDepartment === null) ? null : viewModel.reqDepartment, "EquipmentGroup": (viewModel.equipmentGroup === null) ? null : ...
-
Ajax调用,make数组对象(Ajax call, make array object)[2023-10-24]
您需要在traitementCarte()函数之外声明数组变量,否则每次调用它时都会创建一个新数组。 var test = []; function traitementCarte(xml) { console.log(xml) let lat = [], lng = []; var lastElementLat, lastElementLng; $(xml).find('trkpt').each(function(i, el) { lat[i] = par ... -
nnnnnn是的,你必须使用Deferreds / promises来确保在将route_data发送到控制台之前填充它。 如何做到这一点并不是很明显,尤其是$.when()接受一系列离散参数而不是数组这一事实。 另一个问题是任何个人的ajax失败都不应该破坏整个企业。 如何克服这一点可能不太明显。 我不是百分之百确定,但以下几行应该有效: $.getJSON('http://example-app/api/routes/?callback=?', function(data) { var rout ...
-
你可以这样做 demArray = []; demArray[0] = 'hi'; demArray[1] = 'hello'; $.ajax({ type: "GET", data: {arrayDem:demArray}, url: "someUrl", success: function(response){ } }); serialize()和serializeArray()也可以帮到你。 You can do like this demArray = []; de ...
-
我想我知道你想要什么,但是帖子因json stringify等无关紧要的问题而过于复杂。 这里有一个函数可以在你的代码的几个地方使用,以实现一种类型的AJAX调用或另一种。 然后,您可能会有几个按钮,并为每种类型的按钮调用处理程序中的函数,并更改传递给function的参数 doAjax('someval');/* use in button 1*/ doAjax('someOtherval');/* use in button 2*/ function doAjax(arg) { var ...
-
将ajax数组传递给数据:(pass ajax array into data:)[2022-02-20]
您实际上可以将JS对象传递给ajax调用的data属性: $(".replySubmit").click(function(event){ event.preventDefault();//prevent action from button // Build the data object for ajax request: var replyData = { "reply_txt" : $(".replyText").val(), "replyToPos ...