skip to Main Content

[EDIT] code updated

I have a listview which going to have about 100-200 rows, I’have created a AsyncTask class which loads the data from server side using http request and because there is many items I decided to load 10 items/call, and display them in the list and let the user to interact with them while I call the AsyncTask class again to load more 10 items….

Here is the design of the listview (photoshop)

enter image description here

It works great BUT when the listview is being updated it’s NOT responding for few moments to scroll, and then it responds good and then it’s being updated again and it’s not responding for few moments…till it fully loaded from server side. I also tried RUNNABLE thread but the same behavior 🙁

How can I populate the listview SMOOTHLY and let the user interact with it while it’s populating.

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>

3

Answers


  1. It sounds like 10 items may even be too many. Try loading 1 at a time and see if performance improves.

    Login or Signup to reply.
  2. If the listview is not responding while being updated it means the “update” is doing heavy work on the main thread. What you want to do to make it smoother is delegate as much of this work to an other thread. This includes :

    • Network operations or any I/O operations
    • reading a database
    • parsing / unserializing JSON, xml, … into objects

    EDIT: As per your edit on the question, I can see you are doing some parsing in your onPostExecute() method of your asynctask which is executed on the main thread. You should do this work in the doInBackground() method and only update the adapter in the onPostExecute() method. In order to do that, you can return a list of MyInvoiceItems from your doInBackground method which will be passed as a parameter on your onPostExecute() method and then do something like this:

     @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();
        }
    }
    
    Login or Signup to reply.
  3. I think, your heavy work is here:setListViewHeightBasedOnChildren

    this method will measure each child and get each item height,and add up to a total height for listView. (does it work so?).

    as you have many rows,it will become a dangerous work.

    this method works well at showing a few rows all in a vertical scrollview.

    and, why you call notifyDatasetChange before dataset Changed?

    itemsdialog.adapter_items.notifyDataSetChanged();
            itemsdialog.finalData = itemsdialog.list_items;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search