我对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]
答案 0 :(得分:0)
创建OnClickListener
的单个实例(例如作为内部类)并将此实例分配给每个小部件。如果您需要知道此窗口小部件属于哪一行,则可以在该窗口小部件上调用setTag("pos", position)
。通过这样做,您可以通过在侦听器的view.getTag("pos")
方法中调用onClick(View view)
来获取位置。希望这会有所帮助。