Beiträge von Marco Feltmann

    Jetzt habe ich allerdings das Problem, das ich innerhalb einer Tab (bspw. Tab 3) das Fragment verändere (bspw. TextView ändern) switche ich jetzt zu 2 und wieder zurück ist die testview unverändert. Switche ich zu 1 und dann wieder 3 ist die textview wieder im ursprungszustand... soweit so gut und verstanden.


    Ja. So lange Dein Tab noch im Speicher ist sind alle Änderungen drin.
    Sobald es rausfliegt (also nicht mehr direkt neben dem angezeigten Tab liegt) muss es danach neu geladen werden und Deine Änderungen sind weg.


    Aber wenn ich in jedem der 3 Fragmente Änderungen habe und diese bei Tabwechsel verwerfen möchte, frage ich mich gerade ob die navigation tabs überhaupt das richtige widget für diese Aktion sind?


    Klar.
    Dein Fragment hat genau wie Deine Activity einen Lebenszyklus.
    Wenn es den Fokus verliert, wird es pausiert. Also die onPause() Methode wird aufgerufen.
    Dort kannst Du dann alle gemachten Änderungen verwerfen, beispielsweise in dem Du den Textfeldern ein setText(""); sendest.

    Kommt drauf an.
    Wenn Du sowieso erst Android 4+ unterstützen möchtest (davon gehe ich mal im Template aus), kannst Du Dir den Support-Quatsch sparen und einfach eine normale Activity nehmen. So kommst Du dann etwas schneller zu einem Ziel.


    Ansonsten ist das Importieren der appcompat als Library und das Hinzufügen die richtige Vorgehensweise.
    Du musst das AppCompat als 'Library' kennzeichnen und dein Projekt davon abhängig machen. Wie das in Android Studio geht weiß ich gerade nicht.

    Zeile 34 ist actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);


    In dem Fall gibt es nur zwei Möglichkeiten:
    actionBar ist null, weil getActionBar null zurück gibt. Das solltest Du als allererstes überprüfen.
    ActionBar ist null, weil Du auch Version 2.x unterstützt. Da gibt es das gar nicht.


    Ich vermute eine Kombination aus Beidem. Da Du FragmentActivity nutzt, ist davon auszugehen, dass Du die SupportLibrary v4 nutzt und damit auch 2.x unterstützt werden soll.
    FragmentActivity gehört zur SupportLibrary V4, seit API 10 kann die normale Activity das schon.


    Nimm statt der SupportLibrary V4 die V7 und leite von der ActionBarActivity ab. (Die ist von der FragmentActivity abgeleitet.)
    Dort nutzt Du dann statt getActionBar() die getSupportActionBar() und alles sollte laufen wie geplant.
    http://developer.android.com/r…pp/ActionBarActivity.html

    1) Damit Du siehst wie es gemacht wird. Der Sinn hinter den Navigation Tabs ist es, dass mit Fragmenten gearbeitet wird. So kannst Du ein und dieselbe Ansicht in unterschiedlichen Programmabschnitten immer und immer wieder verwenden. Bevor es Fragmente gab war das ein unglaublich nerviges Gefrickel.
    Das Ding heißt nur 'Placeholder' und tut nix Sinnvolles, da Android Studio ja nicht wissen kann, was das Fragment jetzt genau tun soll.
    Vermutlich liegt das nur der Übersicht halber im Code der Main Activity. Eigene Fragmente gehören meiner Auffassung nach in eigene Klassen.


    2) Leg Dir um Himmels Willen Fragmente an und nimm so wenig Activities wie möglich (und so viele wie nötig.)
    Zur sauberen Trennung sei gesagt: niemand zwingt Dich, jedes einzelne Fragment als interne Klasse deiner Activity zu nutzen. Das ist sogar ausgesprochen kontraproduktiv.
    Ein Fragment = eine Klasse hat sich bewährt.


    Also: Fragments sind Best Practice, Fragments als eigene Klassen innerhalb der Activity sind Mumpitz.


    3) Kann man so und so sehen. ^^

    Marco ich empfehle dir für deine phones cyanogenmod :P


    Danke für diese Empfehlung.
    Ich verweigere mich diesem Cyanogenmod aus mehreren Gründen.
    1) niemand weiß, was deren selbst gefrickelter Kram so alles kommuniziert und wohin das Ganze geht.
    (Falls jemand das 'OpenSource' Argument hervorkramen möchte: es ist nahezu unmöglich herauszufinden, was das System in welcher Situation wo macht. Dafür ist es viel zu komplex.)
    2) nach meinen Erfahrungen mit selbst gefrickeltem Kram (z.B. Android On Freerunner) habe ich für mich festgestellt, das nichts so gut und zuverlässig läuft wie ein System, in dem Hard- und Softwareentwicklung nahezu parallel stattfindet.
    (Beispielsweise ist das von Samsung zusammengefrickelte Android ebenfalls katastrophal.)
    3) Das sind alles Testgeräte. Die sollen allesamt ihr maximal mögliches Stock Android haben. Apps sollen zuverlässig auf den Vorinstallationen der typischen Smartphonenutzer laufen. (Und die haben erfahrungsgemäß keine Ahnung von Smartphones.)
    Wenn jemand CyanogenMod nutzen möchte und meine Apps laufen damit nicht, dann soll er sich bei CyanogenMod beschweren. Und mutmaßlich ist er auch versiert genug ein Stocksystem zurückzuspielen.

    Du beschreibst Testszenarien. Ich nutze Testszenarien.
    Ich verweigere mich lediglich dem TDD. :P


    Und in Deinem gesamten Post finde ich kein Argument, dass mich zum TDD antreibt.

    nur als Tipp: Man schreibt Test eigentlich bevor man anfängt etwas zu implementieren.


    Ich persönlich fasse das mehr als vernünfteln denn als Tipp auf.
    Im Prinzip bin ich mit dem Test Driven Development vertraut. Und was testet man zunächst bevor man sich überhaupt an so etwas wie das User Interface setzt? Das Modell. Alle Objekte, die irgendwas tun ohne wirklich etwas anzuzeigen. Und das hatte ich zu dem Zeitpunkt einfach noch nicht herausgefunden.


    Davon abgesehen halte ich vom echten TDD nicht allzu viel:
    Kostet viel zu viel Zeit - Statt schon mal zu implementieren definiere ich irgendwelche Methoden-Stubs, schraube meinen Test drum herum, prüfe ob die Tests auch ja greifen und richtig sind (meist hat sich dort schon ein Fehler eingeschlichen, der am Ende noch mal Zeit kostet), implementiere meine Methoden in der Klasse und habe da ungefähr 20% mehr Zeit für etwas investiert, das überhaupt nicht notwendig gewesen wäre.


    Zusätzliche Komplexität - Sind die Klassen nicht so simpel, steigt auch die Komplexität der Testszenarien gewaltig an. Man testet ja nicht nur, was alles geht, man testet auch, was alles nicht gehen soll. Und es kann beispielsweise echt hart werden zu testen, ob und wie gut sich dein Objekt während Multithreading verhält. (z.B. 'Ist mein Singleton auch dann ein Singleton, wenn von mehreren Threads auf das Objekt zugegriffen wird?')


    Auswirkungen auf das Design - Wenn das Design nicht zu Beginn steht oder sich auf täglicher Basis ändert, bist Du permanent dabei Deine Tests umzuschreiben um unnötige nicht benutzte Methoden wieder rauszuschmeißen. Und was war das oberste Gebot bei den Tests? Never touch a passing test.
    Dir stehen also 'Finger weg vom funktionierenden Test' und 'Weg mit nicht benutzten Methoden' gegenüber. Blöde Situation.


    Laufende Optimierungen - Sollte Deine Klasse Optimierungen unterzogen werden, die sich nicht vermeiden lassen (Beispielsweise sich ändernde Algorithmen) musst Du wieder an Deinen Tests herumschrauben.


    Aus diesen Gründen (wir nutzen hier hauptsächlich Scrum und da ändert sich ja per Definition immer alles) bin ich vom richtigen echten TDD weg.

    Moin,


    leider sind Activities weniger wie ViewController in iOS sondern mehr wie Window Controller.
    Das Äquivalent zu ViewControllern wären die genannten Fragmente.


    Da Android es verpasst hat, eine sinnvolle Modellverwaltung a lá CoreData anzubieten, musst Du Dich leider mit ContentProvidern herumschlagen.
    Der einzige Trost: egal ob du das in SQLite oder ein eigenes File speicherst, der Zugriff auf die Schnittstelle ist dann immer gleich.


    Du solltest dein komplettes Wissen über iOS über Board werfen, wenn Du mit Android arbeiten möchtest. Hier funktioniert alles komplett anders.
    Es gibt kaum bis keine Möglichkeit auf andere Instanzen von Objekten zuzugreifen. Also mal eben den ManagedObjectContext mitschleifen oder das anzuzeigende Objekt übergeben ist nicht drin. Fall 1 fällt in dem Fall also flach.
    Statt dessen muss sich jedes Fragment seine Daten selbst besorgen.


    Es sieht eher so aus.
    Fall 1:
    - App wird über Haupt-Icon gestartet und dafür die Haupt-Activity "EmployeeList" gestartet.
    - Für die Anzeige der Abgestellten müssten diese natürlich erst einmal geladen werden -> Laden der Liste aus einer Datenbank
    - Anzeigen der Liste
    - Wechsel zur Payments-Activity. Diese benötigt ebenfalls die Liste der Angestellten und muss sie sich selbst besorgen


    Fall2 :
    - Start der App über ein Zweiticon das direkt die Payments-Activity startet.
    - Die Liste der Angestellten wurde nicht mit übergeben, diese muss also auch hier selber geladen werden.


    Und dieser App-Aufbau macht eigentlich überhaupt keinen Sinn. Ich meine, ich habe eine Liste mit Angestellten, wechsle die Ansicht und bekomme eine Liste mit Angestellten. Wozu habe ich dann die Ansicht gewechselt? Die Liste der Angestellten sollte doch eher Ausgangspunkt für alles Andere sein.
    Angestellten antippen -> Detailseite mit Kontaktdaten und ein Button zum Aufrufen der Payment Informationen. Vielleicht noch ein Settings-Knopf zum Bearbeiten der Kontaktdaten.
    Angestellten lange antippen -> Aufrufen der Payment Informationen


    Fall 1:
    - App wird über Haupt-Icon gestartet und dafür die Haupt-Activity "EmployeeList" gestartet.
    - Für die Anzeige der Abgestellten müssten diese natürlich erst einmal geladen werden -> Laden der Liste aus einer Datenbank
    - Anzeigen der Liste mit Vorname, Nachname und Abteilung des Angestellten
    + Fall 1a:
    +- Tippen auf einen Angestellten wechselt zur Detailansicht. Übergabe der ID des Angestellten an die Activity.
    +- Diese besorgt sich sämtliche Kontaktdaten des Angestellten und stellt sie entsprechend dar.
    +- Tippen auf den 'Payments'-Button wechselt zur Payments-Activity. Übergabe der ID des Angestellten an die Activity.
    + Fall 1b:
    +- Langes Tippen auf einen Angestellten wechselt zur Payments-Activity. Übergabe der ID des Angestellten an die Activity.
    - Die Payments Activity besorgt sich die sämtliche Payment-Informationen zum Angestellten mit dieser id.


    Fall2 :
    - Start der App über ein Zweiticon das direkt die Payments-Activity startet.
    - Eine Angestellten-ID wurde nicht übergeben. Die Activity läd sich sämtliche Payment-Informationen aller Angestellten und gruppiert sie der Übersicht halber nach dem Nach- und Vornamen des Angestellten.

    Nach aktuellem Dashboard ist alles unter 4.0 nur noch 22,6%.
    Ich habe mir irgendwann angewöhnt, auf 20% und weniger zu verzichten.


    Allerdings nutze ich sehr sehr gern das Master-Detail-View und Eclipse behautet Stein und Bein, dass dieses erst ab 3.0 möglich sei.
    Insofern höre ich gern auf die IDE, verzichte dann noch auf die 0,1% mit 3.x und mach alles ab 4.0
    Allerdings habe ich auch fast nur interne Projekte, bei denen das jetzt so sehr wichtig nicht ist.


    (Ich habe total vergessen welche Probleme ich mit den Fragmenten unter API 9 noch hatte. Jedenfalls ließen sich diese auch mit der ApplicationSupportLibrary nicht lösen und ich musste noch etwas Anderes nutzen. ActionBarSherlock vielleicht? Oder was zum Nutzen von Themes? Egal, war mir jedenfalls viel zu viel Aufwand.)


    Man bedenke auch: API Level 9 (2.3.5), aktuell ist API Level 19 (4.4.2)
    Mehr als die Hälfte. Unter iOS hat man höchstens das Problem iOS 7, iOS 6 und iOS5 mit der ungefähren Verteilung 85%/13%/2%. (Und der iOS 5 Kram ist mit Sicherheit jailbroken und damit völlig uninteressant.)


    Klar hat jeder Pech, der sich ein Gerät von Herstellern anlacht, die sich einen Dreck um Updates scheren.
    Doch um Peter Parker zu zitieren: "Mir ist wohl entfallen, dass das mein Problem ist."
    Zumal mittlerweile jedes Aldi-Smartphone mit Android 4.0 ausgeliefert wird.


    Mein Testgerät Samsung Galaxy S2 kommt beispielsweise mit 2.3.5 daher, da ein Update auf die 4er einfach immer fehl schlägt. Da ich es zu Testzwecken mal von 4.0 auf 2.3.5 zurückgespielt habe – mein Problem.


    Das Samsung Galaxy ACE hat mittlerweile fast drei Jahre auf dem Buckel und wir wissen ja, dass normale Firmen nach 18 Monaten jeglichen Support einstellen.
    Und das Huawei Sonic U8650-1 ist ungefähr ein halbes Jahr neuer, also auch mein Problem.


    Bei den letzten beiden Geräten ist die Arbeit mit Fragmenten aus der Support Library so unglaublich langsam, dass es für den Benutzer keine Freude mehr ist.
    (Zugegebenermaßen ist es rasend schnell im Vergleich zu PhoneGap Apps…)


    Ich müsste also zwei Varianten entwickeln, um die unglaublich langsame Hardware zu supporten. Und im Allgemeinen ist mir das den Aufwand nicht wert.
    (Im Speziellen bau ich mir für einige Routinen ein API-6 Gerüst um es auf den unglaublich langsamen alten Geräten testen zu können. Davon fließt aber nichts ins Release.)

    Ja, das geht. Oder auch: nein, das geht nicht. Wie Du magst. Soweit ich weiß wird 'null' nicht gecastet.
    Im Gegensatz zu C/Objective-C werden die Casts in Java ja zur Laufzeit in der RuntimeEnvironment irgendwie umgebogen, was im Problemfall zu ClassCastExceptions führen kann. Da null ja per se nicht von derselben Klasse sein kann, wird auch kein Cast im eigentlichen Sinne durchgeführt. Es wird lediglich als erfolgreich durchgewunken.


    null ist alles und nichts. Du kannst jeder Methode, die einen Parameter vom Typen eines Objektes erwartet, ein null mitgeben.
    Der schluckt das erst mal, da 'null' ja nicht falsch ist.
    Assoziationsketten:
    'Ich will eine Liste. Ich bekomme eine Liste. Fein.'
    'Ich will eine Liste. Ich bekomme nichts. Fein.'
    'Ich will eine Liste. Ich bekomme ein Bild. Spinnste?'


    Du benutzt es ja auch ständig.

    Java
    View temporaryView;
    temporaryView = new View(); // Läuft, ist ja ein View.
    temporaryView = new Button(); // Läuft, auch ein View.
    temporaryView = new ArrayList<Integer>(); // Compilerfehler beim Bauen bzw. ClassCastException zur Laufzeit
    temporaryView = "Hallo Welt!"; // Compilerfehler beim Bauen bzw. ClassCastException zur Laufzeit
    temporaryView = null; // geht, obwohl es ja nicht vom Typ 'View' ist.


    null ist ein Platzhalter für 'nüscht'. Und 'nüscht' ist sehr wichtig. Ohne 'nüscht' würde beispielsweise die Garbage Collection nicht laufen. Diese schmeißt ja alle Objekte weg, welche keine Referenz mehr auf sich haben. Und wie wird man eine Referenz auf ein zuvor erstelltes Objekt wieder los?

    Java
    instanceObject = null;


    Natürlich gibt es da Möglichkeiten.
    Man kann eine Methode meines Wissens so schreiben, dass eine Null-Referenz als Parameter sofort eine InvalidArgumentException zur Compilezeit auslöst.

    wie soll ich dafür sorgen ? :D haha... hab es ja eigentlich so geschrieben das es gar nicht null sein kann. :D


    Du hast geschrieben:

    Java
    ImageButton deleteBtn   = (ImageButton)dialog3.findViewById(R.id.dialog3_imageBtnDelete);


    Da findViewById null zurückliefern kann, stimmt Deine Aussage also gar nicht.


    Java
    ImageButton deleteBtn   = (ImageButton)dialog3.findViewById(R.id.dialog3_imageBtnDelete);
    if(deleteBtn == null) {
      deleteBtn = new ImageButton(this);
      // Configure button
      // Try to put it into your layout
    }


    So sorgst Du dafür, dass es gar nicht null sein kann. ;)

    Ich würde zunächst bei SE direkt nachfragen, da die ja eigentlich dafür sorgen müssen, dass Systemupdates zur Verfügung stehen.
    Mit selbst kompilieren und flashen habe ich eher weniger gute Erfahrungen gemacht, da doch etliche Treiber fehlen.


    Eventuell wäre ein passendes CyanogenMod eine Alternative für Dich.
    Die aktuelle stabile Version für's Xperia Pro Mini wäre die 9.1 und hier erhältlich. Das entspricht immerhin der 4.0.1. Aktueller wird es wohl nicht, weil die Hardware schon gut betagt ist.


    Spinnereien bezüglich 'Garantieanspruch erlischt' spare ich mir mal, da das Gerät doch schon etwas älter ist. ;)

    Ich bin mir nicht sicher, ob nicht je nach Hardware requestSingleUpdate() 'falsche' Werte zurückgeben kann.
    Mir schwebt vor, dass das Problem nach einem kurzen Ruhezustand der App auftritt. Eventuell ist es möglich, dass es in der requestLocationUpdate Queue noch weitere alte LocationUpdates gibt, die nicht abgeholt wurden.
    Auch ist es möglich, dass die LocationUpdates triangulieren und nicht nur den einen nächsten Sendemasten ausgeben, sondern alle in Reichweite befindlichen Sendemasten.


    In dem Fall wäre es schön, wenn die Callback-Methode ein Array aller Locations bekäme. (Macht der Konkurrent so.)
    Dann könnte man an Hand der Entfernungen zu den Masten schauen wo man sich ungefähr befindet.


    ---


    Zu den Kriterien:
    ACCURACY_COARSE = 2
    ACCURACY_MEDIUM = 2
    ACCURACY_FINE = 1
    ACCURACY_LOW = 1
    ACCURACY_HIGH = 3


    Coarse durch Medium ersetzen bringt also nicht allzu viele Änderungen.


    Nehmen wir die Namenskonventionen, dann überschreibt 'setX()' den Wert X.
    Würde er ihn hinzufügen, hieße er 'addX()'.


    Weiterhin geht aus der Dokumentation hervor:

    Zitat

    public void setAccuracy (int accuracy)


    Added in API level 1
    Indicates the desired accuracy for latitude and longitude.
    Accuracy may be ACCURACY_FINE if desired location is fine, else it can be ACCURACY_COARSE.
    More accurate location may consume more power and may take longer.


    Eventuell geht ACCURAY_HIGH nicht, weil es in der Dokumentation nicht als gültiger Parameter auftaucht. Was ich nicht verstehe. Aber das ändert ja nix.

    Wobei 'trim()' meines Wissens nach zwar bei 'Olaf', 'Olaf ', ' Olaf ' und ' Olaf' funktioniert, aber nicht bei 'Hans-Peter' und 'Hans - Peter'. Und schon gar nicht bei 'Hans Peter' und 'Hans-Peter'.


    Es ist in den meisten Fällen eine schlechte Idee, sich auf die korrekte Eingabe von Strings zu verlassen.
    Wenn Du also beispielsweise eine personenbezogene Bestenliste führen möchtest, solltest Du davon absehen, alles in eine Tabelle pappen zu wollen und ein wenig normalisieren.


    Also statt

    C
    id| name  | punkte
    --+-------+-------
    1 | Torben | 123
    2 | Torben | 98
    3 | Jan    | 92
    4 | Torben | 110
    5 | Sven   | 189
    6 | Mike   | 93
    7 | Mike   | 99


    Lieber zwei Tabellen: