我有一个活动(ChoozQr2),它在一个单独的类(ChoozQr2Adapter)中显示带有自定义适配器的列表视图。在那个自定义适配器中,我有2个时间戳和一些描述这两个时间选择器之间行为的代码。问题是:此行为仅适用于listview中的最后一项。 我已阅读了几篇文章并尝试最近添加一个视图,但现在它在自定义适配器活动结束时在私有静态类ViewHolder上抛出了一个java.lang.Nullpointerexception(参见2)。
非常感谢您的帮助!
这是我的最后一段代码 1.使用listview调用适配器的活动代码:
public class ChoozQr2 extends Activity implements OnClickListener{
Button fini;
ListView lv;
Context context;
ChoozQr2Adapter adapter;
ArrayList<String> resultArr;
TextView tvNomDuQr;
NumberPicker npNbJours,OccAlarme;
DatePicker dateFirstOcc;
TimePicker StartTime, StopTime;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.choozqr_step2);
//declarations
fini = (Button) findViewById(R.id.fini);
lv = (ListView) findViewById(R.id.listView1);
fini.setOnClickListener(this);
//retrieve data from choozqr
Bundle b = getIntent().getExtras();
String[] sTemp = b.getStringArray("selectedItems");
resultArr = new ArrayList<String>(Arrays.asList(sTemp));
//set up adapter
adapter = new ChoozQr2Adapter(this, R.layout.choozqr_step2_textview, resultArr,new BtnClickListener() {
@Override
public void onBtnClick(int position) {
resultArr.add(resultArr.get(position));
lv.setAdapter(adapter);
}
});
lv.setAdapter(adapter);
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
(...)
自定义适配器代码:
public class ChoozQr2Adapter extends ArrayAdapter<String> {
private final List<String> list;
BtnClickListener mClickListener = null;
TimePicker StartTime,StopTime;
DatePicker dateFirstOcc;
NumberPicker npNbJours, OccAlarme;
TextView tvNomDuQr;
Button Btn1,Btn2;
boolean OccAlarmeNotChanged = true;
ViewHolder holder;
public ChoozQr2Adapter(Context context, int resource, List<String> items,BtnClickListener listener) {
super(context, resource, items);
list = items;
mClickListener = listener;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.choozqr_step2_textview, parent, false);
ViewHolder holder = new ViewHolder();
holder.tvNomDuQr=(TextView)v.findViewById(R.id.NomQr);
holder.npNbJours=(NumberPicker)v.findViewById(R.id.numberPickerOccurence);
holder.OccAlarme=(NumberPicker)v.findViewById(R.id.OccAlarme);
holder.dateFirstOcc=(DatePicker)v.findViewById(R.id.datePicker1erJour);
holder.StartTime=(TimePicker)v.findViewById(R.id.timePickerHeureDebut);
holder.StopTime=(TimePicker)v.findViewById(R.id.timePickerHeureFin);
holder.Btn1=(Button)v.findViewById(R.id.Btn1);
//Btn1
holder.Btn1.setTag(position);
holder.Btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mClickListener != null)
mClickListener.onBtnClick((Integer) v.getTag());
}
});
//initialisations time&date picker
Calendar now = Calendar.getInstance();
now.add(Calendar.DAY_OF_MONTH, 1);
holder.StartTime.setIs24HourView(true);
holder.StopTime.setIs24HourView(true);
//When StartTime is changed and is equal to stopTime, put the StopTime one hour later
holder.StartTime.setOnTimeChangedListener(new OnTimeChangedListener(){
public void onTimeChanged(TimePicker v, int hourOfDay, int minute) {
ViewHolder holder = (ViewHolder) v.getTag();
holder.StopTime.setCurrentHour(holder.StartTime.getCurrentHour()+1);
holder.StopTime.setCurrentMinute(holder.StartTime.getCurrentMinute());
}});
holder.OccAlarme.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker arg0, int arg1, int arg2) {
OccAlarmeNotChanged=false;
}
});
//When StopTime changes...
holder.StopTime.setOnTimeChangedListener(new OnTimeChangedListener(){
public void onTimeChanged(TimePicker v, int hourOfDay, int minute) {
ViewHolder holder = (ViewHolder) v.getTag();
//...and is equal to startTime, put the StartTime one hour earlier
if(holder.StartTime.getCurrentHour().equals(holder.StopTime.getCurrentHour())){
holder.StartTime.setCurrentHour(holder.StartTime.getCurrentHour()+1);
}
//...and OccAlarme has not been set by user already
if(OccAlarmeNotChanged){
//Then OccAlarme is updated to half time between start and end time
int i = (Math.abs((holder.StartTime.getCurrentHour() - holder.StopTime.getCurrentHour())))*30;
holder.OccAlarme.setValue(i);
holder.OccAlarme.setMaxValue(2*i);
}
}});
v.setTag(holder); // set tag on view
} else {
holder = (ViewHolder) v.getTag();
}
return v;
}
private static class ViewHolder {
private TextView tvNomDuQr;
private NumberPicker npNbJours;
private NumberPicker OccAlarme;
private TimePicker StartTime;
private TimePicker StopTime;
private DatePicker dateFirstOcc;
private Button Btn1;
//private Button Btn2;
}
}
这是logcat:
07-02 09:38:22.743: E/AndroidRuntime(20161): FATAL EXCEPTION: main
07-02 09:38:22.743: E/AndroidRuntime(20161): Process: fr.XXX.XXX, PID: 20161
07-02 09:38:22.743: E/AndroidRuntime(20161): java.lang.NullPointerException
07-02 09:38:22.743: E/AndroidRuntime(20161): at fr.XXX.XXX.ChoozQr2Adapter$ViewHolder.access$12(ChoozQr2Adapter.java:193)
07-02 09:38:22.743: E/AndroidRuntime(20161): at fr.XXX.XXX.ChoozQr2Adapter$4.onTimeChanged(ChoozQr2Adapter.java:132)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.widget.TimePicker.onTimeChanged(TimePicker.java:656)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.widget.TimePicker.access$300(TimePicker.java:62)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.widget.TimePicker$2.onValueChange(TimePicker.java:167)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.widget.NumberPicker.notifyChange(NumberPicker.java:1835)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.widget.NumberPicker.setValueInternal(NumberPicker.java:1621)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.widget.NumberPicker.scrollBy(NumberPicker.java:1107)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.widget.NumberPicker.onTouchEvent(NumberPicker.java:889)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.View.dispatchTouchEvent(View.java:7837)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2210)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1945)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.widget.NumberPicker.dispatchTouchEvent(NumberPicker.java:946)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-02 09:38:22.743: E/AndroidRuntime(20161): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2075)
07-02 09:38:22.743: E/AndroidRuntime(20161): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1522)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.app.Activity.dispatchTouchEvent(Activity.java:2458)
07-02 09:38:22.743: E/AndroidRuntime(20161): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2023)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.View.dispatchPointerEvent(View.java:8017)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3966)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3845)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3405)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3455)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3424)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3531)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3432)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3588)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3405)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3455)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3424)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3432)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3405)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5554)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5534)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5505)
07-02 09:38:22.743: E/AndroidRuntime(20161): at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5634)
答案 0 :(得分:0)
问题是视图持有者,因为您多次使用相同的名称,因此只需通过以下代码更改您的适配器,
public class ChoozQr2Adapter extends ArrayAdapter<String>
{
private final List<String> list;
BtnClickListener mClickListener = null;
boolean OccAlarmeNotChanged = true;
public ChoozQr2Adapter(Context context, int resource, List<String> items,BtnClickListener listener) {
super(context, resource, items);
list = items;
mClickListener = listener;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
View v = convertView;
if (v == null) {
LayoutInflater vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.choozqr_step2_textview, parent, false);
holder = new ViewHolder();
holder.tvNomDuQr=(TextView)v.findViewById(R.id.NomQr);
holder.npNbJours=(NumberPicker)v.findViewById(R.id.numberPickerOccurence);
holder.OccAlarme=(NumberPicker)v.findViewById(R.id.OccAlarme);
holder.dateFirstOcc=(DatePicker)v.findViewById(R.id.datePicker1erJour);
holder.StartTime=(TimePicker)v.findViewById(R.id.timePickerHeureDebut);
holder.StopTime=(TimePicker)v.findViewById(R.id.timePickerHeureFin);
holder.Btn1=(Button)v.findViewById(R.id.Btn1);
v.setTag(holder); // set tag on view
}
else {
holder = (ViewHolder) v.getTag();
}
//Btn1
holder.Btn1.setTag(position);
holder.Btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mClickListener != null)
mClickListener.onBtnClick((Integer) v.getTag());
}
});
//initialisations time&date picker
Calendar now = Calendar.getInstance();
now.add(Calendar.DAY_OF_MONTH, 1);
holder.StartTime.setIs24HourView(true);
holder.StopTime.setIs24HourView(true);
//When StartTime is changed and is equal to stopTime, put the StopTime one hour later
holder.StartTime.setOnTimeChangedListener(new OnTimeChangedListener(){
public void onTimeChanged(TimePicker v, int hourOfDay, int minute) {
ViewHolder selectedHolder = (ViewHolder) v.getTag();
selectedHolder.StopTime.setCurrentHour(selectedHolder.StartTime.getCurrentHour()+1);
selectedHolder.StopTime.setCurrentMinute(selectedHolder.StartTime.getCurrentMinute());
}});
holder.OccAlarme.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker arg0, int arg1, int arg2) {
OccAlarmeNotChanged=false;
}
});
//When StopTime changes...
holder.StopTime.setOnTimeChangedListener(new OnTimeChangedListener(){
public void onTimeChanged(TimePicker v, int hourOfDay, int minute) {
ViewHolder selectedHolder = (ViewHolder) v.getTag();
//...and is equal to startTime, put the StartTime one hour earlier
if(selectedHolder.StartTime.getCurrentHour().equals(selectedHolder.StopTime.getCurrentHour())){
selectedHolder.StartTime.setCurrentHour(selectedHolder.StartTime.getCurrentHour()+1);
}
//...and OccAlarme has not been set by user already
if(OccAlarmeNotChanged){
//Then OccAlarme is updated to half time between start and end time
int i = (Math.abs((selectedHolder.StartTime.getCurrentHour() - selectedHolder.StopTime.getCurrentHour())))*30;
selectedHolder.OccAlarme.setValue(i);
selectedHolder.OccAlarme.setMaxValue(2*i);
}
}});
return v;
}
private static class ViewHolder
{
private TextView tvNomDuQr;
private NumberPicker npNbJours;
private NumberPicker OccAlarme;
private TimePicker StartTime;
private TimePicker StopTime;
private DatePicker dateFirstOcc;
private Button Btn1;
//private Button Btn2;
}
}