2014-01-11 4 views
5

Ich bin sehr neu in der Android-Programmierung und experimentiere mit dem Aufbau einer App. In meiner neuen App habe ich den Benutzer eine Taste drücken, die es ermöglicht, eine App auf ihrem Gerät wie "Galerie" auszuwählen, um ein Bild auszuwählen. Dieses Bild wird dann in einem Bildbetrachtungsfenster auf dem Aktivitätsbildschirm angezeigt. Leider, wenn ich mein Telefon wechsle und die Ausrichtung sich ändert, ist das Bild verloren und sie müssen es erneut auswählen.Wie behält man ein Bild während einer Orientierungsänderung in einer Android-Aktivität?

Wie kann ich das Bitmap-Bild speichern und nach der Änderung der Ausrichtung erneut anzeigen lassen?

Hier ist die Code-Funktion, die ich benutze, damit der Benutzer eine Bild-App auswählen, ein Bild auswählen und das Bild im Bildfenster anzeigen kann.

Button buttonLoadImage = (Button)findViewById(R.id.loadimage); 
textTargetUri = (TextView)findViewById(R.id.targeturi); 
targetImage = (ImageView)findViewById(R.id.targetimage); 

buttonLoadImage.setOnClickListener(new Button.OnClickListener(){ 
@Override 
public void onClick(View arg0) { 
    Intent intent = new Intent(Intent.ACTION_PICK, 
    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 
    startActivityForResult(intent, 0); 
}}); 

Im Grunde brauche ich nur in meinem onCreate diese boolean zu setzen und haben es die setzen:

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 

    if (resultCode == RESULT_OK){ 
     Uri targetUri = data.getData(); 
     textTargetUri.setText(targetUri.toString()); 
     Bitmap bitmap; 
     try { 
      bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(targetUri)); 
      targetImage.setImageBitmap(bitmap); 
     } 
     catch (FileNotFoundException e){ 
      e.printStackTrace(); 
     } 
    } 
} 

Die obige Funktion in meinem onCreate als Antwort auf eine Schaltfläche klicken in diesem Code gezeigt initialisiert Bild zurück im Fenster. Es wird auch Text angezeigt, der anzeigt, wo sich das Bild auf dem Gerät befand, aber das ist für mich nicht so wichtig, da das Bild auf dem Bildschirm bleiben kann.

Aber es scheint, die Daten nach der Änderung der Ausrichtung zu löschen? Ich habe keine Ahnung, wie Sie die Daten speichern und wiederherstellen, damit sie in diesem Boolean verwendet werden können. Ich freue mich über jeden Hinweis, Code oder Links, die Sie zur Verfügung stellen können!


UPDATE:

Danke Vishal Vijay und rajahsekar für Ihre schnellen und hilfreiche Antworten. Ich habe sowohl Ihre empfohlene Kodierung als auch Code, den ich aus früheren Untersuchungen gefunden hatte, in der Lage, eine Lösung zu erstellen. Während es jedoch das erste Problem löste, erzeugte es ein anderes, das ich beschreiben werde, nachdem ich den Code gezeigt habe, mit dem ich das ursprüngliche Problem behoben habe.

Ich fand, dass ich 2 Optionen für den Wiederherstellungsabschnitt zur Verfügung hatte.

Entweder ich könnte dies in der onCreate platzieren:

if (savedInstanceState != null) { 
     //if there is a bundle, use the saved image resource (if one is there) 
     image = savedInstanceState.getParcelable("BitmapImage"); 
     targetImage.setImageBitmap(image); 
     textTargetUri.setText(savedInstanceState.getString("path_to_picture"));R.drawable.camera_button); 
    } 

Die erlaubte mir, sowohl das Bild als auch den Weg, um es auf dem Gerät zu haben, auf meiner Tätigkeit wieder angezeigt werden.

Oder ich könnte dies nach dem onCreate

@Override 
protected void onRestoreInstanceState(Bundle savedInstanceState){  
     image = savedInstanceState.getParcelable("BitmapImage"); 
     targetImage.setImageBitmap(image); 
     textTargetUri.setText(savedInstanceState.getString("path_to_picture")); 
} 

und der Sparfunktion, die ich verwendet wurde

@Override 
public void onSaveInstanceState(Bundle savedInstanceState){ 
    super.onSaveInstanceState(savedInstanceState); 
    savedInstanceState.putParcelable("BitmapImage", bitmap); 
    savedInstanceState.putString("path_to_picture", picture_location); 
} 

Um zu klären, wo picture_location kam, wieder in meinem onActivityResult Funktion ich eine Linie hinzugefügt und änderte einen anderen, um die Pfadzeichenfolge

if (resultCode == RESULT_OK){ 
    Uri targetUri = data.getData(); 
    picture_location = targetUri.toString(); 
    textTargetUri.setText(picture_location); 

wie Variabel zu speichern les initialisiert vor dem onCreate,

Bitmap image; 
Bitmap bitmap; 
String picture_location; 

Nun, ich weiß, das ist ziemlich lang geworden ist, aber ich hoffe, es wird anderen helfen, die ein ähnliches Problem haben. Was das neue Problem anbelangt, das ich bereits erwähnt habe, wenn ich mein Android-Gerät rotiere, speichert es tatsächlich die Daten und zeigt sie erneut an, so wie ich es versucht habe. Wenn ich jedoch den Bildschirm erneut rotiere, tritt das ursprüngliche Problem auf; Die Daten scheinen verloren zu sein und werden nicht auf dem Bildschirm angezeigt.

Ich hoffe, es gibt eine viel einfachere Lösung, so dass die Funktionen zum Speichern und Wiederherstellen funktionieren, egal wie oft sich die Bildschirmausrichtung ändert?

Danke nochmal Jungs!

+0

verwenden Android Query dafür. – Kishan

Antwort

4
Bitmap image; 

public void onCreat(..){ 
    if (savedInstanceState != null) { 
     image = (Bitmap) savedInstanceState.getParcelableExtra("BitmapImage");; 
    } else { 
     image = yourBitmapImage; 
    } 
} 

@Override public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    outState.putExtra("BitmapImage", bitmap); 
} 
+0

Wenn ich mich richtig erinnere, klagte Eclipse, dass putExtra und getParcelableExtra Methoden für den Typ Bundle nicht definiert sind. Möglicherweise habe ich Ihren Code falsch integriert, damit dieser Fehler auftritt. Gibt es einen Grund für das if {} else {} im Gegensatz zu dem if (! =) {}, Das ich benutzt habe? Würde die Verwendung des if sonst mein Problem beheben, das nur für eine Orientierungsänderung funktioniert? – DeadJohnDoe

0

Verwenden onSaveInstanceState Bild speichern

if (savedInstanceState == null) { 
    image = R.drawable.default; 
} else { 
    // if there is a bundle, use the saved image resource (if one is there) 
    image = savedInstanceState.getInt(IMAGE_RESOURCE, R.drawable.default); 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    // Make sure you save the current image resource 
    outState.putInt(IMAGE_RESOURCE, image); 
    super.onSaveInstanceState(outState); 
} 

@Override 
protected void onRestoreInstanceState(Parcelable state) { 
    outState.getInt(IMAGE_RESOURCE,image); 
    super.onRestoreInstanceState(state); 
} 
+0

Gibt es einen Grund für das if {} else {} im Gegensatz zu nur dem if (! =) {}, Das ich verwendet habe? Würde die Verwendung des if sonst mein Problem beheben, das nur für eine Orientierungsänderung funktioniert? – DeadJohnDoe

-1

hinzufügen android:configChanges="keyboardHidden|orientation" für Ihre Aktivität in der Manifest-Datei.

+0

Schlechter Ansatz. Sie sollten die Orientierungsänderung manuell vornehmen. –

+0

Ich hatte deine Antwort zuvor als "Lösung" gefunden, es funktioniert leider nicht. Zumindest nicht mit meinem Programm. – DeadJohnDoe

2

Ich denke, es kostet zu viel, wenn Sie ein Bitmap in onSaveInstanceState sparen, da onSaveInstanceState wird vor onStop jedes Mal aufgerufen werden, und Bitmap ist eine große Sache.

Ich denke, ist besser, ein URI in onSaveInstanceState zu speichern.

Uri mUri; 
ImageView mImageView; 

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    ... 
    if (savedInstanceState != null){ 
    mUri = savedInstanceState.getParcelable("uri"); 
    mImageView.setImageURI(mUri); 
    } 
} 


protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    if (resultCode == RESULT_OK){ 
     Uri targetUri = data.getData(); 
     ... 
     mUri = targetUri; 
    } 
} 
public void onSaveInstanceState(Bundle outState) { 
     if (mURI !=null) { 
      outState.putParcelable("uri", mUri); 
     } 
    } 
1

gemäß dem Entwicklerhandbuch https://developer.android.com/topic/performance/graphics/cache-bitmap.html behalten.

Der empfohlene Weg ist die Verwendung von setRetainInstance (true) im Fragment, um Bilder zu behalten.

siehe Abschnitt auf „Handle Configuration Changes“

Runtime Konfigurationsänderungen, wie beispielsweise eine Änderung der Bildschirmausrichtung, Android bewirken, dass die Laufaktivität mit der neuen Konfiguration (Weitere Informationen zu diesem Verhalten zerstören und neu starten , siehe Handhabung von Laufzeitänderungen). Sie möchten vermeiden, dass Sie alle Ihre Bilder erneut verarbeiten müssen, damit der Benutzer bei Konfigurationsänderungen reibungslos und schnell arbeitet.

Zum Glück haben Sie einen schönen Speicher-Cache von Bitmaps, die Sie im Abschnitt Verwenden eines Speicher-Cache erstellt haben.Dieser Cache kann mit einem Fragment, das durch den Aufruf von setRetainInstance (true)) erhalten wird, an die neue Aktivitätsinstanz übergeben werden. Nachdem die Aktivität wiederhergestellt wurde, wird dieses beibehaltene Fragment erneut angefügt, und Sie erhalten Zugriff auf das vorhandene Cache-Objekt, sodass Bilder schnell abgerufen und erneut in die ImageView-Objekte eingefügt werden können.

private LruCache<String, Bitmap> mMemoryCache; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    ... 
    RetainFragment retainFragment = 
      RetainFragment.findOrCreateRetainFragment(getFragmentManager()); 
    mMemoryCache = retainFragment.mRetainedCache; 
    if (mMemoryCache == null) { 
     mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { 
      ... // Initialize cache here as usual 
     } 
     retainFragment.mRetainedCache = mMemoryCache; 
    } 
    ... 
} 

class RetainFragment extends Fragment { 
    private static final String TAG = "RetainFragment"; 
    public LruCache<String, Bitmap> mRetainedCache; 

    public RetainFragment() {} 

    public static RetainFragment findOrCreateRetainFragment(FragmentManager fm) { 
     RetainFragment fragment = (RetainFragment) fm.findFragmentByTag(TAG); 
     if (fragment == null) { 
      fragment = new RetainFragment(); 
      fm.beginTransaction().add(fragment, TAG).commit(); 
     } 
     return fragment; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setRetainInstance(true); 
    } 
} 
Verwandte Themen