JavascriptProva

martedì 6 settembre 2016

J-Communicator: recupero delle immagini dal database con la correzione del salvataggio sotto formato Stringa.

Ora mi devo occupare del "ritiro" delle immagini dal database.
La funzione chiave è nella vecchia app la funzione refreshScreen.
Molto breve:
 private void refreshScreen(){
  mainLayout.removeAllViews();
  try{
   leggiDaDatabase(currentCat);
  } catch(Exception e){} 
  txtBarraCategoria.setText(currentCat);
 }
...fa riferimento a un'altra funzione, leggiDaDatabase(currentCat).
Vediamo anche questa:
 private void leggiDaDatabase(String categoria){
  Cursor crs=helper.query(categoria);
  do{
   LinearLayout layout=new LinearLayout(this);
   
   //crea la TextView ETICHETTA
   TextView txtEtichetta=new TextView(this);
   txtEtichetta.setText(crs.getString(1));
   txtEtichetta.setHeight(30);
   txtEtichetta.setSingleLine(false);
   layout.addView(txtEtichetta);

   //crea la TextView CATEGORIA
   TextView txtCategoria=new TextView(this);
   txtCategoria.setText(crs.getString(2));
   //...che non deve occupare spazio.
   txtCategoria.setVisibility(View.GONE);
   layout.addView(txtCategoria);
   
   
   //crea la ImageView IMMAGINE
   ImageView imageView=new ImageView(this);
   
   imageView.setImageBitmap(BitmapFactory.decodeByteArray(crs.getBlob(3), 0, crs.getBlob(3).length));
   layout.addView(imageView);
   imageView.getLayoutParams().width=100;
   imageView.getLayoutParams().height=100;
   
   //crea la TextView TIPO
   TextView txtTipo=new TextView(this);
   txtTipo.setText(crs.getString(4));
   //...che non deve occupare spazio
   txtTipo.setWidth(0);
   txtTipo.setHeight(0);
   txtTipo.setVisibility(View.GONE);
   layout.addView(txtTipo);
   
   //marca le views di tipo "categoria".Utile metterci il modello
   //grafico di cartella predeterminato.
   if(txtTipo.getText().equals("categoria")){
    GradientDrawable gd=new GradientDrawable();
    gd.setColor(Color.WHITE);
    gd.setStroke(5, Color.RED);
    layout.setBackground(gd);
   }
   else{
    layout.setBackgroundColor(Color.WHITE);
   }
   
   layout.setOrientation(LinearLayout.VERTICAL);
   RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
   params.leftMargin=crs.getInt(5);
   params.topMargin=crs.getInt(6);
   params.rightMargin=-250;
   params.bottomMargin=-250;
   layout.setLayoutParams(params);
   layout.setGravity(1);
   layout.setOnTouchListener(onTouchListener);
   mainLayout.addView(layout);
   if(txtTipo.getText().equals("categoria")){
    layout.getLayoutParams().width=imageView.getLayoutParams().width+20+10;
   }else{
    layout.getLayoutParams().width=imageView.getLayoutParams().width+20;
   }
   layout.getLayoutParams().height=imageView.getLayoutParams().height+35;
  } while(crs.moveToNext());
 }
questa, invece, è lunga...
La prima rimuove tutte le immagini (views) dal mainLayout, e chiama la seconda: la sua funzione si limita a questo, fondamentalmente.
La seconda prende un oggetto Cursor query(categoria) che seleziona i records del database in relazione al campo categoria, passato ad essa tramite il parametro categoria, nel quale viene fornito currentCat, ossia la categoria corrente.
Io credo che possa andare bene, con l'accortezza di modificare la decodifica delle immagini dal momento che adesso stanno nel database come stringhe, non più come arrays di bytes.
La parte da modificare è questa:
   //crea la ImageView IMMAGINE
   ImageView imageView=new ImageView(this);
   
   imageView.setImageBitmap(BitmapFactory.decodeByteArray(crs.getBlob(3), 0, crs.getBlob(3).length));
   layout.addView(imageView);
   imageView.getLayoutParams().width=100;
   imageView.getLayoutParams().height=100;
in cui da byte[] bisogna arrivare a String.

Copio la funzione refreshScreen che va chiamata in onStart.

onStart:
    @Override
    protected void ofnStart(){
        super.onStart();
        mLucchettiChangeListener.onLucchettiChange(boolLucchettoSinistroAperto,boolLucchettoDestroAperto);
        refreshScreen();

    }


refreshScreen:
    //Ricarica la schermata.
    private void refreshScreen(){
        mainLayout.removeAllViews();
        try{
            leggiDaDatabase(currentCat);
        } catch(Exception e){}
        txtBarraCategoria.setText(currentCat);
    }
e non mi riconosce leggiDaDatabase(normale, perché non l'ho ancora copiata-incollata), txtBarraCategoria e currentCat.
Per queste devo fare due digressioni.
txtBarraCategoria: cerchiamo l'oggetto nel file XML del layout di MainActivity: Eccolo:
        <TextView
            android:id="@+id/txtBarraCategoria"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/textView1"
            android:layout_alignParentBottom="true"
            android:layout_alignTop="@+id/lucchettoSinistro" />
Vado a dichiararne la variabile e a inizializzarla:
TextView txtBarraCategoria;

.....

txtBarraCategoria=(TextView)findViewById(R.id.txtBarraCategoria);

Ora si deve pensare alla categoria corrente.
Per essa mi sembra razionale usare lo stesso sistema usato per il mantenimento del settingMode.

Dichiaro e inizializzo la variabile currentCat fra le dichiarazioni delle variabili di istanza:
    //LA CATEGORIA CORRENTE
    String currentCat="iniziale";
Quindi la pongo in onSaveInstanceState:
    //per il salvataggio delle variabili in saveInstanceState
    @Override
    protected void onSaveInstanceState(Bundle state){
        super.onSaveInstanceState(state);
        state.putSerializable("boolLucchettoSinistroAperto",boolLucchettoSinistroAperto);
        state.putSerializable("boolLucchettoDestroAperto",boolLucchettoDestroAperto);
        state.putSerializable("categoria corrente",currentCat);
    }
e la recupero in onCreate:
        //Ripristino delle variabili con savedInstanceState
        if(savedInstanceState!=null){
            if(savedInstanceState.getSerializable("boolLucchettoSinistroAperto")!=null) {
                boolLucchettoSinistroAperto = (boolean) savedInstanceState
                        .getSerializable("boolLucchettoSinistroAperto");
            }
            if(savedInstanceState.getSerializable("boolLucchettoDestroAperto")!=null) {
                boolLucchettoDestroAperto = (boolean) savedInstanceState
                        .getSerializable("boolLucchettoDestroAperto");
            }
            if(savedInstanceState.getSerializable("categoria corrente")!=null){
                currentCat=(String)savedInstanceState.getSerializable("categoria corrente"):
            }

        }


Torniamo a refreshScreen:
    //Ricarica la schermata.
    private void refreshScreen(){
        mainLayout.removeAllViews();
        try{
            leggiDaDatabase(currentCat);
        } catch(Exception e){}
        txtBarraCategoria.setText(currentCat);
    }
non riconosce soltanto leggiDaDatabase, ovviamente, perché devo ancora copia-incollarla.
E facciamolo, dunque:
 private void leggiDaDatabase(String categoria){
  Cursor crs=helper.query(categoria);
  do{
   LinearLayout layout=new LinearLayout(this);
   
   //crea la TextView ETICHETTA
   TextView txtEtichetta=new TextView(this);
   txtEtichetta.setText(crs.getString(1));
   txtEtichetta.setHeight(30);
   txtEtichetta.setSingleLine(false);
   layout.addView(txtEtichetta);

   //crea la TextView CATEGORIA
   TextView txtCategoria=new TextView(this);
   txtCategoria.setText(crs.getString(2));
   //...che non deve occupare spazio.
   txtCategoria.setVisibility(View.GONE);
   layout.addView(txtCategoria);
   
   
   //crea la ImageView IMMAGINE
   ImageView imageView=new ImageView(this);
   
   imageView.setImageBitmap(BitmapFactory.decodeByteArray(crs.getBlob(3), 0, crs.getBlob(3).length));
   layout.addView(imageView);
   imageView.getLayoutParams().width=100;
   imageView.getLayoutParams().height=100;
   
   //crea la TextView TIPO
   TextView txtTipo=new TextView(this);
   txtTipo.setText(crs.getString(4));
   //...che non deve occupare spazio
   txtTipo.setWidth(0);
   txtTipo.setHeight(0);
   txtTipo.setVisibility(View.GONE);
   layout.addView(txtTipo);
   
   //marca le views di tipo "categoria".Utile metterci il modello
   //grafico di cartella predeterminato.
   if(txtTipo.getText().equals("categoria")){
    GradientDrawable gd=new GradientDrawable();
    gd.setColor(Color.WHITE);
    gd.setStroke(5, Color.RED);
    layout.setBackground(gd);
   }
   else{
    layout.setBackgroundColor(Color.WHITE);
   }
   
   layout.setOrientation(LinearLayout.VERTICAL);
   RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
   params.leftMargin=crs.getInt(5);
   params.topMargin=crs.getInt(6);
   params.rightMargin=-250;
   params.bottomMargin=-250;
   layout.setLayoutParams(params);
   layout.setGravity(1);
   layout.setOnTouchListener(onTouchListener);
   mainLayout.addView(layout);
   if(txtTipo.getText().equals("categoria")){
    layout.getLayoutParams().width=imageView.getLayoutParams().width+20+10;
   }else{
    layout.getLayoutParams().width=imageView.getLayoutParams().width+20;
   }
   layout.getLayoutParams().height=imageView.getLayoutParams().height+35;
  } while(crs.moveToNext());
 }
Non riconosce onTouchListener, perché non l'ho ancora implementata, per cui al momento la commentizzo, e helper, perché una istanza della classe Helper non è ancora stata creata in MainActivity.
La creo subito.
Helper helper;

.....

        //istanziazione dell'oggetto helper:
        helper=new Helper(this);
Credo di poterla sperimentare...

Le immagini appaiono, nel posto voluto, segno che le coordinate funzionano, ma... senza immagine!
E certo: ho dimenticato di correggere la decodifica delle immagini salvate sotto forma di stringa!
Isoliamo la parte:
            //crea la ImageView IMMAGINE
            ImageView imageView=new ImageView(this);

            imageView.setImageBitmap(BitmapFactory.decodeByteArray(crs.getBlob(3), 0, crs.getBlob(3).length));
            layout.addView(imageView);
            imageView.getwLayoutParams().width=100;
            imageView.getLayoutParams().height=100;
Ecco: da settare come immagine di imageView ho posto il risultato di questa funzione, che pongo nel modulo Funzioni:
 public static Bitmap StringToBitmap(String stringImage){
        byte[] b=Base64.decode(stringImage,Base64.DEFAULT);
        Bitmap bmp=BitmapFactory.decodeByteArray(b,0,b.length);
        return bmp;
    }
Quindi il pezzo diventa:
            //crea la ImageView IMMAGINE
            ImageView imageView=new ImageView(this);

            imageView.setImageBitmap(Funzioni.StringToBitmap(crs.getString(3)));
            layout.addView(imageView);
            imageView.getLayoutParams().width=100;
            imageView.getLayoutParams().height=100;
E vediamo...

PERFETTO! Le immagini sono di nuovo lì!

Nessun commento:

Posta un commento