Question

Ceci est mon premier Android app et avant cela je n'avais aucune connaissance de Java du tout.

J'utilisé le code suivant ( trouvé dans une autre question , par Adam L. ), j'ai 28 timepickers et il a très bien fonctionné après avoir modifié un peu le code.
Mais un avis chose I est que je reçois la force de fermeture (NullPointerException) quand je suis dans un timepickerdialog (ou datepickerdialog lorsque vous utilisez le code tel qu'il apparaît ici) et l'orientation du changement de l'écran.
Je suppose que je dois sauver quelques informations avec OnDestroy et restaurer à nouveau avec onStart mais je ne sais pas comment accomplir cela.
Dans mon code, je l'utilise mais timepickerdialogs Adam L. Code s est plus propre afin de résoudre le problème, il y aurait aussi résoudre mon propre problème.

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;
    }
}
}

Je pense que c'est la partie intéressante du logcat dans 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
Était-ce utile?

La solution

Utilisez ce code dans votre activité:

@Override

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

Utilisez dans votre fichier manifeste:

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

Autres conseils

conseils de Fargath n'a pas été le meilleur que j'ai peur. Votre problème est que activateDate est nulle quand onCreateDialog() est appelée après un changement de configuration. Puisque vous ne définissez une fois dans onClick(). Vous devez le mettre en onStart(). Réglage en onResume() ne fonctionnera pas, mais vous pourriez avoir besoin de le mettre là aussi, voir mon problème cycle de vie Android:. Remplissez les données de l'activité dans onStart () ou onResume ()

Si vous souhaitez mettre à jour les dates au moment précis où la boîte de dialogue est affiché, vous pouvez faire une Calendar.getInstance() directe via updateDate() dans onPrepareDialog().

Le problème avec la solution de Fargath est que vous cachez le clavier virtuel, mais le problème existe toujours sur les appareils avec un clavier matériel tels que le G1. La même chose vaut pour les appels téléphoniques entrants. Je ne sais pas ce que onConfigurationChanged() doit faire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top