如何构建一个在滚动时加载更多数据的listView

时间:2014-06-03 17:30:43

标签: android listview arraylist

我有一个类WorkOrder的ArrayList。这个ArrayList填充了ListView,但是,当我的SELECT返回一个非常大的结果时,我有填充listView的问题。好奇以某种方式加载信息作为我的需要。在搜索时,我找到了一些使用setOnScrollListener事件的方法,但不清楚信息是如何上传到listView的。 我的怀疑是:

  • 如何加载信息?必须根据需要从服务器请求它们,或者我们填充整个ArrayList并稍后进行控制?

  • 我在哪里可以找到一个简单的教程来满足我的需求?

要填充我的listView,我使用以下代码:

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.pending_wos);
    new LoadPendingWorkOrders().execute();
    }

    private class LoadPendingWorkOrders extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {

        progress = ProgressDialog.show(PendingWorkOrders.this,
                getResources().getString(R.string.Wait), getResources()
                        .getString(R.string.LoadingPendingWOs));
    }

    @Override
    protected Void doInBackground(Void... params) {

        try {

            worker = Application.getInstance().getUser();

            WorkOrderQueries woQ = WorkOrderQueriesFactory
                    .createWorkOrderQueriesFactory();

            pendingWorkOrders = woQ
                    .selectPendingWorkOrders(asset, fromDate, workType,
                            workRequestType, workOrderState);

                for (WorkOrder w : pendingWorkOrders) {
                    if (w.getDataCompare() >= 0) {
                        w.setFlag(getResources().getDrawable(
                                R.drawable.green));
                    } else {
                        w.setFlag(getResources()
                                .getDrawable(R.drawable.red));
                    }
                }

        } catch (QueryException e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        } catch (ParseException e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {

        setListAdapter(new PendingWOArrayAdapter(getApplicationContext(),
                R.layout.pending_wos_list, pendingWorkOrders));

        ListView listView = getListView();
        listView.setTextFilterEnabled(true);

        if (progress != null)
            progress.dismiss();

    }
    }

这是我的适配器类:

public class PendingWOArrayAdapter extends ArrayAdapter<WorkOrder> {

private List<WorkOrder> workOrders = new ArrayList<WorkOrder>();

public PendingWOArrayAdapter(Context context, int textViewResourceId,
        List<WorkOrder> objects) {
    super(context, textViewResourceId, objects);
    this.workOrders = objects;
}

static class ViewHolder {
    protected ImageView flagIcon;
    protected TextView workOrderName;
    protected TextView workOrderState;
    protected TextView priority;
    protected TextView plannedDate;
    protected TextView asset;
    protected CheckBox chkDownloadWorkOrder;
}

public int getCount() {
    return this.workOrders.size();
}

public WorkOrder getItem(int index) {
    return this.workOrders.get(index);
}

public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    WorkOrder pendingWO = getItem(position);

    if (row == null) {
        LayoutInflater inflater = (LayoutInflater) this.getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = inflater.inflate(R.layout.pending_wos_list, parent, false);

        final ViewHolder viewHolder = new ViewHolder();

        viewHolder.flagIcon = (ImageView) row.findViewById(R.id.flagIcon);
        viewHolder.workOrderName = (TextView) row
                .findViewById(R.id.TxtWorkOrder);
        viewHolder.workOrderState = (TextView) row
                .findViewById(R.id.TxtWorkOrderState);
        viewHolder.priority = (TextView) row.findViewById(R.id.TxtPriority);
        viewHolder.plannedDate = (TextView) row
                .findViewById(R.id.TxtPlannedDate);
        viewHolder.asset = (TextView) row.findViewById(R.id.TxtAsset);
        viewHolder.chkDownloadWorkOrder = (CheckBox) row
                .findViewById(R.id.ChkDownloadWorkOrder);

        viewHolder.chkDownloadWorkOrder
                .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

                    @Override
                    public void onCheckedChanged(CompoundButton buttonView,
                            boolean isChecked) {
                        WorkOrder workOrder = (WorkOrder) viewHolder.chkDownloadWorkOrder
                                .getTag();
                        workOrder.setSelected(buttonView.isChecked());

                    }
                });

        row.setTag(viewHolder);
        viewHolder.chkDownloadWorkOrder.setTag(pendingWO);
    } else {
        ((ViewHolder) row.getTag()).chkDownloadWorkOrder.setTag(workOrders
                .get(position));
    }

    ViewHolder holder = (ViewHolder) row.getTag();
    holder.workOrderName.setText(pendingWO.toString());
    holder.workOrderState.setText("Estado OS: " + pendingWO.getWorkOrderState() + " - "
            + pendingWO.getWorkOrderStateName());
    holder.priority.setText("Prioridade: " + pendingWO.getPriority());
    holder.plannedDate.setText("Data Prevista: "
            + pendingWO.getPlannedDate());
    holder.asset.setText("Ativo: " + pendingWO.getAsset() + " - "
            + pendingWO.getAssetName());
    holder.flagIcon.setImageDrawable(pendingWO.getFlag());
    holder.chkDownloadWorkOrder.setChecked(pendingWO.isSelected());

    if (pendingWO.isChkVisible()) {
        holder.chkDownloadWorkOrder.setVisibility(View.VISIBLE);
    } else {
        holder.chkDownloadWorkOrder.setVisibility(View.GONE);
    }

    return row;
}

}

1 个答案:

答案 0 :(得分:0)

似乎这个列表的大小太大而不能在不损失性能的情况下保留在内存中。我会考虑使用CursorAdapter,在我看来,这是一个更好,更清洁的解决方案。

两个很好的教程:

  1. http://developer.xamarin.com/guides/android/user_interface/working_with_listviews_and_adapters/part_4_-_using_cursoradapters/

  2. http://www.gustekdev.com/2013/05/custom-cursoradapter-and-why-not-use.html