Italian [RISOLTO] Movimento oggetto non fluido

Discussion in 'Italian Forum' started by Sagenut, Apr 5, 2018.

  1. Sagenut

    Sagenut Active Member Licensed User

    Ciao!
    Ho fatto un piccolo programma di test per vedere di riuscire a spostare una immagine trascinandola.
    L'immagine l'ho caricata su un Panel per avere gli eventi Touch che mi pare non siano disponibili con la ImageView.
    Fondamentalmente mi pare che funzioni solo che il movimento dell'oggetto è decisamente traballante, soprattutto se lo muovo molto lentamente.
    La sub che si occupa del movimento è questa:
    Code:
    Sub Panel1_Touch (Action As Int, X As Float, Y As Float)
        
    Select Action
            
    Case Panel1.ACTION_DOWN
                toccox = X
                toccoy = Y
            
    Case Panel1.ACTION_MOVE
                Panel1.Left = Panel1.Left + (X - toccox)
                Panel1.Top = Panel1.Top + (Y - toccoy)
        
    End Select
    End Sub
    Secondo voi è corretto il mio codice?
    Come posso fare per ottenere un movimento un pò più fluido e preciso?
    Grazie
     
  2. LucaMs

    LucaMs Expert Licensed User

    Code:
    Dim r As Reflector
        r.Target = Panel1
        r.SetOnTouchListener(
    "Panel1_Touch")
     
    Sagenut likes this.
  3. Star-Dust

    Star-Dust Expert Licensed User

    Metti un po' di olio nel panel :p
    Il problema è legato al wrap dell'oggetto che fa b4a. Android legge da 3 a 5 punti (multi touch) e ti da quel senso di vibrazione

    Ma c'è un modo per evitarlo,leggendo solo il primo punto usando il reflector
     
    Sagenut likes this.
  4. Sagenut

    Sagenut Active Member Licensed User

    Adesso vedo di integrare la soluzione che mi avete indicato.
    Mi rendo conto che 9 volte su 10 la soluzione è usare il Reflector.
    Il problema di usare il Reflector è capire quale metodo Java bisogna andare a puntare di volta in volta.
    E questo al momento non mi sembra troppo semplice, ma direi che è abbastanza normale visto che sono un benemerito principiante.
    Conto di riuscire a capire come fare prima dell'arrivo dell'Alzheimer.
     
  5. LucaMs

    LucaMs Expert Licensed User

    Mettiamo che il movimento che devi eseguire sia semplicemente in un'Activity; ciapa quelle 3 righe di codice e schiaffale nella Activity_Create, non devi fare altro.

    Semmai, se vuoi farlo per più panel, crea una routine apposita, passandogli ogni volta un panel (o una View qualunque).

    Code:
    Sub SetOnTouchListener(Vw As View, EventName As String)
        
    Dim r As Reflector
        r.Target = Vw
        r.SetOnTouchListener(EventName & 
    "_Touch")
    End Sub
    Meglio ancora, potresti dichiarare una mReflector nella Process_Globals ed usare quella nella routine, al posto di r.
     
    Sagenut likes this.
  6. LucaMs

    LucaMs Expert Licensed User

    Sagenut likes this.
  7. Sagenut

    Sagenut Active Member Licensed User

    Aggiungendo il tuo codice in Activity_Create ottengo questo errore appena clicco l'immagine:
    Nella riga del r.setontouchlistener mi indica come dovrebbe essere la Sub (in neretto le differenze):
    ma non capisco esattamente come devo modificarla.
     
  8. LucaMs

    LucaMs Expert Licensed User

    Sorry

    Code:
    Private Sub Panel1_Touch (o As Object, ACTION As Int, x As Float, y As Float, motion As Object) As Boolean
     
    Sagenut likes this.
  9. Sagenut

    Sagenut Active Member Licensed User

    Sicuramente sbaglio qualcosa io......adesso addirittura crasha l'app.
    Code:
    Sub Globals
        
    Dim lstContacts As ListView
        
    Public Panel1 As Panel
        
    Dim r As Reflector
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
    If FirstTime Then
            cu.Initialize
        
    End If
        
    Activity.LoadLayout("1")
        
    For Each c As cuContact In cu.FindAllContacts(True)
            lstContacts.AddSingleLine2(c.DisplayName, c)
        
    Next
        r.Target = Panel1
        r.SetOnTouchListener(
    "Panel1_Touch")
    End Sub

    Sub Panel1_Touch (o As Object, Action As Int, X As Float, Y As Float, motion As Object)
        
    Select Action
            
    Case Panel1.ACTION_DOWN
                toccox = X
                toccoy = Y
            
    Case Panel1.ACTION_MOVE
                Panel1.Left = Panel1.Left + (X - toccox)
                Panel1.Top = Panel1.Top + (Y - toccoy)
        
    End Select
        
    Return True
    End Sub
    Il Reflector l'ho messo nelle Globals......ma avevo comunque l'errore anche mettendolo in Activity_Create.
    L'immagine viene reperita dai contatti.
     
  10. LucaMs

    LucaMs Expert Licensed User

    metti:
    Code:
    If Panel1 IS Null Then
       
    Log("è null")
    Else
       
    log("NON è null")
       r.Target = Panel1
       r.SetOnTouchListener(
    "Panel1_Touch")
    End If
    Il seguito non c'entra con il crash, ma:
    1) Panel1 è privato
    2) r lo chiamerei mReflector e comunque lo dichiarerei nella Process_Globals
     
    Sagenut likes this.
  11. Sagenut

    Sagenut Active Member Licensed User

    Mi dice che il Reflector non può essere dichiarato in Process_Globals e và messo in Globals.
    Non la facevo così irta la cosa.
    E non gradisce nemmeno
    Code:
    If Panel1 IS Null Then
     
    LucaMs likes this.
  12. LucaMs

    LucaMs Expert Licensed User

    Comunque è probabile che Panel1 sia Null quando cerchi di aggiungere il listener.

    Va in crash... con quale messaggio d'errore?

    Eventualmente, puoi provare ad impostare il listener in una routine, da chiamare usando CallSubDelayed.

    Code:
    Sub Globals
        
    Dim lstContacts As ListView
        
    Private Panel1 As Panel
        
    Dim mReflector As Reflector
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
    If FirstTime Then
            cu.Initialize
        
    End If
        
    Activity.LoadLayout("1")
        
    For Each c As cuContact In cu.FindAllContacts(True)
            lstContacts.AddSingleLine2(c.DisplayName, c)
        
    Next
        CallSubDelayed(Me, 
    "ImpostaListener")
    End Sub

    Sub ImpostaListener
        mReflector.Target = Panel1
        mReflector.SetOnTouchListener(
    "Panel1_Touch")
    End Sub

    Sub Panel1_Touch (o As Object, Action As Int, X As Float, Y As Float, motion As Object)
        
    Select Action
            
    Case Panel1.ACTION_DOWN
                toccox = X
                toccoy = Y
            
    Case Panel1.ACTION_MOVE
                Panel1.Left = Panel1.Left + (X - toccox)
                Panel1.Top = Panel1.Top + (Y - toccoy)
        
    End Select
        
    Return True
    End Sub
     
  13. Sagenut

    Sagenut Active Member Licensed User

    Ho applicato la tua correzione:
    Appena clicco sull'immagine.
    Quindi il Reflector dovrebbe comunque averlo impostato correttamente, credo.
     
  14. Sagenut

    Sagenut Active Member Licensed User

    Parentesi: testo su Emulatore.......devo provare su dispositivo reale?

    EDIT

    Crasha anche su dispositivo reale.
     
  15. LucaMs

    LucaMs Expert Licensed User

    Questo sarebbe meglio, sempre; ma non penso sia questo il problema, adesso.

    Direi che, senza impiccarci troppo (anche perché io stesso sto scrivendo una domanda complessa alla quale spero mi rispondano :D), dovresti fare così:

    1) crea una nuova classe e chiamala DraggableView
    2) elimina il contenuto e sostituiscilo con questo:
    Code:
    'DraggableView class module
    Sub Class_Globals
       
    Private innerView As View
       
    Private panel1 As Panel
       
    Private downx, downy As Int
       
    Private ACTION_DOWN, ACTION_MOVE, ACTION_UP As Int
    End Sub

    Sub Initialize(Activity As Activity, v As View)
       innerView = v
       panel1.Initialize(
    "")
       panel1.Color = 
    Colors.Transparent
       
    Activity.AddView(panel1, v.Left, v.Top, v.Width, v.Height)
       ACTION_DOWN = 
    Activity.ACTION_DOWN
       ACTION_MOVE = 
    Activity.ACTION_MOVE
       ACTION_UP = 
    Activity.ACTION_UP
       
    Dim r As Reflector
       r.Target = panel1
       r.SetOnTouchListener(
    "Panel1_Touch"'why reflection instead of the regular Panel_Touch event? Good question which deserves a forum thread of its own (not related to classes)...
    End Sub

    Private Sub Panel1_Touch (o As Object, ACTION As Int, x As Float, y As Float, motion As Object) As Boolean
       
    If ACTION = ACTION_DOWN Then
          downx = x
          downy = y
       
    Else
          innerView.Left = innerView.Left + x - downx
          innerView.Top = innerView.Top + y - downy     
          panel1.Left = innerView.Left
          panel1.Top = innerView.Top
       
    End If
       
    Return True
    End Sub

    poi nella Globals della tua Activity:
    Private mDrag As DraggableView

    nella Activity_Create:
    mDrag.Initialize(Activity, Panel1)


    Se va ancora in crash, significa che Panel1 non è stato ancora caricato (prova il codice del post #10)
     
    Sagenut likes this.
  16. Sagenut

    Sagenut Active Member Licensed User

    Vi allego il progetto se vi capita di volerci guardare.
    Per oggi penso di fare pausa.
    Grazie dell'aiuto.
     

    Attached Files:

  17. LucaMs

    LucaMs Expert Licensed User

    Ecco, si fa prima ;)
     
  18. LucaMs

    LucaMs Expert Licensed User

    Usando quella classe, DraggableView, funziona.

    NOTA che per testarlo ho commentato tutte le linee che riguardano i contatti, ho provato solo il trascinamento di Panel1.
     

    Attached Files:

    Sagenut likes this.
  19. Sagenut

    Sagenut Active Member Licensed User

    Appena posso verifico.
    L'unica differenza che ho notato al volo guardando la classe Draggable è che la Sub del Touch è Private....a parte il resto della implementazione.
    Che possa essere quella la differenza importante?
    In ogni caso vi farò sapere...... Anche se a voi esperti non serve. :oops:
    Grazie del tuo tempo.
     
  20. LucaMs

    LucaMs Expert Licensed User

    Non penso sia questo il problema.

    Solo che non ho voglia (né testa) per cercare bug vari; meglio usare direttamente la classe :).
     
    Sagenut likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice