2

ObjectAnimator.ofFloat(Object target, String xPropertyName, String yPropertyName, Path path) scheint in API 21 zu arbeiten, aber nicht 23? Einfache Reproduktion: Hier ist die Aktivität und das Layout. Versuchen Sie lange auf die Textansicht zu drücken, beide Ebenen funktionieren. Aber, tippen Sie einfach auf der Ansicht: 21 funktioniert, aber nicht 23.ObjectAnimator auf Pfad funktioniert nicht auf Marshmallow?

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     final View hello = findViewById(R.id.hello); 
     final Path p = new Path(); 
     p.addCircle(-200, 0, 100, Path.Direction.CW); 
     hello.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       ObjectAnimator a = ObjectAnimator.ofFloat(hello, "translationX", "translationY", p); 
       a.setDuration(1000); 
       a.start(); 
      } 
     }); 
     hello.setOnLongClickListener(new View.OnLongClickListener() { 
      @Override 
      public boolean onLongClick(View v) { 
       ObjectAnimator a = ObjectAnimator.ofFloat(hello, "scaleX", 2); 
       a.setDuration(1000); 
       a.start(); 
       return true; 
      } 
     }); 
    } 
} 

-

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/activity_main" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="letstwinkle.com.pathtest.MainActivity"> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Hello World!" 
     android:layout_alignParentTop="true" 
     android:layout_alignParentEnd="true" 
     android:layout_marginEnd="63dp" 
     android:layout_marginTop="210dp" 
     android:id="@+id/hello" 
     android:background="#880033"/> 
</RelativeLayout> 

Dies kann das gleiche wie dieser Fehler im Juni berichtet werden. https://code.google.com/p/android/issues/detail?id=212776

+0

Getestet habe ich mit AppCompatActivity und Emulator-Versionen 22 und 23: am 22 arbeitet, auf 23 zu bewegen beginnt, aber friert gleich danach. – 0X0nosugar

+1

Ich hatte ein Update-Listener hinzugefügt, und schaute durch den animierten Wert - auf API 21 unterscheidet, aber auf API 23 ist es stabil, immer die gleichen "-100" - um genau zu sein. –

+0

Und mit path.lineTo (200,200) - es funktioniert perfekt. Müssen Sie in den Kreis Sachen tauchen, oder sogar etwas mit Textansicht hat sich geändert. –

Antwort

2

Als Workaround können Sie eine ValueAnimator mit einer benutzerdefinierten AnimatorUpdateListener verwenden.

Zuerst benötigen Sie eine PathMeasure für Ihre Path. Dadurch erhalten Sie Zugriff auf Daten wie Pfadlänge und Koordinaten auf dem Pfad für eine bestimmte Entfernung (0 < = Abstand < = Pfadlänge).

Path p = new Path(); 
p.addCircle(-200, 0, 100, Path.Direction.CW); 
PathMeasure pathMeasure = new PathMeasure(p, true); 

Dann stellen Sie die ValueAnimator von 0 auf die Weglänge zu animieren.

final ValueAnimator a = ValueAnimator.ofFloat(0,pathMeasure.getLength()); 
a.setDuration(1000); 

Als Nächstes fügen Sie ein AnimatorUpdateListener, um tatsächlich die View zu manipulieren. Ich werde zunächst zeigen, wie es hinzuzufügen:

MyAnimatorUpdateListener myListener = new MyAnimatorUpdateListener(hello, pathMeasure); 
a.addUpdateListener(myListener); 

Fahren Sie mit dem OnClickListener:

hello.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     a.start(); 
    } 
}); 

Bitte beachten Sie, dass ich den Code geändert und erklärt/initialisiert, um die ValueAnimator außerhalb des OnClickListener besser zu bekommen Leistung: Auf diese Weise wird es nicht jedes Mal neu erstellt, wenn ich auf TextView klicke und so der Müllsammler weniger beschäftigt sein wird :).

Schließlich ist der AnimatorUpdateListener Code:

class MyAnimatorUpdateListener implements ValueAnimator.AnimatorUpdateListener 
{ 
    private View view; 
    private PathMeasure pathMeasure; 
    private float[] coordinates = new float[2]; 

    public MyAnimatorUpdateListener(View view, PathMeasure pathMeasure) 
    { 
     this.view = view; 
     this.pathMeasure = pathMeasure; 
    } 

    @Override 
    public void onAnimationUpdate(ValueAnimator animation) { 
     float distance = (float) animation.getAnimatedValue(); 
     pathMeasure.getPosTan(distance, coordinates, null); 
     view.setTranslationX(coordinates[0]); 
     view.setTranslationY(coordinates[1]); 
    } 
} 
+0

Sieht vielversprechend aus. Was ich hackte, war nur, x und y getrennt zu animieren, aber eins mit einem Beschleunigungsinterpolator und eins mit einer Verzögerung, um etwas Art von Kreis zu erzeugen. Definitiv nicht so gut. Ich werde zurückschleifen und dies umsetzen, wenn ich kann. – user3175580

Verwandte Themen