JavascriptProva

mercoledì 21 settembre 2016

Esercizio sullo scaling di un'immagine.

Adesso è il momento di ripetere lo zooming.
Purtroppo devo rivedermi il codice di sana pianta perché non me lo ricordo.

Quello che ti ricordi?
ScaleGestureDetector.simpleOn... Boh?

Ascoltami, Ciccio.
Innanzitutto devi definire una classe, che è una classe Listener.
Estende un altro listener.
E che cosa ascolta questo listener?

Ascolta onScale, ossia la scalatura.
Vediamo.
    private class QualunqueListener extends ScaleGestureDetector.SimpleOnScaleGestureListener{

    }
Ho denominato a cazzo il listener per rimarcare che la parte fondamentale è ScaleGestureDetector.SimpleOnScaleGestureListener.

Non ha metodi da implementare, però.
Perlomeno non mi appare nulla da implementare, probabilmente perché non è un'interfaccia ma una classe.
Vediamo sulla documentazione ufficiale che accidenti è ScaleGestureDetector.SimpleOnScaleGestureListener.

Sì, ho detto giusto! Questo ScaleGestureDetector.SimpleOnScaleGestureListener è una classe, e non un'interfaccia come altri listeners.

Dunque il suo metodo onScale è già implementato, e non deve essere obbligatoriamente overridato, per questo non appare nessun avviso.
Dobbiamo overridarlo a memoria!

Ora, onScale ha come parametro un oggetto di tipo ScaleGestureDetector, ossia lo stesso oggetto di cui questo listener estende la classe SimpleOnScaleGestureListener.

Proviamo...

    private class QualunqueListener extends ScaleGestureDetector.SimpleOnScaleGestureListener{
        @Override
        public boolean onScale(ScaleGestureDetector detector){
            
            return true;
        }

    }
E siamo qui.
Mandala!

    private class IlMioListener extends ScaleGestureDetector.SimpleOnScaleGestureListener{
        @Override
        public boolean onScale(ScaleGestureDetector detector){
            
            return true;
        }
    }
Ecco. Ora ho una misura da rilevare da detector.
scaleFactor*=detector.getScaleFactor();
la misura getScaleFactor esprime il fattore scala, per il quale una grandezza va moltiplicata.
Cerchiamo di riscrivere il tutto anche se scaleFactor mi resta ancora non definito.
    private class Listener extends ScaleGestureDetector.SimpleOnScaleGestureListener{
        @Override
        public boolean onScale(ScaleGestureDetector detector){
            scaleFactor*=detector.getScaleFactor();
            return true;
        }
    }
Per il momento, ottimo.
Al posto del nome di fantasia, il programma originale cosa mette?
ScaleListener.
Bene. E' il nome della classe.


scaleFactor possiamo dichiararlo fra le variabili di istanza.
float scaleFactor=1.f;
E ora?
Una classe va istanziata. Dove si istanzia la classe ScaleListener o accidentichetipiglia... nomi di fantasia che le ho dato prima?
Vediamo...

In realtà si deve istanziare un oggetto ScaleGestureDetector.
Fra i parametri, esso porta un'istanza della classe ScaleListener o l'accidentechetipigliaListener.
Dichiarazione e istanziazione di ScaleGestureDetector.
ScaleGestureDetector mDetector;
e poi, nel costruttore:
    public Immagine(Context context) {
        super(context);
        this.context=context;
        mImage=getResources().getDrawable(R.drawable.facciadaculo);
        mImage.setBounds(0,0,300,300);
        mDetector=new ScaleGestureDetector(context,new Listener());
Ed ecco che all'evento onTouchEvent:
    @Override
    public boolean onTouchEvent(MotionEvent event){
        mDetector.onTouchEvent(event);


        return true;
    }
Dovrebbe funzionare...

Ovviamente, anche:
    @Override
    public void onDraw(Canvas canvas){
        canvas.save();
        canvas.scale(scaleFactor,scaleFactor);
        mImage.draw(canvas);
        canvas.restore();
    }
e vediamo...

Ho dimenticato invalidate():
    private class Listener extends ScaleGestureDetector.SimpleOnScaleGestureListener{
        @Override
        public boolean onScale(ScaleGestureDetector detector){
            scaleFactor*=detector.getScaleFactor();
            invalidate();
            return true;
        }
    }
che non sia questo il problema?

Sì, era quello: adesso funziona!

Adesso Mandala!

public class Immagine extends View{
    Context context;
    Drawable mImage;
    float scaleFactor=1.f;
    ScaleGestureDetector mDetector;
    float lastX, lastY, posX, posY;
    public Immagine(Context context) {
        super(context);
        this.context=context;
        mImage=getResources().getDrawable(R.drawable.facciadaculo);
        mImage.setBounds(0,0,300,300);
        mDetector=new ScaleGestureDetector(context, new ScaleListener());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        mDetector.onTouchEvent(event);
        return true;
    }

    @Override
    public void onDraw(Canvas canvas){
        super.onDraw(canvas);
        canvas.save();
        canvas.scale(scaleFactor,scaleFactor);
        mImage.draw(canvas);
        canvas.restore();
    }


    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener{
        @Override
        public boolean onScale(ScaleGestureDetector detector){
            scaleFactor*=detector.getScaleFactor();
            invalidate();
            return true;
        }
    }

}


Nessun commento:

Posta un commento