AdMob Banner in ListView als Item integrieren Problem

  • Nabend!


    Ich hab vor ein paar Tagen in eine ListView mit einem CustomArrayAdapter AdMob Banner als Items eingefügt. Das Ganze funktionierte alles auch reibungslos. Nach einem kleinem Wasserschaden, kompletten zerlegtem Galaxy Note, ein wenig Alkohol und einer ROM, funktioniert das nun nicht mehr, wobei davon ausgehe, dass es Anfangs nur Glück war, dass es funktioniert hat....




    Bei diesem Code sollte nun an jeder fünften Stelle ein Banner erscheinen, was er auch tut. Aber, ich kann nun nicht mehr Scrollen, da die App mit einer NullPointerException crashed. Erwarte ich 8 ListItems, weil ich dementsprechend ein Array übergebe, so erhalte ich, bei (position % 2) nur noch 4 Items. Ich hatte darauf Anfangs nicht geachtet....


    Wie kann ich denn am besten innerhalb meines ArrayAdapters sagen, dass zb an jeder 10. Stelle ein Banner erscheinen soll, dafür aber kein ListItem einsparen? Daran wird es ja wohl liegen, dass die App beim Scrollen crashed....


    Den Code, um Banner als ListItem zu setzen habe ich von googleadsdeveloper.blogspot.de


    Dort holen die sich aber die View anstelle von normal convertView über


    Java
    getView(position - (int) Math.ceil(position / k) - 1,          convertView, parent);



    was bei mir aber auch eine NullPointerException auswirft...


    Jemand eine Idee? Stehe mal wieder auf dem Schlauch....(Immer bei den scheinbar einfachsten Sachen...)

  • Wenn dir Items fehlen, dann musst du natürlich auch die Anzahl in getCount() entsprechend erhöhen.

    Java
    int count = array.length;
    // Hier nutzen wir die Eigenheit, dass die Division durch einen int einen int zurückliefert.
    int bannerCount = count / 4;
    return count + bannerCount;


    So, nun zu deinen Abstürzen.
    Vermutlich hast du Obiges bereits bedacht, dann ist allerdings dein Code bezüglich der Abfrage der Items falsch.
    Es sollte zumindest eine OutOfBound Exception geschmissen werden. ;)


    Nehmen wir mal Position 19.
    Wir haben an Position 19 deines ListViews bereits 5 Werbebanner, nämlich für die Positionen 0, 4, 8, 12 und 16.
    Deine Position ist also locker um fünf Indices zu weit hinten. Während du sagst array[19] willst du eigentlich array[14]. Du kannst dir die Sache ja mal aufmalen. ;)


    Insofern wirst du die Indizes in Abhängigkeit der aktuellen Position ändern müssen.


    Anbei ein kleines Beispielprojekt, ganz simpel mit 'javac Rechnen.java' compilieren und mit 'java Rechnen' starten.


    Ich denke, ich sollte alle Problemfälle abgefangen haben, die sich bei diesen doch sehr begrenzten Eingabemöglichkeiten bieten. ^^


    (Nein, mir ist keine superdupertolle mathematische Formel eingefallen, mit der man ausrechnen kann, wie viele Elemente angezeigt werden müssen.
    Vielleicht via numberOfRuns+Math.ceil(numberOfRuns/(bannerPosition-1)) oder so. +schulter zuck+)

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Servus,


    ja das ist richtig...ich habe ersteinmal dafür gesorgt, dass meine Klasse von BaseAdapter erbt anstelle von ArrayList<t> damit ich auch auf die getCount() zugreifen kann.


    Das Problem tritt, so wie ich es sehe, immer bei der Abfrage



    auf. Wenn ich die Abfrage if(row == null) entferne, geht es, dann allerdings erzeugt er ja immer die Row neu, anstatt eine fertige schon zu nehmen.


    Die korrekte Anzahl der Items zzgl. der Banner habe ich mit Deiner Hilfe nun umgesetzt. Ich bin mir nicht ganz sicher, aber ich glaube, dass die in dem Bsp. von dem Blog einen extra BaseAdapter für die Anzeigen verwendet haben, die ja mittels


    Java
    return delegate.getView(position - (int) Math.ceil(position / k) - 1,
              convertView, parent);


    sich die nichtBanner holen. Das delegate wird dann wohl deren BaseAdapter sein, wo die die Daten für die normalen Items aufbauen. Ich habe das auch versucht, aber bei mir geht es nicht.


    Habe einen BannerAdapter aufgesetzt, mit dem Code aus dem Bsp. In meiner Activty eine Instanz beider Adapter erzeugt und versucht, die Instanz meines DatenAdapters in den BannerAdapter beim instanziieren zu übergeben, bekomme aber den Fehler, dass das nicht erwartet wird...warum auch immer. Leider findet man da keine kompletten Bsp. Scheinbar ist es zu einfach, als das man es erklären müsste aber ICH hänge da schon wieder...."macht langsam keine Spass mehr :D"

  • Also 'bei mir geht es nicht' ist immer eine unzureichende Beschreibung. ;)


    Deine Worte verwirren mich.
    Du bekommst du eine NullPointerException, wenn explizit der Zweig der If-Abfrage angesprungen wird, in dem 'row' niemals nicht null sein kann?
    Das kann nicht sein. Darf es zumindest nicht. Diese Art des ViewHolderPatterns habe ich schon so unendlich oft erfolgreich benutzt...

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Guten morgen!


    @Lucas de Vil: Sorry, ich hatte das Thema erst einmal zur Seite geschoben und nicht gesehen, dass Du noch etwas geschrieben hast.


    So, nun will ich aber endlich das Problem lösen. Bisher habe ich ja versucht, alles in einem CustomBaseAdapter zu lösen. Das gestaltet sich aber mehr als schwierig, wenn man allein schon bedenkt, wie man später an die richtigen ListItems kommt über onItemClickListener();


    In dem Beispiel aus dem Blogbeitrag übergeben die ja in dem Konstruktor eine BaseAdapter Instanz. Leider ist nirgends wirklich beschrieben,wie genau das geschehen soll. (Oder ich habe einfach Tomaten auf den Augen...)


    Ich habe nun einfach mal ein Testprojekt angelegt. Zwei CustomBaseAdapter. Im ersten Baseadapter (nachfolgend als WeahterAdapter genannt) verarbeite ich die Daten aus einem Array mit meinen normalen Items.


    Diesen WeahterAdapter übergebe ich dann an den AdmobAdapter. In dem AdmobAdapter mache ich alles genau so, wie in dem Bsp.


    Java
    return delegate.getView(position - (int) Math.ceil(position / k) - 1, convertView, parent);



    Wenn ich versuche in dem AdmobAdapter mir eine View aus dem WeatherAdapter zu holen, crashed die app...


    Hier mal ein Logauszug, wobei ich denke, ich mache schon etwas Grundlegendes falsch:




    Laut LogCat gibt er den ersten Banner auch aus bzw. lädt diesen. Nur crashed die App eben wenn ich versuche eine View aus dem anderen BaseAdapter zu bekommen.

  • In Zeile 44 der WeatherAdapter.java (innerhalb der Methode getView(...)) greifst du auf ein Objekt zu, dass nicht initialisiert wurde, also null ist.
    Steht doch da. ;)

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

    Einmal editiert, zuletzt von Lucas de Vil ()

  • Ein Wunder ist geschehen :D


    Mein einziges Problem lag darin, dass ich in dem WeatherAdapter abfrage:


    Code
    if(row == null)



    Wenn das zweite Banner ausgegeben wurde, ist das nachfolgende RowItem aber nicht null, sondern eine Instance einer AdView...


    mit


    Code
    if(row == null || row instaceof AdView)



    Kann ich die Row neu instanziieren und auch auf diese Zugreifen und einen Wert aus meinem Array hinzufügen.


    Dadurch, dass ich zwei Adapter verwende, brauche ich mir keine Gedanken mehr machen beim Abfragen des ListItemIndex in der setOnItemClickListener und es gibt beim scrollen kein Problem...super!


    Nochmal besten Dank an Lucas de Vil, ohne Deine Hilfe hätte ich wohl noch Jahre gebraucht :D


    DANKE!


    Grüße

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!