Android, ListView adapter



我对Android编程有一些问题。更具体地说,我有一个ListView,其中每一行都包含五个小部件和每个触发器事件。我已经为getView方法中的每个小部件创建了自定义适配器并定义了事件处理程序。一切都很好,但是由于里面有所有这些事件处理程序,代码看起来很长、不可读、很糟糕。有更好的设计吗?也许是在getView方法或其他方法之外创建事件处理程序?问候

根据建议,我发布了部分源代码。正如您所看到的,我在getView方法之外创建了几个事件处理程序,在里面创建了两个。我真的不知道哪种设计更好。

    public class ListViewAdapter extends ArrayAdapter<HourReport> {
private static Activity context;
private int resourcecId;
private TextView fromTime;
private TextView toTime;
private TextView total;
private HourReport rowModelBean;
private HourReport rowBean;
private CheckBox billable;
private ArrayList<HourReport> list;
private HourReportCatalog catalog;
private Map<Integer, Integer>selectedItems;
private Map<Integer, Integer>selectedRoles;


public ListViewAdapter(Activity context, int resourcecId,
        ArrayList<HourReport> list, HourReportCatalog catalog) {
    super(context, resourcecId, list);
    this.catalog = catalog;
    ListViewAdapter.context = context;
    this.resourcecId = resourcecId;
    this.list = list;
    selectedItems = new HashMap<Integer, Integer>();
    selectedRoles = new HashMap<Integer, Integer>();
}

// event handler for delete button "-"
private OnClickListener delete = new OnClickListener() {
    @Override
    public void onClick(View deletBtnF) {
        int myPosition = (Integer) deletBtnF.getTag();
        HourReport r = list.remove(myPosition);
        selectedItems.put(myPosition, 0);
        selectedRoles.put(myPosition, 0);
        r.setTimeFinished(null);
        r.setTimeStarted(null);
        r.setTaks(null);
        r.setTotal(0.0);
        r.setBillable(false);
        r.setEngagementContractID(0);       
        list.add(myPosition, r);  
        notifyDataSetChanged();
        if (r.getDateCreated() != null) {
            Log.e("Listview adapter", "inside the if statement");
            Long id = r.getHourReportID();
            Log.e("", "date created" + r.getDateCreated());
            catalog.deleteHourReport(r);
            r.setDateCreated(null);
        }
    }
};
// event handler for textView which is responsible for defining dateFrom
Calendar c = Calendar.getInstance();
OnClickListener onClickLisOnDateFrom = new OnClickListener() {
    @Override
    public void onClick(View editField) {
        Integer position1 = (Integer) editField.getTag();
        TableRow parent = (TableRow) editField.getParent();
        fromTime = (TextView) parent.findViewById(R.id.viewTextFrom);
        total = (TextView) parent.findViewById(R.id.textViewShowsTotal);
        rowBean = getModel(position1);
        TimePickerDialog.OnTimeSetListener timeListener1 = new TimePickerDialog.OnTimeSetListener() {
            @Override
            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                c.set(Calendar.HOUR_OF_DAY, hourOfDay);
                c.set(Calendar.MINUTE, minute);
                int hour = c.get(Calendar.HOUR_OF_DAY);
                int minutes = c.get(Calendar.MINUTE);
                String time = hour + ":" + minutes;
                fromTime.setText(time);
                setTimeFieldFrom(time);
                String totalTime = totalHourCalculator();
                total.setText(totalTime);
            }
        };
        new TimePickerDialog(context, timeListener1,
                c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), true)
                .show();
    }
};
// event handler for textView which is responsible for defining dateTo
private OnClickListener onClickLisOnDateTo = new OnClickListener() {
    @Override
    public void onClick(View editField) {
        Integer position1 = (Integer) editField.getTag();
        Log.e("ListView - Timer ", "position: " + position1);
        TableRow parent = (TableRow) editField.getParent();
        toTime = (TextView) parent.findViewById(R.id.viewTextFrom);
        total = (TextView) parent.findViewById(R.id.textViewShowsTotal);
        rowBean = getModel(position1);
        TimePickerDialog.OnTimeSetListener timeListener2 = new TimePickerDialog.OnTimeSetListener() {
            @Override
            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                c.set(Calendar.HOUR_OF_DAY, hourOfDay);
                c.set(Calendar.MINUTE, minute);
                int hour = c.get(Calendar.HOUR_OF_DAY);
                int minutes = c.get(Calendar.MINUTE);
                String time = hour + ":" + minutes;
                toTime.setText(time);
                setTimeFieldTo(time);
                String totalTime = totalHourCalculator();
                total.setText(totalTime);
            }
        };
        new TimePickerDialog(context, timeListener2,
                c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), true)
                .show();
    }
};
        // event handler for check box
private OnClickListener checkBoxListener = new OnClickListener() {
    @Override
    public void onClick(View checkBox) {
        Integer num = (Integer) checkBox.getTag();
        rowBean = getModel(num);
        if (rowBean.isBillable()) {
            rowBean.setBillable(false);
        } else {
            rowBean.setBillable(true);
        }
    }
};
@Override
public View getView( int position, View convertView, ViewGroup parent) {
    getHourReportList();
    TextView deleteBtnV = null;
    View row = convertView;
    Spinner taskSpinner, roleSpinner;
    TextView addReport;
    final ViewHolder viewHolder;
    if (row == null) {
        LayoutInflater layoutInflater = context.getLayoutInflater();
        row = layoutInflater.inflate(resourcecId, parent, false);
        viewHolder = new ViewHolder(row);           
        fromTime = viewHolder.getFromTime();
        deleteBtnV = viewHolder.getDeleteBtnVView();
        deleteBtnV.setOnClickListener(delete);
        billable = viewHolder.getCheckBox();
        addReport = viewHolder.getAddButtonView();
        // event handler for the button "+" which adds extra row
        addReport.setOnClickListener(new OnClickListener() {
            @Override   
            public void onClick(View view) {
                Integer myPosition = (Integer) view.getTag();
                HourReport report = list.get(myPosition);
                HourReport nReport = new HourReport();
                nReport.setClaimDate(report.getClaimDate());
                nReport.setEmployeeID(report.getEmployeeID());
                nReport.setBillable(false);
                nReport.setEngagementContractID(0);
                list.add(myPosition + 1, nReport);
                notifyDataSetChanged();
            }
        });
        viewHolder.adapter = new SpinerAdapter(context);            
        taskSpinner = viewHolder.getSpinnerTask();
        roleSpinner = viewHolder.getSpinnerRole();
        //event handler for the spinner
        taskSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> arg0, View spin,
                    int selected, long arg3) {
                Spinner spinner = (Spinner) spin.getParent();
                Integer myPosition = (Integer) spinner.getTag();                    
                viewHolder.adapter.setSelected(selected);                   
                String task = viewHolder.adapter.getSelectcetdTask();
                long engmId = viewHolder.adapter.getSelectedTaskID();
                rowBean = getModel(myPosition);                   
                rowBean.setTaks(task);   
                rowBean.setEngagementContractID(engmId);
                selectedItems.put(myPosition, selected);                    
            }
            @Override
            public void onNothingSelected(AdapterView<?> arg0) {   
            }
        });
        ////event handler for the spinner
        roleSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> arg0, View spin,
                    int selectedRole, long arg3) {                  
                Spinner spinner = (Spinner) spin.getParent();
                Integer myPosition = (Integer) spinner.getTag();
                selectedRoles.put(myPosition, selectedRole);                
            }   
            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
                // TODO Auto-generated method stub              
            }
        });
        fromTime = viewHolder.getFromTime();
        toTime = viewHolder.getToTime();
        fromTime.setOnClickListener(onClickLisOnDateFrom);
        toTime.setOnClickListener(onClickLisOnDateTo);
        billable.setOnClickListener(checkBoxListener);
        row.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) row.getTag();
        fromTime = viewHolder.getFromTime();
        toTime = viewHolder.getToTime();
        taskSpinner = viewHolder.getSpinnerTask();
        roleSpinner = viewHolder.getSpinnerRole();
        total = viewHolder.getTotal();
        billable = viewHolder.getCheckBox();
        TextView date = viewHolder.getDate();
        deleteBtnV = viewHolder.getDeleteBtnVView();
        addReport = viewHolder.getAddButtonView();
    }
    HourReport model = getModel(position);
    Integer selection = 0;
    if (selectedItems.get(position) != null) {
        selection = selectedItems.get(position);
    }
    int selectionR = 0;
    if (selectedRoles.get(position) != null) {
        selectionR = selectedRoles.get(position);
    }
    viewHolder.getFromTime().setText(
            parseDateToString(model.getTimeStarted()));
    viewHolder.getToTime().setText(
            parseDateToString(model.getTimeFinished()));
    viewHolder.getTotal().setText(
            convertDoubleTotToStringTot(model.getTotal()));
    viewHolder.getDate().setText(
            parseDateToStringDDate(model.getClaimDate()));
    viewHolder.getCheckBox().setChecked(model.isBillable());
    Log.e("", "tag " + selection + " date " + model.getClaimDate());
    viewHolder.taskSpinner.setSelection(selection);
    viewHolder.roleSpinner.setSelection(selectionR);
    fromTime.setTag(Integer.valueOf(position));
    toTime.setTag(Integer.valueOf(position));
    taskSpinner.setTag(Integer.valueOf(position));
    roleSpinner.setTag(Integer.valueOf(position));
    billable.setTag(Integer.valueOf(position));
    deleteBtnV.setTag(Integer.valueOf(position));
    addReport.setTag(Integer.valueOf(position));
    return row;
}![here you have screen shoot of single row][1]

创建OnClickListener的单个实例(例如作为内部类),并将该实例分配给每个小部件。如果您需要知道这个小部件属于哪一行,可以在该小部件上调用setTag("pos", position)。通过这样做,您将能够通过在侦听器的onClick(View view)方法中调用view.getTag("pos")来获得位置。希望这能有所帮助。

最新更新