Domanda

Questo è il mio primo Android-app e prima di questo ho avuto alcuna conoscenza di Java a tutti.

ho usato il seguente codice ( trovano in un'altra domanda , da Adam L. ), ho 28 timepickers e ha funzionato grande dopo aver modificato il codice un po '.
Ma una cosa che ho avviso è che ho la forza di chiusura (NullPointerException), quando mi trovo in un timepickerdialog (o datepickerdialog quando si utilizza il codice come viene visualizzato qui) e cambiare l'orientamento dello schermo.
Credo che ho bisogno di salvare alcune informazioni con OnDestroy e il ripristino di nuovo con onStart ma non so come fare questo.
Nel mio codice che utilizzo timepickerdialogs ma codice Adam L. s è più pulita in modo da risolvere il problema ci sarebbe anche risolvere il mio proprio problema.

import java.util.Calendar;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;

public class MultiDatePickerActivity extends Activity {

private TextView startDateDisplay;
private TextView endDateDisplay;
private Button startPickDate;
private Button endPickDate;
private Calendar startDate;
private Calendar endDate;

static final int DATE_DIALOG_ID = 0;

private TextView activeDateDisplay;
private Calendar activeDate;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.multidatepicker);

    /*  capture our View elements for the start date function   */
    startDateDisplay = (TextView) findViewById(R.id.startDateDisplay);
    startPickDate = (Button) findViewById(R.id.startPickDate);

    /* get the current date */
    startDate = Calendar.getInstance();

    /* add a click listener to the button   */
    startPickDate.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            showDateDialog(startDateDisplay, startDate);
        }
    });

    /* capture our View elements for the end date function */
    endDateDisplay = (TextView) findViewById(R.id.endDateDisplay);
    endPickDate = (Button) findViewById(R.id.endPickDate);

    /* get the current date */
    endDate = Calendar.getInstance();

    /* add a click listener to the button   */
    endPickDate.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            showDateDialog(endDateDisplay, endDate);
        }
    });

    /* display the current date (this method is below)  */
    updateDisplay(startDateDisplay, startDate);
    updateDisplay(endDateDisplay, endDate);
}

private void updateDisplay(TextView dateDisplay, Calendar date) {
    dateDisplay.setText(
            new StringBuilder()
                // Month is 0 based so add 1
                .append(date.get(Calendar.MONTH) + 1).append("-")
                .append(date.get(Calendar.DAY_OF_MONTH)).append("-")
                .append(date.get(Calendar.YEAR)).append(" "));

}

public void showDateDialog(TextView dateDisplay, Calendar date) {
    activeDateDisplay = dateDisplay;
    activeDate = date;
    showDialog(DATE_DIALOG_ID);
}

private OnDateSetListener dateSetListener = new OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
        activeDate.set(Calendar.YEAR, year);
        activeDate.set(Calendar.MONTH, monthOfYear);
        activeDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
        updateDisplay(activeDateDisplay, activeDate);
        unregisterDateDisplay();
    }
};

private void unregisterDateDisplay() {
    activeDateDisplay = null;
    activeDate = null;
}

@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
        case DATE_DIALOG_ID:
            return new DatePickerDialog(this, dateSetListener, activeDate.get(Calendar.YEAR), activeDate.get(Calendar.MONTH), activeDate.get(Calendar.DAY_OF_MONTH));
    }
    return null;
}

@Override
protected void onPrepareDialog(int id, Dialog dialog) {
    super.onPrepareDialog(id, dialog);
    switch (id) {
        case DATE_DIALOG_ID:
            ((DatePickerDialog) dialog).updateDate(activeDate.get(Calendar.YEAR), activeDate.get(Calendar.MONTH), activeDate.get(Calendar.DAY_OF_MONTH));
            break;
    }
}
}

Credo che questa è la parte interessante del logcat in Eclipse:

12-18 11:32:52.415: INFO/ActivityManager(577): Displayed activity se.bergsland.manydatepickers/.ManyDatePickers: 993 ms
12-18 11:32:57.625: DEBUG/dalvikvm(1734): GC freed 1950 objects / 104136 bytes in 192ms
12-18 11:33:00.396: INFO/WindowManager(577): Config changed: { scale=1.0 imsi=0/0 locale=en_US touch=3 key=2/1/2 nav=3 orien=2 }
12-18 11:33:00.535: DEBUG/StatusBar(577): updateResources
12-18 11:33:00.595: DEBUG/AndroidRuntime(1763): Shutting down VM
12-18 11:33:00.595: WARN/dalvikvm(1763): threadid=3: thread exiting with uncaught exception (group=0x4000fe70)
12-18 11:33:00.605: ERROR/AndroidRuntime(1763): Uncaught handler: thread main exiting due to uncaught exception
12-18 11:33:00.615: INFO/WindowManager(577): onOrientationChanged, rotation changed to 0
12-18 11:33:00.625: ERROR/AndroidRuntime(1763): java.lang.RuntimeException: Unable to start activity ComponentInfo{se.bergsland.manydatepickers/se.bergsland.manydatepickers.ManyDatePickers}: java.lang.NullPointerException
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2268)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2284)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3278)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at android.app.ActivityThread.access$1900(ActivityThread.java:112)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at android.os.Looper.loop(Looper.java:123)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at android.app.ActivityThread.main(ActivityThread.java:3948)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at java.lang.reflect.Method.invokeNative(Native Method)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at java.lang.reflect.Method.invoke(Method.java:521)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at dalvik.system.NativeStart.main(Native Method)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763): Caused by: java.lang.NullPointerException
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at se.bergsland.manydatepickers.ManyDatePickers.onCreateDialog(ManyDatePickers.java:102)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at android.app.Activity.restoreManagedDialogs(Activity.java:857)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at android.app.Activity.performRestoreInstanceState(Activity.java:801)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1172)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2245)
12-18 11:33:00.625: ERROR/AndroidRuntime(1763):     ... 12 more
È stato utile?

Soluzione

Utilizzare questo codice nel tuo attività:

@Override

public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
}

Utilizzare questo nel file manifest:

<activity android:name="MyActivity" android:label="@string/app_name" 
    android:configChanges="orientation|keyboardHidden"></activity>

Altri suggerimenti

I consigli di Fargath non era dei migliori ho paura. Il tuo problema è che activateDate è nullo quando onCreateDialog() viene chiamato dopo una modifica alla configurazione. Dal momento che si imposta solo una volta in onClick(). È necessario impostare in onStart(). Impostazione in onResume() non funzionerà, ma potrebbe essere necessario impostarlo anche lì, vedere il mio problema ciclo di vita Android:?. Compila i dati in attività nel onStart () o onResume ()

Se si desidera aggiornare le date al momento esatto in cui la finestra di dialogo viene mostrato, allora si può fare un Calendar.getInstance() diretto tramite updateDate() in onPrepareDialog().

Il problema con la soluzione di Fargath è che si nasconde la tastiera virtuale, ma il problema esiste ancora su dispositivi con una tastiera hardware, come il G1. Lo stesso vale per le chiamate in arrivo. Non sono sicuro di quello che onConfigurationChanged() ha a che fare con esso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top