Autore Topic: Anteprima di Bitmap in una ListView con Layout Semplice  (Letto 829 volte)

Offline andryx

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung GT - S5830
  • Sistema operativo:
    Eclipse su Windows 7
Anteprima di Bitmap in una ListView con Layout Semplice
« il: 19 Aprile 2013, 11:56:42 CEST »
0
Salve a tutti!! :D

Il problema che sto per affrontare è sorto dopo aver cercato di riadattare la guida di Qlimax Topic: [medio] ListView con layout personalizzato tramite un SimpleAdapter ( veramente ben fatta ), preticamente anzicchè spiattellare nella lista risorse drawable a caso vorrei mettergli delle anteprime 50x50 di immagini prese da una cartella fisica nella sdcard.

dunque riadattando la classe persona ( che per me è PhotoData ) in questo modo:

Codice (Java): [Seleziona]
package com.example.photosharing;

import android.graphics.Bitmap;
//import java.io.File;
//import android.net.Uri;

public class PhotoData {
        private String titolo;
        private String data;
        private Bitmap icona;
       
        public PhotoData(String title, String date, Bitmap icn) {
                super();
//              File f = new File(file);
                this.titolo=title;
                this.data=date;
                this.icona=icn;
        }
       
        public String getTitle() {
                return titolo;
        }
       
        public String getDate(){
                return data;
        }
       
        public Bitmap getIcon() {
                return icona;
        }

}

successivamente costruisco il layout item_list.xml di ciascun item della ListView

Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
       xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="fill_parent"
       android:layout_height="60dip"
       android:padding="5dip">


        <ImageView
               android:id="@+id/photoIcon"
               android:layout_width="50dip"
               android:layout_height="50dip">
        </ImageView>


        <TextView
               android:text="Titolo"
               android:layout_marginLeft="5dip"
               android:textAppearance="?android:attr/textAppearanceLarge"
               android:textColor="#505050"
               android:id="@+id/photoTitle"
               android:layout_toRightOf="@+id/photoIcon"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"></TextView>
        <TextView
               android:text="Data"
               android:textAppearance="?android:attr/textAppearanceMedium"
               android:textColor="#6b71f1"
               android:id="@+id/photoDate"
               android:layout_alignLeft="@+id/photoTitle"
               android:layout_alignParentBottom="true"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content">
        </TextView>
</RelativeLayout>

dunque predispongo la schermata della activity principale con una ListView nel file ps_main.xml:

Codice (XML): [Seleziona]
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".PSMainActivity" >

    <ListView
       android:id="@+id/photoList"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_above="@+id/get_button"
       android:layout_alignParentLeft="true"
       android:layout_alignParentTop="true" >

    </ListView>

</RelativeLayout>

a questo punto spiattello il contenuto della lista con il metodo seguente nella activity principale PSMainActivity

Codice (Java): [Seleziona]
package com.example.photosharing;


import java.io.File;
import java.util.*;

import android.os.Bundle;
import android.provider.Settings;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.content.Context;
import android.content.Intent; // per gestire gli intent
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;       // per gestire le viste


public class PSMainActivity extends Activity {
        DBAdapter db;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.ps_main);
        }
       
        @Override
        protected void onResume() {
                super.onResume();
                db = new DBAdapter(this);
                createPhotoList();
        }
       
        public void createPhotoList(){
                //lista delle foto che la listview visualizzerà
                ArrayList<PhotoData> photos = new ArrayList<PhotoData>();
               
                //riempimento della lista da interrogazione del database
                db.open();
                try {
                        Cursor c = db.getAllPhotos();
                        if(c.moveToFirst()) {
                                do {
                                        //aggiungo foto alla lista
                                        photos.add( new PhotoData(
                                                        c.getString(DBAdapter.NOME_FOTO),
                                                        c.getString(DBAdapter.ID_FOTO),
                                                        getIconFromBitmap(c.getString(DBAdapter.PATH_FOTO))  
/* Anteprima della foto come oggetto Bitmap vedi metodo più in basso*/
                                                        )
                                        );

                                }while(c.moveToNext());
                        }
                }catch (SQLiteException exc) {
                        Log.d("ErrorDB", "I can't get all photos");
                }
                db.close();
               
                if(!photos.isEmpty()) { // controllo che la lista non sia vuota

                        //Questa è la lista che rappresenta la sorgente dei dati della listview
                //ogni elemento è una mappa(chiave->valore)
                       
                        ArrayList<HashMap<String, Object>> data=new ArrayList<HashMap<String, Object>>();
                       
                        for (int i=0; i < photos.size(); i++) {
                                PhotoData f = photos.get(i); //per ogni foto
                               
                                HashMap<String,Object> photoMap = new HashMap<String,Object>();  //creiamo una mappa di valori
                               
                                photoMap.put("title", f.getTitle()); // associo chiave => valore
                                photoMap.put("data", f.getDate());
                                photoMap.put("icon", f.getIcon());
                               
                                data.add(photoMap); // aggiungo la mappa di valori alla sorgente dei dati
                        }
                       
                        Log.i("onCreate", "set ListView on main view");
                       
                        // Costruisco l'adapter...
                        String[] from={"icon","title","data"}; //...dai valori contenuti in queste chiavi...
                        int[] to={R.id.photoIcon,R.id.photoTitle,R.id.photoDate}; //...agli id delle view...
                       
                        SimpleAdapter adapter = new SimpleAdapter(
                                        getApplicationContext(),        //Context
                                        data,                                           //mappa dati
                                        R.layout.item_list,                     //
                                        from,                                           //chiavi delle sorgenti
                                        to                                                      //id del layout
                                        );
                       
                        ListView list=(ListView)findViewById(R.id.photoList);
                        list.setAdapter(adapter);
                        Log.i("createPhotLIst", "populated listview");
                       
                        list.setOnItemClickListener(new ItemListClick());
                        list.setOnItemLongClickListener(new ItemListLongClick());

                }
                else{
                        TextView msg = (TextView)findViewById(R.id.textMsg);
                        msg.setText("No photos in DataBase");
                }
        }
        public Bitmap getIconFromBitmap(String file){
                /* ecco come tento di realizzare l'anteprima */
                Bitmap icon = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(file),50,50,false);
                return icon;
        }
        /* implements click event of list */
        private class ItemListClick implements OnItemClickListener{

                @Override
                public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                                long arg3) {
                        // TODO Auto-generated method stub
                       
                }
               
        }
       
        private class ItemListLongClick implements OnItemLongClickListener{

                @Override
                public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
                                int arg2, long arg3) {
                        // TODO Auto-generated method stub
                        return false;
                }
               
        }
       
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                // Inflate the menu; this adds items to the action bar if it is present.
                getMenuInflater().inflate(R.menu.ps_main, menu);
                return true;
        }

}

Non ho postato la classe DBAdapter perchè è la classica classe per la gestione al database dove non faccio altro che memorizzare stringhe. La chiave PATH_FOTO non è altro che il percorso dell'immagine nella sd-card di cui voglio creare l'anteprima da mettere sulla ListView. E Adesso andiamo all'errore:

Codice: [Seleziona]
04-19 11:48:31.330: I/onCreate(7578): set ListView on main view
04-19 11:48:31.340: I/createPhotLIst(7578): populated listview
04-19 11:48:31.340: I/LOCATION(7578): provider: network
04-19 11:48:31.430: W/System.err(7578): java.io.FileNotFoundException: /android.graphics.Bitmap@40555488 (No such file or directory)
04-19 11:48:31.440: W/System.err(7578):         at org.apache.harmony.luni.platform.OSFileSystem.open(Native Method)
04-19 11:48:31.440: W/System.err(7578):         at dalvik.system.BlockGuard$WrappedFileSystem.open(BlockGuard.java:232)
04-19 11:48:31.440: W/System.err(7578):         at java.io.FileInputStream.<init>(FileInputStream.java:80)
04-19 11:48:31.440: W/System.err(7578):         at java.io.FileInputStream.<init>(FileInputStream.java:132)
04-19 11:48:31.440: W/System.err(7578):         at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:362)
04-19 11:48:31.440: W/System.err(7578):         at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:412)
04-19 11:48:31.440: W/System.err(7578):         at android.graphics.drawable.Drawable.createFromPath(Drawable.java:800)
04-19 11:48:31.440: W/System.err(7578):         at android.widget.ImageView.resolveUri(ImageView.java:528)
04-19 11:48:31.440: W/System.err(7578):         at android.widget.ImageView.setImageURI(ImageView.java:305)
04-19 11:48:31.440: W/System.err(7578):         at android.widget.SimpleAdapter.setViewImage(SimpleAdapter.java:264)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.SimpleAdapter.bindView(SimpleAdapter.java:192)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.SimpleAdapter.createViewFromResource(SimpleAdapter.java:126)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.SimpleAdapter.getView(SimpleAdapter.java:114)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.AbsListView.obtainView(AbsListView.java:1611)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.ListView.makeAndAddView(ListView.java:1795)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.ListView.fillDown(ListView.java:718)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.ListView.fillFromTop(ListView.java:775)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.ListView.layoutChildren(ListView.java:1646)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.AbsListView.onLayout(AbsListView.java:1441)
04-19 11:48:31.490: W/System.err(7578):         at android.view.View.layout(View.java:7175)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.RelativeLayout.onLayout(RelativeLayout.java:912)
04-19 11:48:31.490: W/System.err(7578):         at android.view.View.layout(View.java:7175)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.FrameLayout.onLayout(FrameLayout.java:338)
04-19 11:48:31.490: W/System.err(7578):         at android.view.View.layout(View.java:7175)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1254)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1130)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.LinearLayout.onLayout(LinearLayout.java:1047)
04-19 11:48:31.490: W/System.err(7578):         at android.view.View.layout(View.java:7175)
04-19 11:48:31.490: W/System.err(7578):         at android.widget.FrameLayout.onLayout(FrameLayout.java:338)
04-19 11:48:31.490: W/System.err(7578):         at android.view.View.layout(View.java:7175)
04-19 11:48:31.490: W/System.err(7578):         at android.view.ViewRoot.performTraversals(ViewRoot.java:1146)
04-19 11:48:31.490: W/System.err(7578):         at android.view.ViewRoot.handleMessage(ViewRoot.java:1866)
04-19 11:48:31.490: W/System.err(7578):         at android.os.Handler.dispatchMessage(Handler.java:99)
04-19 11:48:31.490: W/System.err(7578):         at android.os.Looper.loop(Looper.java:130)
04-19 11:48:31.490: W/System.err(7578):         at android.app.ActivityThread.main(ActivityThread.java:3687)
04-19 11:48:31.490: W/System.err(7578):         at java.lang.reflect.Method.invokeNative(Native Method)
04-19 11:48:31.490: W/System.err(7578):         at java.lang.reflect.Method.invoke(Method.java:507)
04-19 11:48:31.490: W/System.err(7578):         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
04-19 11:48:31.490: W/System.err(7578):         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
04-19 11:48:31.490: W/System.err(7578):         at dalvik.system.NativeStart.main(Native Method)
04-19 11:48:31.490: I/System.out(7578): resolveUri failed on bad bitmap uri: android.graphics.Bitmap@40555488

(chiedo scusa anticipatamente allo staff se ho postato in maniera errata il logcat)

Risultato: il testo si visualizza normalmente ma senza le anteprime (dove rimane lo spazio vuoto)...questo per ogni Foto nel database.
Dunque chiedo  O:-) umilmente supporto!!
Android to iOS: How many phone mount your OS??
iOS to Android: mmm...are you joking me?

Offline rs94

  • Utente normale
  • ***
  • Post: 227
  • Respect: +21
    • Mostra profilo
  • Dispositivo Android:
    Sony Ericsson Xperia Arc S
  • Sistema operativo:
    Windows 8
Re:Anteprima di Bitmap in una ListView con Layout Semplice
« Risposta #1 il: 19 Aprile 2013, 13:59:40 CEST »
0
Hai inserito nel manifest le permission per read / write dalla scheda sd?

(permission.READ_EXTERNAL_STORAGE,permission..WRITE_EXTERNAL_STORAGE)
L'unica certezza è il dubbio.
Dubitare di se stessi è il primo segno di intelligenza.

Offline andryx

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung GT - S5830
  • Sistema operativo:
    Eclipse su Windows 7
Re:Anteprima di Bitmap in una ListView con Layout Semplice
« Risposta #2 il: 19 Aprile 2013, 16:43:02 CEST »
0
Hai inserito nel manifest le permission per read / write dalla scheda sd?

(permission.READ_EXTERNAL_STORAGE,permission..WRITE_EXTERNAL_STORAGE)

Si certo!! a che ci sono posto pure il manifest (ovviamente ci sono tante altre cose che servono per altre funzioni della app che sto creando)

Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.photosharing"
   android:versionCode="1"
   android:versionName="1.0" >

    <uses-sdk
       android:minSdkVersion="8"
       android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-feature android:name="android.hardware.camera"/>
    <permission android:protectionLevel="signature" android:name="com.example.photosharing.MAPS_RECEIVE"></permission>
    <uses-permission android:name="com.example.photosharing.MAPS_RECEIVE"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
    <uses-feature android:required="true" android:glEsVersion="0x00020000"/>
    <application
       android:allowBackup="true"
       android:icon="@drawable/ic_launcher"
       android:label="@string/app_name"
       android:theme="@style/AppTheme" >
        <activity
           android:name="com.example.photosharing.PSMainActivity"
           android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:theme="@style/AppTheme" android:label="Getting Photo" android:name="GettingPhotoActivity">
            <intent-filter>
                <action android:name="com.example.photosharing.GettingPhotoActivity"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>
        <activity android:theme="@style/AppTheme" android:label="Send to Web" android:name="SendToWebActivity">
            <intent-filter>
                <action android:name="com.example.photosharing.SendToWebActivity"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>
        <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="ilMioKeydiGoogle"/>
    </application>

</manifest>
Android to iOS: How many phone mount your OS??
iOS to Android: mmm...are you joking me?

Offline rs94

  • Utente normale
  • ***
  • Post: 227
  • Respect: +21
    • Mostra profilo
  • Dispositivo Android:
    Sony Ericsson Xperia Arc S
  • Sistema operativo:
    Windows 8
Re:Anteprima di Bitmap in una ListView con Layout Semplice
« Risposta #3 il: 19 Aprile 2013, 16:57:59 CEST »
0
Se il problema non era quello c'è un errore quando cerchi di caricare le immagini... nello specifico il percorso non esiste (il file non c'è).
Prova nel metodo getIconFromBitmap ad aggiungere
Codice (Java): [Seleziona]
Log.e("Percorso immagine",file); e vedi cosa ti compare nel logcat :)
L'unica certezza è il dubbio.
Dubitare di se stessi è il primo segno di intelligenza.

Offline andryx

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung GT - S5830
  • Sistema operativo:
    Eclipse su Windows 7
Re:Anteprima di Bitmap in una ListView con Layout Semplice
« Risposta #4 il: 19 Aprile 2013, 18:01:22 CEST »
0
Lo escludo! ho modificato la app settando un OnClickLIstener alla ListView dove al click faccio aprire la foto con il visualizzatore nativo di android così:

Codice (Java): [Seleziona]
list.setOnItemClickListener(new OnItemClickListener(){
@Override
        public void onItemClick(AdapterView<?> parent, View arg1, int position,
                        long arg3) {
                // TODO Auto-generated method stub
               
                /* dichiaro un oggetto HashMap e faccio il cast dell'oggetto ottenuto dall'item*/
                HashMap<String,Object> photoMap = (HashMap<String,Object>) (parent.getItemAtPosition(position));
                /* estraggo la stringa con la chiave richiesta */
                String obj = photoMap.get("title").toString();
                Toast.makeText(getApplicationContext(), obj , Toast.LENGTH_SHORT).show();
               
                Cursor c = db.getPhoto( Long.parseLong(photoMap.get("data").toString()) );
                if(c.moveToFirst()) {
                        Intent intent = new Intent();
                        intent.setAction(Intent.ACTION_VIEW);
                        File f = new File(c.getString(DBAdapter.PATH_FOTO));
                        if(f.exists()){
                                intent.setDataAndType(
                                                Uri.fromFile(f),
                                                c.getString(DBAdapter.MIME_TYPE) + "/*"
                                                );
                                startActivity(intent);
                        }else {
                                Log.w("click LIstener", "no such file on path"+f.toString());
                        }
                }
               
        }
        }
);

Ed effettivamente mi si apre la foto!! XD può essere invece che l'adapter della listview non riesce a prendersi le Bitmap?? Se fosse così cosa dovrei passare?
Android to iOS: How many phone mount your OS??
iOS to Android: mmm...are you joking me?

Offline rs94

  • Utente normale
  • ***
  • Post: 227
  • Respect: +21
    • Mostra profilo
  • Dispositivo Android:
    Sony Ericsson Xperia Arc S
  • Sistema operativo:
    Windows 8
Re:Anteprima di Bitmap in una ListView con Layout Semplice
« Risposta #5 il: 19 Aprile 2013, 18:59:06 CEST »
0
Sinceramente non saprei in quanto io solitamente utilizzo un arrayadapter con l'override del metodo getview... perchè a mio parere è più flessibile e puoi farci quello che vuoi :)
Se ti interessa un esempio è qui: http://www.anddev.it/index.php/topic,432.0.html

Altrimenti aspetta qualcuno che abbia idea di come aiutarti :)
L'unica certezza è il dubbio.
Dubitare di se stessi è il primo segno di intelligenza.