Grid Lists Image Gallery

darman96

Aktives Mitglied
Hallo ich möchte in meiner App ein Bilder Gallerie einbauen wie die Grid Lists hier in der Android Doc: GridLists
Da ist wohl leider nichts zu erklärt und das Grid View beispiel (ist bei den Grid Lists verlinkt) funktioniert bei mir nicht (heißt es ist einfach nur das leere Fragment zu sehen).

Meine Fragment Klasse für die Menüpunkte im Navigation Drawer:
Java:
public class ImageViewFragment extends Fragment {

	private int orderBy;
    private Vector<Bitmap> thumbs = new Vector<Bitmap>();
	
	// Constructor
	public ImageViewFragment() {
		
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		
		orderBy = (Integer) getArguments().get("wall_order");

		return inflater.inflate(R.layout.image_layout, container, false);
	}
	
	@Override
	public void onViewCreated(View view, Bundle savedInstanceState) {

        GetPreviewTask task = new GetPreviewTask();
        task.execute("http://alpha.wallhaven.cc/latest?page=1");

        GridView gridview = (GridView) getActivity().findViewById(R.id.gridview);
        gridview.setAdapter(new ImageAdapter(getActivity(), thumbs));

		switch (orderBy) {
		case 0:
			view.setBackgroundColor(Color.YELLOW);
			break;
		case 1:
			view.setBackgroundColor(Color.RED);
			break;
		case 2:
			view.setBackgroundColor(Color.GRAY);

		default:
			break;
		}
	}
	
	@Override
	public void onStart() {
		super.onStart();
		


    }
	
	@Override
	public void onResume() {
		super.onResume();
		// Do stuff
	}



    public class GetPreviewTask extends AsyncTask<String, Void, Void> {

        private String sourceCode = "";
        private Vector<String> IDs = new Vector<String>();
        private Vector<Bitmap> thumbNails = new Vector<Bitmap>();

        @Override
        protected Void doInBackground(String... urls) {
            try {
                getSourceCode(urls[0]);
                getIDsFromSource();
                getThumbNails();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return null;
        }

        // Get the source code from Wallhaven
        private void getSourceCode(String url) throws IOException {
            HttpClient client = new DefaultHttpClient();
            HttpGet request = new HttpGet(url);
            HttpResponse response = null;
            try {
                response = client.execute(request);
            } catch (IOException e) {
                e.printStackTrace();
            }
            HttpEntity entity = response.getEntity();
            InputStream in = null;
            try {
                in = entity.getContent();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
            String line = "";
            StringBuilder builder = new StringBuilder();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            while ((line = reader.readLine()) != null ) {
                builder.append(line);
            }

            sourceCode = builder.toString();
        }

        // Get all IDs from the source code
        private void getIDsFromSource() {
            int startIndex = 0;
            // find all wallpaper ID's
            if(sourceCode.indexOf("http://alpha.wallhaven.cc/wallpapers/thumb/small/", startIndex) == -1)
                Log.d("DEBUG", "sourceCode is wrong");
            while(sourceCode.indexOf("http://alpha.wallhaven.cc/wallpapers/thumb/small/", startIndex) != -1) {
                int currentIndex = sourceCode.indexOf("http://alpha.wallhaven.cc/wallpapers/thumb/small/", startIndex);
                int indexID = sourceCode.indexOf("-", currentIndex) + 1;
                int endIndexID = sourceCode.indexOf(".", indexID);
                // Get the ID
                String ID = sourceCode.substring(indexID, endIndexID);
                IDs.add(ID);
                // Display the ID for debugging
                Log.d("ID CHECK", ID);
                // Set new start Index
                startIndex = endIndexID;
            }
        }

        // Download the preview thumb nails from Wallhaven
        private void getThumbNails() {
            for(String ID : IDs) {
                thumbs.add(getImage(ID));
                Log.d("DEBUG", "Thumnail " + ID + " downloaded!");
            }
        }

        private Bitmap getImage(String ID) {

            Bitmap thumb = null;

            InputStream in = null;
            try {
                in = (InputStream) new URL("http://alpha.wallhaven.cc/wallpapers/thumb/small/th-" + ID + ".jpg").getContent();
            } catch (MalformedURLException e) {
                e.printStackTrace();
                Log.e("URL ERROR", e.getMessage());
            } catch (IOException e) {
                e.printStackTrace();
                Log.e("IO ERROR", e.getMessage());
            }
            thumb = BitmapFactory.decodeStream(in);
            try {
                in.close();
            } catch (IOException e) {
                Log.e("IO ERROR", e.getMessage());
                e.printStackTrace();
            }

            return thumb;

        }

    }

}

Und die ImageAdapter Klasse:
Java:
public class ImageAdapter extends BaseAdapter {
    private Context mContext;
    private Vector<Bitmap> thumbs;

    public ImageAdapter(Context c, Vector<Bitmap> thumbs) {
        this.thumbs = thumbs;
        mContext = c;
    }

    @Override
    public int getCount() {
        return thumbs.size();
    }

    @Override
    public Object getItem(int i) {
        return thumbs.get(i);
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ImageView imageView;
        if(view == null) {
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(8, 8, 8, 8);
        } else {
            imageView = (ImageView) view;
        }

        imageView.setImageBitmap(thumbs.get(i));

        return null;
    }
}
 
Zuletzt bearbeitet:

dzim

Top Contributor
Bitte ein paar Sachen beachten: Android-Apps sind keine Java-Konsolen-Anwendung, daher System.out oder .err oder e.printStrackTrace() (was nach System.err schreibt) vermeiden, dafür aber ordentliches Logging verwenden

e.printStackTrace(); --> Log.e(<tag>, <msg>, e);

Was sind die Berechtigungen deiner App? Vielleicht fehlt z.B. die Permission für's Internet (siehe GetPreviewTask)...
Gibt es Fehler auf der LogCat (du catched ja einfach nur und machst den e.printStackTrace()-Call).
Ohne den Code in einem Test-Projekt einzubauen, sehe ich sonst spontan auch kein Problem. Aber da es recht viel Code ist, habe ich auch jetzt auf die schnelle auch nur grob drüber geschaut...
 

darman96

Aktives Mitglied
Also Internet ist nicht das Problem, ich hab die Permission gesetzt und der Lädt die Bilder auch runter.
Nur die die Grid View funktioniert nicht.
 

dzim

Top Contributor
Sorry, aber ohne es nach zu implementieren und ein laufendes Bsp. zu proggn, nein. (Und die Zeit habe ich gerade nicht dazu...)
Vielleicht versuchst du erst mal einen etwas simpleren Ansatz, und lädst ein oder zwei fixe Bilder aus dem Speicher des Telefons - nur um sicherzustellen, dass es wirklich Daten hat, die du anzeigen kannst.
Bemühe vielleicht auch mal den Debugger - idealerweise im Adapter - und schau mal, ob Daten im Vector enthalten sind (warum nutzt du eigentlich einen Vector? Wegen der Zugriffssicherheit durch mehrere Threads? Ich frage, weil Vectoren wohl etwas langsamer sein sollen, als z.B. eine ArrayList...) und wenn der nicht leer ist, was deine #getView-Methode macht... Und überlege mal, ob das ViewHolder-Pattern bei dir Sinn bringen würde.


Android ViewHolder Pattern Example | Java Code Geeks
Making ListView Scrolling Smooth | Android Developers
 

dzim

Top Contributor
Argh! Ich seh gerade deinen Fehler in der #getView Merthode
Java:
    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ImageView imageView;
        if(view == null) {
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(8, 8, 8, 8);
        } else {
            imageView = (ImageView) view;
        }
 
        imageView.setImageBitmap(thumbs.get(i));
 
        return null;
    }

Änder das mal ab, das es z.B. so hier aussieht:
Java:
    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {

        ImageView imageView = null;

        if (view == null) {
            // verwende hie vielleicht eher einen View aus einer XML den du inflatest...
            ImageView imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(8, 8, 8, 8);
            vh.imageView = imageView;
            imageView.setTag(vh);
        } else {
            imageView = (ImageView) view;
        }

        Bitmap bm = thumbs.get(i);
        if (bm != null) {
            imageView.setImageBitmap(bm);
        }

        return imageView;
    }

#getView sollte am Ende auch einen View zurückgeben.... Das ist mir erst eben gerade aufgefallen und erklärt eigentlich alles.
 

darman96

Aktives Mitglied
ah ja das war es aber ein Problem war auch, das die Gridview erstellt wird bevor der Async Task fertig wird.
Danke für die Hilfe
 

darman96

Aktives Mitglied
Noch ne frage.
bei:

Java:
imageView.setLayoutParams(new GridView.LayoutParams(500, 500));

gibt es da auch ne möglichkeit einzustellen, das die image view die komplette gridview spalte ausfüllt?

Edit:

Achja und weißt du wie man das hier: Grid Lists
mit den Balken machen könnte die die bilder hier etwas überlappen?
 
Zuletzt bearbeitet:

darman96

Aktives Mitglied
So ich habe ein weiteres Problem...
Wenn ich im Image Adapter bei den LayoutParams die größe höher stelle (300, 300 reicht schon) dann schmiert die App ab und gibt mir als Fehler meldung Fatal Signal 16 zurück was bedeutet das zu viel speicher verbraucht wird anscheinend.

also:
Java:
imageView.setLayoutParams(new GridView.LayoutParams(100, 100));

das funktioniert

Java:
imageView.setLayoutParams(new GridView.LayoutParams(300, 300));

das hier aber nicht.

Ich speicher die Bitmaps für die GridView ja in nem Vector, gibt es da irgendwelche möglichkeiten speicher zu sparen weil es sollten eigentlich auch noch mehr Bilder dazu kommen.
 

dzim

Top Contributor
Das Problem wird sein, das eben alle Bilder vorab schon als Bitmaps geladen werden. Vielleicht noch über den Umweg anderer Listen, die dann noch nicht vom GC weggeputzt wurden (beispielsweise in einem AsyncTask). Ich weiss ja nicht, was du mit den Bildern anstellst. machst du wirklich Thumbnails draus, oder lädst du die je in voller Grösse? Wenn letzteres, dann wandel die Bilder vorher so um, das sie auch nur deine maximale Grösse im Grid haben (Aspect Ratio).
Falls du es schon gemacht hast, musst du überlegen, die Daten asynchron, bzw. auf Bedarf hin, zu laden. Das sollte am Einfachsten gehen, indem du nicht eine List der Bitmaps vorhälst, sondern nur die File Deskriptoren. Dann kannst du sie im #getView nachladen (AsnycTask, dessen Ergebnis dann den View im #getView updated - so würde ich es zumindest einmal probieren).
 

dzim

Top Contributor
FileDescriptor | Android Developers

:-D

Nimm das nicht so wörtlich. Die meisten File-bezogenen Sachen in Android laufen auch nur über die File-Klasse. Nimm einfach die.
Also dein Ziel: Der Vector<Bitmap> wird z.B. zu einer ArrayList<File> (oder auch String mit dem Pfad zum File auf dem Telefonspeicher). Und lade die Bilder dann asynchron: Processing Bitmaps Off the UI Thread | Android Developers
#onPostExecute muss dann bei dir im View (idealerweise ein einfaches Layout in das der ImageView eingefügt werden kann; der sollte also übergeben werden) das Bild einfügen.

Ich würde ein möglichst simples Layout im #getView erstellen, das dem AsycTask aus dem Link oben übergeben und am Ende halt den erstellen ImageView da einfügen.

Das war jetzt alles etwas doppelt-gemoppelt, aber ich hoffe, du wird in etwa daraus schlau.
 

dzim

Top Contributor
Wobei. Bei einem zweiten Blick: Übernimm das Beispiel. Das sieht hinreichend für deinen Fall aus. Eventuell könnte man halt nur einen Spinner oder so anzeigen, das der Nutzer sieht, das etwas passiert. Habe leider mir selbst auch noch nie so sehr Gedanken um Speicher sparen gemacht und hab z.B. mit WeakReference auch noch nicht gearbeitet.
 

dzim

Top Contributor
Ja so ungefähr. Es gibt den Cache-Berich für deine App ( Context | Android Developers --> kann vom System "jederzeit" gelöscht werden), oder den "Files"-Bereicht (Context | Android Developers --> werden nur beim Deinstallieren der App entfernt).
Du müsstest dir also idealerweise Thumbnails (weil klein, spart Speicher - auch für die Galerie) herunterladen und vielleicht ein paar Metainformationen zusätzlich, wo man die richtigen Bilder findet. Deine App zeigt nun diese (asynchron geladenen!) Thumbnails an (indem die File-Objekte in den ArrayListAdapter übergeben werden) und lädt beim Klick auf ein Thumbnail da richtige Bild herunter (speichert es, damit es nicht jedes mal heruntergeladen werden muss!) und lädt es ebenfalls asynchron. Das Ziel ist, das deine UI nie blockiert. Eher zeigt es Spinner oder ähnliche Warteanimationen an, bis das eigentliche Bild da ist. Vergiss nur nicht, dass auch bei einem Fehler dieser irgendwie deutlich werden sollte (Spinner verschwindet und/oder Toast wird angezeigt, bzw. ein dauerhafter Text auf der UI).

In etwa klar?
 

darman96

Aktives Mitglied
Ja eigentlich schon nur ich krieg immer noch ne meldung:

12-08 22:22:22.970 19910-19923/com.example.erik.wallhavenviewer W/dalvikvm﹕ threadid=11: spin on suspend #1 threadid=1 (pcf=0)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer W/dalvikvm﹕ threadid=11: spin on suspend #2 threadid=1 (pcf=0)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ "AsyncTask #1" prio=5 tid=11 RUNNABLE
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ | group="main" sCount=0 dsCount=0 obj=0x41b91ca0 self=0x73d97768
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ | sysTid=19923 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1943632832
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ | state=R schedstat=( 0 0 0 ) utm=43 stm=8 core=0
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:739)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:715)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:753)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ at com.example.erik.wallhavenviewer.MainActivity$GetThumbnailsTask.getThumbnails(MainActivity.java:183)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ at com.example.erik.wallhavenviewer.MainActivity$GetThumbnailsTask.doInBackground(MainActivity.java:112)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ at com.example.erik.wallhavenviewer.MainActivity$GetThumbnailsTask.doInBackground(MainActivity.java:100)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ at java.lang.Thread.run(Thread.java:864)
12-08 22:22:23.721 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ [ 12-08 22:22:23.721 19910:19923 I/dalvikvm ]
"main" prio=5 tid=1 RUNNABLE JIT
...
12-08 22:22:30.108 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ | group="system" sCount=1 dsCount=0 obj=0x41b45fa8 self=0x726d3748
12-08 22:22:30.108 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ | sysTid=19914 nice=0 sched=0/0 cgrp=apps handle=1941033032
12-08 22:22:30.108 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ | state=S schedstat=( 0 0 0 ) utm=0 stm=0 core=0
12-08 22:22:30.108 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ #00 pc 00022624 /system/lib/libc.so (__futex_syscall3+8)
12-08 22:22:30.108 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ #01 pc 0000f054 /system/lib/libc.so (__pthread_cond_timedwait_relative+48)
12-08 22:22:30.108 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ #02 pc 0000f0b4 /system/lib/libc.so (__pthread_cond_timedwait+64)
12-08 22:22:30.108 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ #03 pc 000840b7 /system/lib/libdvm.so
12-08 22:22:30.108 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ #04 pc 0005fb99 /system/lib/libdvm.so
12-08 22:22:30.108 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ #05 pc 0000d300 /system/lib/libc.so (__thread_entry+72)
12-08 22:22:30.108 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ #06 pc 0000d498 /system/lib/libc.so (pthread_create+240)
12-08 22:22:30.108 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ at dalvik.system.NativeStart.run(Native Method)
12-08 22:22:30.108 19910-19923/com.example.erik.wallhavenviewer I/dalvikvm﹕ [ 12-08 22:22:30.108 19910:19923 E/dalvikvm ]
threadid=11: stuck on threadid=1, giving up
12-08 22:22:30.118 19910-19910/com.example.erik.wallhavenviewer A/libc﹕ Fatal signal 16 (SIGSTKFLT) at 0x00004dc6 (code=-6), thread 19910 (wallhavenviewer)

Ich hab mal nach diesem FATAL Signal16 gegooglet und nur gefunden das das scheinbar speicher probleme sind.
kann das daran liegen das ich den main thread während dem Download in ner while schleife laufen lasse damit die Grid View erst gefüllt wird wenn der download angeschlossen ist?

Edit:

Okay ich hab jetzt herausgefunden das man den Adapter der View updaten kann mit notifyDataSetChanged() das Problem ist nur mein Adapter hat die funktion nicht :/ da ist nur notify() und notifyAll()
 
Zuletzt bearbeitet:

dzim

Top Contributor
Was ist denn der "main thread" bei dir? Da ich deine Implementierung nicht kenne, kann ich dir diese Frage nicht genau beantworten, sorry.

#notifyDataSetChanged()
Wenn du einen ArrayAdapter verwendest, hat er diese Methode sehr wohl: ArrayAdapter | Android Developers
Oder verwendest du einen anderen? (Bin mittlerweile etwas raus aus dem Thread hier und möchte nicht alles noch einmal lesen).
 

darman96

Aktives Mitglied
Also meine Image Adapter Klasse erbt von BaseAdapter:
Java:
public class ImageAdapter extends BaseAdapter {
        private Context mContext;

        public ImageAdapter(Context context) {
            mContext = context;
        }

        @Override
        public int getCount() {
            return thumbnails.size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        public void updateView() {
            notifyDataSetChanged();
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ImageView imageView;
            if(convertView == null) {
                imageView = new ImageView(mContext);
                imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                imageView.setPadding(8, 8, 8, 8);
            } else {
                imageView = (ImageView) convertView;
            }
            Log.d("DEBUG", thumbnails.get(position).getAbsolutePath());
            Bitmap img = BitmapFactory.decodeFile(thumbnails.get(position).getAbsolutePath());
            imageView.setImageBitmap(img);

            return imageView;
        }
    }

Ich will ja einfach nur immer wenn neue Bilder geladen werden die Gridview Updaten
 

darman96

Aktives Mitglied
Also ich meine damit, dass ImageAdapter eine InnerClass von der Main Activity ist und die ArrayList ist auch in der Main Activity Klasse so das der Image Adapter direkt auf die ArrayList zugreifen kann.
 

dzim

Top Contributor
Hm. Ich würde es halt nicht (mehr) als innere Klasse machen. Ist aber vielleicht nur eine Geschmackssache.
Erklär mir bitte noch einmal kurz dein momentanes Problem. Denn rein vom Code-Schnipsel oben her, kann ich da nichts sehen, was problematisch wäre...
 

darman96

Aktives Mitglied
Das mit der inneren klasse ist nicht das Problem, macht es in dem Fall sogar leichter.
Mein Problem ist, das da ja der download über nen Async Task läuft der noch nicht fertig ist wenn die Gridview erstellt wird.
Deswegen sind noch keine Bilder da wenn die getView() vom Adapter aufgerufen wird. Ich müsste also irgendwie dem Adapter sagen wenn der download fertig ist, das der dann die Bilder laden soll.
 

dzim

Top Contributor
Eigentlich muss nur (wie in dem Bsp. mit dem AsyncTask beschrieben) dem Task die Referenz auf den ImageView im Grid gegeben werden und am Ende (in #onPostIrgendwas) müssen die Bilddaten dem ImageView übergeben werden. Der Rest (das Anzeigen) sollte damit automatisch gehen (dafür gibt es den Mechanismus schliesslich).
 

darman96

Aktives Mitglied
Aber es gibt nicht eine bestimmte image view, in der Gridview ist für jedes item eine.
Soweit ich weiß funktioniert das über die notifyDataSetChanged() oder wie die heißt, ich weiß nur nicht wo und wie ich die aufrufen soll.
 

dzim

Top Contributor
Ich glaube, wir haben uns hier missverstanden: Du brauchst die AsyncTasks umd die Bilddaten asynchron zu laden. Soweit klar. Aber ich habe nicht gesagt, dass du einen Task am Anfang starten musst und das war es dann.
Dein #getView lädt als erstes einen Stub (daher meinte ich auch, dass es klug wäre, ein via XML definiertes Layout zu nutzen - pro View), z.B. ein FrameLayout deren oberstes Kindelement der ImageView ist, dass aber (da anfangs noch "leer" auf Visibility#INVISIBLE oder gar #GONE gesetzt ist. Darunter liegt z.B. ein einfacher Spinner (der nachher entweder einfach nur vom IV überdeckt wird, oder aber den du explizit entfernst. Und zwar im AsyncTask. Und einen solchen startest du pro getView-Methoden-Aufruf. Der bekommt die WeakReference auf den ImageView des o.g. Layouts und füllt ihn in der #onPostIrgendwas-Methode (und versteckt/löscht/whatever den zuvor erwähnten Spinner).

Achtung:
Weiss jetzt nicht aus dem Stehgreif, ob sich hier dann ein ThreadPoolExecutor notwendig ist (ThreadPoolExecutor | Android Developers) aber laut dem hier (android - How to use AsyncTask with ThreadPoolExecutor - Stack Overflow) eher nicht (hab den Src-Code vom AsyncTask nicht mehr im Kopf (https://developer.android.com/reference/android/os/AsyncTask.html?hl=de), aber ein kurzes Googlen bringt mich zu der Auffassung, das du dir darum keinen Kopf machen musst (z.B. https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/AsyncTask.java).
 
Zuletzt bearbeitet:

darman96

Aktives Mitglied
hmm ich versteh noch nicht so ganz wo da der unterschied ist ob ein Layout in ner XML definiert ist oder nicht weil ich hab die GridView z.B. ja in nem XML File muss die dann aber doch trotzdem im Code erstellen.

Und was ich in der getView() machen soll versteh ich auch nicht...

Java:
public View getView(int position, View convertView, ViewGroup parent) {

        FrameLayout frameLayout;
        if(convertView == null) {
            frameLayout = new FrameLayout(mContext);
        } else {
            frameLayout = (FrameLayout) convertView;
        }


        return frameLayout;

    }
Sowas?
 

dzim

Top Contributor
Unterschied ist, dass du die UI deklarativ erställst und vom Code trennst. Ich würde dir wirklich empfehlen den Code-basierten Ansatz wirkich nur in Ausnahmefällen anzuwenden. Z.B. Wenn es nur ein ImageView ist. Ich hab das mal mit einem Graphen der Lib "GraphView" gemacht. Sonst aber verzichte ich auf die Erstellung von UI im Code und manipulier sie nur von dort. Das Konzept ist das MVC - oder eigentlich noch eher MVVM - vereinfacht: Strikte Trennung von UI-Deklaration und Controller (oder ViewModel - je nachdem). Du verwurschtelst halt beides.
Ich werde mal, wenn ich Zeit finde, etwas Code von Arbeit zusammenstellen und unkritisch machen und posten. Wird aber wohl erst Anfang der Woche werden...
 

Ähnliche Java Themen

Neue Themen


Oben