Android:如何顺利填充ListView(x项/服务器端调用)并让用户在加载时与它进行交互?

时间:2015-03-04 20:05:36

标签: android multithreading listview

[EDIT]代码已更新

我有一个大约有100-200行的listview,我创建了一个AsyncTask类,它使用http请求从服务器端加载数据,因为有很多项目我决定加载10个项目/调用,将它们显示在列表中,让用户与它们进行交互,同时再次调用AsyncTask类来加载更多10个项目....

这是listview(photoshop)的设计

enter image description here

效果很好但是当列表视图 更新时,它没有响应很短的时间滚动,然后它响应良好,然后它再次更新,它没有响应片刻......直到它从服务器端满载。我也试过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>

3 个答案:

答案 0 :(得分:1)

如果列表视图在更新时没有响应,则表示“更新”正在主线程上进行繁重的工作。你想要做的更顺畅的是将这项工作委托给另一个线程。这包括:

  • 网络操作或任何I / O操作
  • 阅读数据库
  • 解析/反序列化JSON,xml,...到对象
编辑:根据你对这个问题的编辑,我可以看到你在你的asynctask的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,看看性能是否有所改善。