[EDIT]代码已更新
我有一个大约有100-200行的listview,我创建了一个AsyncTask类,它使用http请求从服务器端加载数据,因为有很多项目我决定加载10个项目/调用,将它们显示在列表中,让用户与它们进行交互,同时再次调用AsyncTask类来加载更多10个项目....
这是listview(photoshop)的设计
效果很好但是当列表视图 更新时,它没有响应很短的时间滚动,然后它响应良好,然后它再次更新,它没有响应片刻......直到它从服务器端满载。我也试过RUNNABLE线程但行为相同:-(
如何填充listview SMOOTHLY并让用户在填充时与其进行交互。
class DBreadInvItems extends AsyncTask<Void, Void, String> {
Connection dbConnection = null;
Statement statement = null;
ResultSet resultSet = null;
ImageView splash;
CstmrInvoice activity;
JSONObject jObj;
String phpResult;
String db;
ItemsDialog itemsdialog;
Integer ttl_read=0;
//----------------------------------------------------------------------------------------------
protected DBreadInvItems(CstmrInvoice a,ItemsDialog itemsdialog) {
this.activity = a;
this.itemsdialog=itemsdialog;
Intent iin= this.activity.getIntent();
Bundle b = iin.getExtras();
db = b.getString("db");
}
//----------------------------------------------------------------------------------------------
@Override
protected void onPreExecute() {
phpResult="";
AnimateImgLoad();
}
//----------------------------------------------------------------------------------------------
@Override
protected String doInBackground(Void... params) {
fetchitems();
return null;
}
//----------------------------------------------------------------------------------------------
@Override
protected void onPostExecute(String result) {
if(phpResult.equals(""))
{
Toast.makeText(itemsdialog.dialog.getContext(), R.string.msg_nointernet, Toast.LENGTH_LONG).show();
return;
}
else
{
if(ttl_read>=10) {
itemsdialog.adapter_items.notifyDataSetChanged();
itemsdialog.finalData = itemsdialog.list_items;
itemsdialog.setListViewHeightBasedOnChildren((ListView) itemsdialog.dialog.findViewById(R.id.listViewInvPopupItems));
//try reading more...
AnimateImgLoad();
itemsdialog.ReadMoreData();
}
}
AnimateImgLoad();
}
//----------------------------------------------------------------------------------------------
private void fetchitems()
{
try
{
JSONObject json=new JSONObject();
json.put("db",db);
json.put("action","fetchitems");
json.put("seq",itemsdialog.SEQ.toString());
HttpParams httpparams= new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpparams, 10000);
HttpClient client=new DefaultHttpClient(httpparams);
String url="http://roya4u.com:8972/roya/invoices.php";
HttpPost request=new HttpPost(url);
request.setEntity(new ByteArrayEntity(json.toString().getBytes("UTF8")));
request.setHeader("json",json.toString());
HttpResponse response=client.execute(request);
HttpEntity entity=response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
phpResult= RestClient.convertStreamToString(instream);
}
}
catch (Throwable t)
{
}
if(phpResult.equals(""))
{
//Toast.makeText(itemsdialog.dialog.getContext(), R.string.msg_nointernet, Toast.LENGTH_LONG).show();
return;
}
try
{
JSONObject object = new JSONObject(phpResult);
final String islogged = object.getString("success");
if(Boolean.valueOf(islogged))//success=true
{
ttl_read=Integer.parseInt(object.getString("total").toString());
if(ttl_read>0) {
itemsdialog.SEQ = Integer.parseInt(object.getString("seq"));
//Toast.makeText(itemsdialog.dialog.getContext(),itemsdialog.SEQ, Toast.LENGTH_SHORT).show();
for (int i = 0; i < object.getJSONArray("items").length(); i++) {
JSONObject j = object.getJSONArray("items").optJSONObject(i);
itemsdialog.list_items.add(new MyInvoiceItems(Integer.parseInt(j.get("id").toString()), j.get("mkat").toString(), 1, Double.parseDouble(j.get("ccost").toString()), j.get("iname").toString(), 0));
}
}
}
else
{
//Toast.makeText(itemsdialog.dialog.getContext(), R.string.msg_errorlogin, Toast.LENGTH_LONG).show();
}
}
catch (JSONException e)
{
//Toast.makeText(itemsdialog.dialog.getContext(),R.string.msg_nointernet, Toast.LENGTH_LONG).show();
}
}
//----------------------------------------------------------------------------------------------
//------------------------------
private void AnimateImgLoad()
{
RotateAnimation anim;
if(splash==null)
{
anim = new RotateAnimation(0f, 360f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
anim.setInterpolator(new LinearInterpolator());
anim.setRepeatCount(Animation.INFINITE);
anim.setDuration(700);
//Start animating the image
splash = (ImageView) itemsdialog.dialog.findViewById(R.id.imgReload);
splash.startAnimation(anim);
ProgressBar progressbar=(ProgressBar) itemsdialog.dialog.findViewById(R.id.invPopupProgressBar);
progressbar.setVisibility(View.VISIBLE);
}
else
{
splash.setAnimation(null);
splash=null;
ProgressBar progressbar=(ProgressBar) itemsdialog.dialog.findViewById(R.id.invPopupProgressBar);
progressbar.setVisibility(View.GONE);
}
}
}
ADAPTER:
public class SearchableItemsAdapter extends BaseAdapter implements Filterable
{
ArrayList<MyInvoiceItems> filteredData = new ArrayList<MyInvoiceItems>();
private ItemFilter mFilter;
private LayoutInflater mInflater;
//
public SearchableItemsAdapter(Context context, ArrayList<MyInvoiceItems> data) {
filteredData = data;
mInflater = LayoutInflater.from(context);
}
//
public int getCount() {
return filteredData.size();
}
//
public Object getItem(int position) {
return filteredData.get(position);
}
//
public long getItemId(int position) {
return position;
}
//
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolderItems itemsholder;
if(convertView==null)
{
convertView=mInflater.inflate(R.layout.lstcstmrinvoicepopupitems,null);
itemsholder=new ViewHolderItems();
itemsholder.iTaken=(CheckBox) convertView.findViewById(R.id.inv_popupTaken);
itemsholder.iName=(TextView) convertView.findViewById(R.id.inv_popupName);
itemsholder.iQuan=(EditText) convertView.findViewById(R.id.inv_popupQuan);
itemsholder.iPrice=(EditText) convertView.findViewById(R.id.inv_popupPrice);
itemsholder.iTotal=(TextView) convertView.findViewById(R.id.inv_popupTotal);
convertView.setTag(itemsholder);
}
else
{
itemsholder=(ViewHolderItems) convertView.getTag();
}
if(filteredData!=null) {
itemsholder.iTaken.setChecked(false);
if (filteredData.get(position).getTaken() == 1)
itemsholder.iTaken.setChecked(true);
itemsholder.iName.setText(filteredData.get(position).getItem_desc());
itemsholder.iQuan.setText(filteredData.get(position).getItem_num().toString());
itemsholder.iPrice.setText(filteredData.get(position).getItem_cost().toString());
itemsholder.iTotal.setText(filteredData.get(position).getAmountTotal());
}
return convertView;
}
//
public class ViewHolderItems {
CheckBox iTaken;
TextView iName;
EditText iQuan;
EditText iPrice;
TextView iTotal;
}
//
public Filter getFilter() {
if(mFilter==null) mFilter = new ItemFilter();
return mFilter;
}
//
private class ItemFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
//validate
if(filterString.toString().trim().equals(""))
{
results.values = list_items;
results.count = list_items.size();
}
else
{
ArrayList<MyInvoiceItems> tempData =list_items;
finalData = new ArrayList<MyInvoiceItems>();
//mhmd
int count = tempData.size();
String filterableString ;
for (int i = 0; i < count; i++) {
filterableString = tempData.get(i).getItem_desc();
if (filterableString.toLowerCase().contains(filterString)) {
finalData.add(new MyInvoiceItems(tempData.get(i).getItem_key(),tempData.get(i).getItem_mkat(),tempData.get(i).getItem_num(),tempData.get(i).getItem_cost(),tempData.get(i).getItem_desc(),tempData.get(i).getTaken()));
}
}
results.values = finalData;
results.count = finalData.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, Filter.FilterResults results) {
filteredData =(ArrayList<MyInvoiceItems>) results.values;
notifyDataSetChanged();
}
}
}
popup_invitems.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:background="#ffe3e3e3">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="48dp"
android:id="@+id/tbl_mainTitle"
android:background="#ffffffff">
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tbl_searchIcon"
android:layout_alignParentRight="false"
android:layout_marginTop="8dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="8dp">
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imgReload"
android:src="@drawable/ic_reload" />
</TableRow>
</TableLayout>
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="false"
android:id="@+id/tbl_txtName"
android:layout_marginTop="11dp"
android:layout_marginRight="4dp"
android:layout_toLeftOf="@+id/tbl_sort">
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="45dp"
android:layout_height="wrap_content"
android:text="@string/inv_popup_itemname_title"
android:singleLine="true"
android:id="@+id/txtName"
android:textSize="16dp"
android:textColor="#ff3c3c3c" />
</TableRow>
</TableLayout>
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tbl_edtName"
android:layout_toLeftOf="@+id/tbl_txtName"
android:layout_marginTop="6dp"
android:layout_toRightOf="@+id/tbl_searchIcon"
android:layout_marginLeft="10dp"
android:stretchColumns="*">
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/edtName"
android:background="@drawable/edittext" />
</TableRow>
</TableLayout>
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:id="@+id/tbl_sort"
android:layout_marginTop="13dp"
android:layout_marginRight="8dp" >
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imgSort"
android:src="@drawable/ic_sortb"
android:cropToPadding="false" />
</TableRow>
</TableLayout>
<ProgressBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:indeterminateOnly="false"
style="@style/ProgressBar.Horizontal"
android:indeterminate="true"
android:id="@+id/invPopupProgressBar"
android:visibility="gone"
android:layout_below="@+id/tbl_sort"
android:layout_marginTop="2dp"
android:layout_marginBottom="2dp" />
</RelativeLayout>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/scrollView"
android:layout_below="@+id/tbl_mainTitle"
android:layout_above="@+id/Relative_Buttons"
android:layout_marginBottom="2dp"
android:layout_marginTop="5dp">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/listViewInvPopupItems"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:background="#fff4f4f4" />
</RelativeLayout>
</ScrollView>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:id="@+id/Relative_Buttons"
android:layout_marginRight="8dp"
android:layout_marginLeft="8dp">
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tbl_yes"
android:layout_alignParentRight="true">
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="161dp"
android:layout_height="50dp"
android:text="@string/inv_popup_btnOK_title"
android:id="@+id/txtYes"
android:drawableRight="@drawable/ic_ok"
android:drawablePadding="10dp"
android:singleLine="true"
android:textSize="16dp"
android:background="#fff4f4f4"
android:paddingRight="50dp"
android:gravity="center_vertical"
android:textColor="#ff828282" />
</TableRow>
</TableLayout>
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tbl_no"
android:layout_toLeftOf="@+id/tbl_yes"
android:layout_marginRight="2dp">
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:layout_width="161dp"
android:layout_height="50dp"
android:text="@string/inv_popup_btnCancel_title"
android:id="@+id/txtNo"
android:drawableRight="@drawable/ic_delete"
android:drawablePadding="10dp"
android:singleLine="true"
android:textSize="16dp"
android:background="#fff4f4f4"
android:paddingRight="50dp"
android:gravity="center_vertical|right"
android:textColor="#ff828282" />
</TableRow>
</TableLayout>
</RelativeLayout>
</RelativeLayout>
lstcstmrinvoicepopupitems.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:background="#fff4f4f4"
android:paddingBottom="8dp"
android:paddingTop="3dp">
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tbl_check"
android:layout_alignParentRight="true">
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/inv_popupTaken" />
</TableRow>
</TableLayout>
<TableLayout
android:layout_width="285dp"
android:layout_height="wrap_content"
android:id="@+id/tbl_name"
android:layout_toLeftOf="@+id/tbl_check"
android:layout_marginTop="7dp">
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="צבע יסוד טרי מתאים לברזל וגם לעץ מהיר בייבוש"
android:id="@+id/inv_popupName"
android:textSize="15dp"
android:textColor="#ff000000"
android:singleLine="true" />
</TableRow>
</TableLayout>
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tbl_txtQuan"
android:layout_below="@+id/tbl_check"
android:layout_alignParentRight="true"
android:layout_marginRight="7dp"
android:layout_marginTop="3dp">
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="45dp"
android:layout_height="wrap_content"
android:text="@string/inv_quan_title"
android:id="@+id/inv_txtQuan"
android:textSize="15dp"
android:textColor="#ff8c8a8a"
android:singleLine="true" />
</TableRow>
</TableLayout>
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tbl_edtQuan"
android:layout_below="@+id/tbl_check"
android:layout_toLeftOf="@+id/tbl_txtQuan">
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText
android:layout_width="60dp"
android:layout_height="wrap_content"
android:id="@+id/inv_popupQuan"
android:background="@drawable/edittext"
android:text="15400"
android:textColor="#ff8c8a8a"
android:textSize="15dp"
android:singleLine="true" />
</TableRow>
</TableLayout>
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tbl_txtPrice"
android:layout_below="@+id/tbl_check"
android:layout_alignParentRight="false"
android:layout_marginRight="12dp"
android:layout_marginTop="3dp"
android:layout_toLeftOf="@+id/tbl_edtQuan">
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:layout_width="45dp"
android:layout_height="wrap_content"
android:text="@string/inv_price_title"
android:id="@+id/txt_Price"
android:textSize="15dp"
android:textColor="#ff8c8a8a"
android:singleLine="true" />
</TableRow>
</TableLayout>
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tbl_edtPrice"
android:layout_below="@+id/tbl_check"
android:layout_toLeftOf="@+id/tbl_txtPrice" >
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<EditText
android:layout_width="70dp"
android:layout_height="wrap_content"
android:id="@+id/inv_popupPrice"
android:background="@drawable/edittext"
android:text="19540.66"
android:textColor="#ff8c8a8a"
android:textSize="15dp"
android:singleLine="true" />
</TableRow>
</TableLayout>
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tbl_equal"
android:layout_below="@+id/tbl_check"
android:layout_alignParentRight="false"
android:layout_marginRight="2dp"
android:layout_marginTop="3dp"
android:layout_toLeftOf="@+id/tbl_edtPrice" >
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="="
android:id="@+id/txt_equal"
android:textSize="15dp"
android:textColor="#ff8c8a8a"
android:singleLine="true" />
</TableRow>
</TableLayout>
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tbl_total"
android:layout_below="@+id/tbl_check"
android:layout_alignParentRight="false"
android:layout_marginRight="2dp"
android:layout_marginTop="3dp"
android:layout_toLeftOf="@+id/tbl_equal" >
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="128549.87"
android:id="@+id/inv_popupTotal"
android:textSize="15dp"
android:textColor="#ff8c8a8a"
android:singleLine="true" />
</TableRow>
</TableLayout>
</RelativeLayout>
答案 0 :(得分:1)
如果列表视图在更新时没有响应,则表示“更新”正在主线程上进行繁重的工作。你想要做的更顺畅的是将这项工作委托给另一个线程。这包括:
onPostExecute()
方法中进行了一些解析,这个方法是在主线程上执行的。您应该使用doInBackground()
方法执行此操作,并仅使用onPostExecute()
方法更新适配器。为此,您可以从doInBackground方法返回一个MyInvoiceItems列表,该方法将作为onPostExecute()方法的参数传递,然后执行以下操作:
@Override
protected void onPostExecute(List<MyInvoiceItems> result) {
if(result == null)
Toast.makeText(itemsdialog.dialog.getContext(), R.string.msg_nointernet, Toast.LENGTH_LONG).show();
else{
itemsdialog.list_items.add(result);
itemsdialog.adapter_items.notifyDataSetChanged();
}
}
答案 1 :(得分:0)
我认为,你的繁重工作就在这里:setListViewHeightBasedOnChildren
此方法将测量每个子项并获取每个项目的高度,并将listView的总高度相加。 (它有效吗?)。
因为你有很多行,这将成为一项危险的工作。
此方法适用于在垂直滚动视图中显示几行。
以及为什么在更改数据集之前调用notifyDatasetChange?
itemsdialog.adapter_items.notifyDataSetChanged();
itemsdialog.finalData = itemsdialog.list_items;
答案 2 :(得分:-1)
听起来有10个项目甚至可能太多了。尝试一次加载1,看看性能是否有所改善。