[OFFEN] SharedPreferences und ViewPager, unique key

H

hackbu

Neues Mitglied
0
Hallo zusammen! :smile:

Wir müssen in der Schule gerade unsere erste App entwickeln. Ich habe jetzt mit SharedPreferences gearbeitet um abzuspeichern, ob etwas als Favorit markiert ist oder nicht. Das Layout ist allerdings mit einem ViewPager aufgebaut. Es gibt insgesamt 10 Items zwischen denen der User hin und her wischen kann. Der ViewPager besteht aus einem TextView welcher die Items hochzählt. Beim ersten Item steht [1/10] und beim letzten dementsprechend [10/10]. Der TextView ist gefolgt von einem Image. Die zwei Fragmente funktionieren ohne Probleme. Der ImageButton unter dem Bild ist dafür da, um ein Item als Favorit zu markieren.

Favorit = rotes Herz
kein Favorit = graues Herz

Das ist der ViewPager aus dem Main Layout:

Code:
<android.support.v4.view.ViewPager
    android:id="@+id/image_swipe"
    android:layout_width="match_parent"
    android:layout_height="590dp"
    android:layout_marginTop="130dp" />

Und so ist der Pager zusammengesetzt:

Code:
<TextView
    android:id="@+id/image_count"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:text="Here we count..."
    android:textColor="@android:color/black"
    android:textSize="16sp" />

<ImageView
    android:id="@+id/swipe_image"
    android:layout_width="match_parent"
    android:layout_height="365dp"
    android:layout_marginBottom="20dp"
    android:layout_marginLeft="30dp"
    android:layout_marginRight="30dp"
    android:layout_marginTop="30dp"
    android:adjustViewBounds="false"
    android:onClick="onClickImage" />

<ImageButton
    android:id="@+id/favourite_button"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:layout_gravity="center"
    android:background="@android:color/transparent"
    android:scaleType="fitCenter"
    android:src="@drawable/heart"
    android:onClick="onClickFav" />

Bei den Preferences brauch jedes Item seinen unique key. Den setze ich zusammen aus dem String "fav" und count (count kann 1-10 sein und kommt auch schon beim TextView zum Einsatz). Es existieren also insgesamt 10 von diesen keys: fav1 bis fav10. Wenn so ein Item jetzt geladen wird, wird erstmal geprüft ob für den key des Items etwas gespeichert ist und dementsprechend die ImageResource gesetzt. Danach wird mit einem anderen key = "count" abgespeichert, welches Item gerade geladen ist. Dazu der Code aus dem Adapter (Part mit den Prefs in blau):

Code:
/*
    Instantiate an single adapter item
    Set image resources and text about current position
*/
@Override
public Object instantiateItem(ViewGroup container, int position) {
    layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View item_view = layoutInflater.inflate(R.layout.swipe_layout,container,false);
    ImageView imageView = (ImageView) item_view.findViewById(R.id.swipe_image);
    TextView textView = (TextView) item_view.findViewById(R.id.image_count);
    ImageButton imageButton = (ImageButton) item_view.findViewById(R.id.favourite_button);

    imageView.setImageResource(image_resources[position]);
    textView.setText("["+(position+1)+"/10]");

    SharedPreferences prefs = context.getSharedPreferences("favInfo", Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = prefs.edit();

    // get the unique key consisting of fav and the current item position
    String key = "fav" + (position+1);

    String value = prefs.getString(key, "0");

    // check if value of favorite key is 0
    // set image resource dependent on what value is set
    if (value.equals("1")) {
        imageButton.setImageResource(R.drawable.heart_red);
    } else {
        imageButton.setImageResource(R.drawable.heart);
    }

    int p = (position+1);
    String count = Integer.toString(p);

    // store index of current adapter item as shared pref
    editor.putString("count", count);
    editor.commit();

    container.addView(item_view);

    return item_view;
}

Wenn der User jetzt aber auf den ImageButton klickt, ändert sich meist der vom Item davor oder danach. Hier die onClick Methode für den ImageButton:

Code:
/*
    Method for click actions on the favorite button
    @heart grey heart symbolizes no favorite (flag 0)
    @heart_red red heart symbolizes marked as favorite (flag 1)
*/
public void onClickFav(View v) {
    ImageButton favouriteButton = (ImageButton) findViewById(R.id.favourite_button);

    SharedPreferences prefs = getSharedPreferences("favInfo", MODE_PRIVATE);
    SharedPreferences.Editor editor = prefs.edit();

    // get the count value of the item which is loaded at the moment
    String count = prefs.getString("count", "");

    // get the unique key consisting of fav and the count text
    String key = "fav" + count;

    // get value stored with that key, default: if no value exists take 0
    String value = prefs.getString(key, "0");

    // check if value of favorite key is 0,
    // set image resource dependent on what value is stored behind the key
    if (value.equals("0")) {
        favouriteButton.setImageResource(R.drawable.heart_red);
    } else {
        favouriteButton.setImageResource(R.drawable.heart);
    }

     String isFav;

    // switch value to opposite
    if (value.equals("0")) {
        isFav = "1";
    } else {
        isFav = "0";
    }

    // store shared preferences
    editor.putString(key, isFav);
    editor.commit();
}

Irgendwas wird immer abgespeichert. Nur nicht ganz das richtige. Wenn ich beispielsweise beim Item [7/10] auf den ImageButton drücke, verändert sich der von 6 oder 8. Manchmal aber auch der von 7 wie er es soll... Ich bin ratlos und versteh nicht so ganz an was das liegt.

Falls sich jemand auskennt, wäre ich wirklich dankbar um jeden Ratschlag! Und verzeiht mir, falls das alles nicht sehr professionell wirkt. Bin noch ganz am Anfang. :rolleyes:

Danke! :thumbup:
 
Zuletzt bearbeitet:
Hallo Hackbu,

ich kann dir jetzt nicht mit dem Code weiterhelfen, aber du könntest Objektorientiert an dieses Problem dran gehen.
Warum machst du nicht ein Objekt, welches auch den Zustand des Favoritenflags speichert?

Code:
public class PageItem {

private int uuid;
private String image;
private Boolean isFavorite;

[.. getter und setter..]

}

Danach könntest du eine Liste mit den Objekten erstellen.
Wenn du dann eine bestimmte Seite anzeigst und die uuid kennst, hast du auch dein "isFavorite" direkt drin. (Du müsstest dass dann natürlich auch persitieren, vielleicht im Setter von isFavorite?
 
@Kardroid Hey Kardroid. Erstmal danke für den Vorschlag. Wie wird das Item dann aber so abgespeichert, dass ich nach einem Neustart der App wieder darauf zugreifen kann? :confused2:
 
Ich habe es mir so vorgestellt, dass du es in dem Getter und Setter von isFavorite machst.
Ist zwar nicht das performanteste und schönste, aber könnte funktionieren.

Code:
public getIsFavorite() {

.. Hier den SharedPreferencesCode für get etc.

}

public setIsFavorite(Boolean value)
{
 .. hier den SharedPreferences Code für Set
}
 
  • Danke
Reaktionen: swa00
Das View wird nicht erzeugt, wenn es angezeigt wird, sondern schon früher. Das braucht man, um den Wechsel zwischen den Views schnell genug zu animieren. Ich habe die Doku gerade nicht im Kopf, aber ich meine, es gibt eine Möglichkeit herauszubekommen, welcher View gerade angezeigt werden. (Bin zu Müde, um die Doku zu durchsuche - 0:20 Uhr).
 

Ähnliche Themen

D
Antworten
9
Aufrufe
1.721
jogimuc
J
H
Antworten
2
Aufrufe
1.263
Hcman
H
M
Antworten
4
Aufrufe
1.129
swa00
swa00
Zurück
Oben Unten