mirror of
				https://github.com/oxen-io/session-android.git
				synced 2025-10-30 23:09:20 +00:00 
			
		
		
		
	Lottie play pause animation.
This commit is contained in:
		| @@ -126,6 +126,9 @@ dependencies { | ||||
|         exclude group: 'com.android.support', module: 'appcompat-v7' | ||||
|         exclude group: 'com.android.support', module: 'recyclerview-v7' | ||||
|     } | ||||
|  | ||||
|     implementation 'com.airbnb.android:lottie:3.0.7' | ||||
|  | ||||
|     implementation 'com.codewaves.stickyheadergrid:stickyheadergrid:0.9.4' | ||||
|     implementation 'com.github.dmytrodanylyk.circular-progress-button:library:1.1.3-S2' | ||||
|     implementation 'org.signal:android-database-sqlcipher:3.5.9-S3' | ||||
| @@ -171,6 +174,7 @@ dependencyVerification { | ||||
|         'cn.carbswang.android:NumberPickerView:18b3c316d62c7c277978a8d4ed57a5b8f4e943762264960f579a8a549c756729', | ||||
|         'com.tomergoldst.android:tooltips:4c56697dd1ad64b8066535c61f961a6d901e7ae5d97ae27084ba40ad620349b6', | ||||
|         'com.takisoft.fix:colorpicker:f5d0dbabe406a1800498ca9c1faf34db36e021d8488bf10360f29961fe3ab0d1', | ||||
|         'com.airbnb.android:lottie:6819ff968eb768096133c7873d63351705fd4ac424a0917d86c4145f5035097d', | ||||
|         'com.codewaves.stickyheadergrid:stickyheadergrid:5b4aa6a52a957cfd55f60f4220c11c0c371385a3cb9786cae03c260dcdef5794', | ||||
|         'androidx.appcompat:appcompat:49ad229add44f822fcb3c8405c3fddbd72660da6a839ce29e13158f5980514fd', | ||||
|         'com.melnykov:floatingactionbutton:15d58d4fac0f7a288d0e5301bbaf501a146f5b3f5921277811bf99bd3b397263', | ||||
| @@ -271,6 +275,7 @@ dependencyVerification { | ||||
|         'com.nineoldandroids:library:68025a14e3e7673d6ad2f95e4b46d78d7d068343aa99256b686fe59de1b3163a', | ||||
|         'com.klinkerapps:logger:177e325259a8b111ad6745ec10db5861723c99f402222b80629f576f49408541', | ||||
|         'com.google.android:flexbox:a9989fd13ae2ee42765dfc515fe362edf4f326e74925d02a10369df8092a4935', | ||||
|         'com.squareup.okio:okio:d78fac588458fc099e6c82e91fe5f0375c67434626451a3a77772c65d9eee85b', | ||||
|         'org.jsoup:jsoup:abeaf34795a4de70f72aed6de5966d2955ec7eb348eeb813324f23c999575473', | ||||
|         'org.whispersystems:signal-protocol-android:c80aac5f93114da2810e2e89437831f79fcbc8bece652f64aeab313a651cba85', | ||||
|         'org.signal:signal-metadata-java:2ce71cc4ec5dacfbaef4a265fceef61b8a09696b541994106a22a946762cbdcc', | ||||
| @@ -283,7 +288,6 @@ dependencyVerification { | ||||
|         'org.whispersystems:curve25519-android:b502bcf83efe001f09a7a9efda6f0fa772c43ed5924e97816296ed3503caa092', | ||||
|         'com.fasterxml.jackson.core:jackson-annotations:45d32ac61ef8a744b464c54c2b3414be571016dd46bfc2bec226761cf7ae457a', | ||||
|         'com.fasterxml.jackson.core:jackson-core:3083079be6088db2ed0a0c6ff92204e0aa48fa1de9db5b59c468f35acf882c2c', | ||||
|         'com.squareup.okio:okio:693fa319a7e8843300602b204023b7674f106ebcb577f2dd5807212b66118bd2', | ||||
|         'org.whispersystems:curve25519-java:0aadd43cf01d11e9b58f867b3c4f25c3194e8b0623d1953d32dfbfbee009e38d', | ||||
|     ] | ||||
| } | ||||
|   | ||||
| @@ -1,8 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|                 android:duration="@integer/play_button_animation_duration" | ||||
|                 android:interpolator="@android:interpolator/accelerate_decelerate" | ||||
|                 android:propertyName="pathData" | ||||
|                 android:valueFrom="@string/pause_icon_bottom_path_data" | ||||
|                 android:valueTo="@string/play_icon_bottom_path_data" | ||||
|                 android:valueType="pathType"/> | ||||
| @@ -1,8 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|                 android:duration="@integer/play_button_animation_duration" | ||||
|                 android:interpolator="@android:interpolator/accelerate_decelerate" | ||||
|                 android:propertyName="pathData" | ||||
|                 android:valueFrom="@string/play_icon_bottom_path_data" | ||||
|                 android:valueTo="@string/pause_icon_bottom_path_data" | ||||
|                 android:valueType="pathType"/> | ||||
| @@ -1,8 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|                 android:duration="@integer/play_button_animation_duration" | ||||
|                 android:interpolator="@android:interpolator/accelerate_decelerate" | ||||
|                 android:propertyName="pathData" | ||||
|                 android:valueFrom="@string/pause_icon_upper_path_data" | ||||
|                 android:valueTo="@string/play_icon_upper_path_data" | ||||
|                 android:valueType="pathType"/> | ||||
| @@ -1,8 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|                 android:duration="@integer/play_button_animation_duration" | ||||
|                 android:interpolator="@android:interpolator/accelerate_decelerate" | ||||
|                 android:propertyName="pathData" | ||||
|                 android:valueFrom="@string/play_icon_upper_path_data" | ||||
|                 android:valueTo="@string/pause_icon_upper_path_data" | ||||
|                 android:valueType="pathType"/> | ||||
| @@ -1,18 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|                  xmlns:tools="http://schemas.android.com/tools" | ||||
|                  android:drawable="@drawable/pause_icon" | ||||
|                  tools:targetApi="lollipop"> | ||||
|  | ||||
|     <target | ||||
|         android:name="@string/play_icon_group_parts" | ||||
|         android:animation="@animator/rotate_minus_90_animation"/> | ||||
|  | ||||
|     <target | ||||
|         android:name="@string/play_icon_top_path_name" | ||||
|         android:animation="@animator/upper_pause_to_play_animation"/> | ||||
|  | ||||
|     <target | ||||
|         android:name="@string/play_icon_bottom_path_name" | ||||
|         android:animation="@animator/bottom_pause_to_play_animation"/> | ||||
| </animated-vector> | ||||
| @@ -1,18 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|                  xmlns:tools="http://schemas.android.com/tools" | ||||
|                  android:drawable="@drawable/play_icon" | ||||
|                  tools:targetApi="lollipop"> | ||||
|  | ||||
|     <target | ||||
|         android:name="@string/play_icon_group_parts" | ||||
|         android:animation="@animator/rotate_90_animation"/> | ||||
|  | ||||
|     <target | ||||
|         android:name="@string/play_icon_top_path_name" | ||||
|         android:animation="@animator/upper_play_to_pause_animation"/> | ||||
|  | ||||
|     <target | ||||
|         android:name="@string/play_icon_bottom_path_name" | ||||
|         android:animation="@animator/bottom_play_to_pause_animation"/> | ||||
| </animated-vector> | ||||
| @@ -7,6 +7,7 @@ | ||||
|     <LinearLayout android:id="@+id/audio_widget_container" | ||||
|                   android:orientation="vertical" | ||||
|                   android:layout_width="match_parent" | ||||
|                   tools:background="#ff00ff" | ||||
|                   android:layout_height="wrap_content"> | ||||
|  | ||||
|         <LinearLayout android:layout_width="fill_parent" | ||||
| @@ -15,46 +16,39 @@ | ||||
|  | ||||
|             <org.thoughtcrime.securesms.components.AnimatingToggle | ||||
|                     android:id="@+id/control_toggle" | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:layout_width="48dp" | ||||
|                     android:layout_height="48dp" | ||||
|                     android:layout_gravity="center" | ||||
|                     android:gravity="center"> | ||||
|  | ||||
|                 <com.pnikosis.materialishprogress.ProgressWheel | ||||
|                 <FrameLayout | ||||
|                     android:id="@+id/progress_and_play" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="match_parent"> | ||||
|  | ||||
|                     <com.pnikosis.materialishprogress.ProgressWheel | ||||
|                         android:id="@+id/download_progress" | ||||
|                         android:layout_width="48dp" | ||||
|                         android:layout_height="48dp" | ||||
|                         android:visibility="gone" | ||||
|                         android:layout_width="match_parent" | ||||
|                         android:layout_height="match_parent" | ||||
|                         android:layout_gravity="center" | ||||
|                         app:matProg_barColor="@color/white" | ||||
|                         app:matProg_linearProgress="true" | ||||
|                         app:matProg_spinSpeed="0.333" | ||||
|                         tools:visibility="gone"/> | ||||
|                         app:matProg_spinSpeed="0.333" /> | ||||
|  | ||||
|                 <ImageView android:id="@+id/play" | ||||
|                            android:layout_width="wrap_content" | ||||
|                            android:layout_height="wrap_content" | ||||
|                            android:layout_gravity="center_vertical" | ||||
|                            android:gravity="center_vertical" | ||||
|                            android:clickable="true" | ||||
|                            android:visibility="gone" | ||||
|                            android:background="@drawable/circle_touch_highlight_background" | ||||
|                            android:src="@drawable/ic_play_circle_fill_white_48dp" | ||||
|                            android:scaleType="centerInside" | ||||
|                            tools:visibility="gone" | ||||
|                            android:contentDescription="@string/audio_view__play_accessibility_description"/> | ||||
|                     <com.airbnb.lottie.LottieAnimationView | ||||
|                         android:id="@+id/play" | ||||
|                         android:layout_width="48dp" | ||||
|                         android:layout_height="48dp" | ||||
|                         android:layout_gravity="center" | ||||
|                         android:background="@drawable/circle_touch_highlight_background" | ||||
|                         android:contentDescription="@string/audio_view__play_pause_accessibility_description" | ||||
|                         android:gravity="center_vertical" | ||||
|                         android:padding="12dp" | ||||
|                         android:visibility="gone" | ||||
|                         app:lottie_rawRes="@raw/lottie_play_pause" | ||||
|                         tools:visibility="visible" /> | ||||
|  | ||||
|                 <ImageView android:id="@+id/pause" | ||||
|                            android:layout_width="wrap_content" | ||||
|                            android:layout_height="wrap_content" | ||||
|                            android:layout_gravity="center_vertical" | ||||
|                            android:gravity="center_vertical" | ||||
|                            android:clickable="true" | ||||
|                            android:visibility="gone" | ||||
|                            android:background="@drawable/circle_touch_highlight_background" | ||||
|                            android:src="@drawable/ic_pause_circle_fill_white_48dp" | ||||
|                            android:scaleType="centerInside" | ||||
|                            android:contentDescription="@string/audio_view__pause_accessibility_description"/> | ||||
|                 </FrameLayout> | ||||
|  | ||||
|                 <ImageView android:id="@+id/download" | ||||
|                            android:layout_width="wrap_content" | ||||
|   | ||||
							
								
								
									
										1
									
								
								res/raw/lottie_play_pause.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								res/raw/lottie_play_pause.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| {"v":"5.5.2","fr":60,"ip":0,"op":30,"w":24,"h":24,"nm":"lottie-assets2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Play Outlines 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":28,"s":[90]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[14,12,0],"to":[-0.333,0,0],"ti":[0.333,0,0]},{"t":28,"s":[12,12,0]}],"ix":2},"a":{"a":0,"k":[7.25,8.25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7,-4],[-7,4],[7,4],[6.888,3.936]],"c":true}]},{"t":28,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-8,-1.969],[-7.984,1.999],[8,1.999],[7.998,-1.997]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[7.25,4.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Play Outlines 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":28,"s":[90]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[14,12,0],"to":[-0.333,0,0],"ti":[0.333,0,0]},{"t":28,"s":[12,12,0]}],"ix":2},"a":{"a":0,"k":[7.25,8.25,0],"ix":1},"s":{"a":0,"k":[100,-100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7,-4],[-7,4],[7,4],[6.888,3.936]],"c":true}]},{"t":28,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-8,-1.969],[-7.984,1.999],[8,1.999],[7.998,-1.997]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[7.25,4.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0}],"markers":[]} | ||||
| @@ -991,8 +991,7 @@ | ||||
|     <string name="conversation_item_received__contact_photo_description">Contact photo</string> | ||||
|  | ||||
|     <!-- audio_view --> | ||||
|     <string name="audio_view__play_accessibility_description">Play</string> | ||||
|     <string name="audio_view__pause_accessibility_description">Pause</string> | ||||
|     <string name="audio_view__play_pause_accessibility_description">Play ... Pause</string> | ||||
|     <string name="audio_view__download_accessibility_description">Download</string> | ||||
|  | ||||
|     <!-- QuoteView --> | ||||
|   | ||||
| @@ -1,9 +1,6 @@ | ||||
| package org.thoughtcrime.securesms.components; | ||||
|  | ||||
| import android.content.Context; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.interpolator.view.animation.FastOutSlowInInterpolator; | ||||
| import android.util.AttributeSet; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| @@ -11,6 +8,10 @@ import android.view.animation.Animation; | ||||
| import android.view.animation.AnimationUtils; | ||||
| import android.widget.FrameLayout; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.interpolator.view.animation.FastOutSlowInInterpolator; | ||||
|  | ||||
| import org.thoughtcrime.securesms.R; | ||||
| import org.thoughtcrime.securesms.util.ViewUtil; | ||||
|  | ||||
| @@ -41,13 +42,15 @@ public class AnimatingToggle extends FrameLayout { | ||||
|   public void addView(@NonNull View child, int index, ViewGroup.LayoutParams params) { | ||||
|     super.addView(child, index, params); | ||||
|  | ||||
|     if (getChildCount() == 1) { | ||||
|       current = child; | ||||
|       child.setVisibility(View.VISIBLE); | ||||
|     } else { | ||||
|       child.setVisibility(View.GONE); | ||||
|     if (!isInEditMode()) { | ||||
|       if (getChildCount() == 1) { | ||||
|         current = child; | ||||
|         child.setVisibility(View.VISIBLE); | ||||
|       } else { | ||||
|         child.setVisibility(View.GONE); | ||||
|       } | ||||
|       child.setClickable(false); | ||||
|     } | ||||
|     child.setClickable(false); | ||||
|   } | ||||
|  | ||||
|   public void display(@Nullable View view) { | ||||
|   | ||||
| @@ -1,15 +1,9 @@ | ||||
| package org.thoughtcrime.securesms.components; | ||||
|  | ||||
| import android.annotation.TargetApi; | ||||
| import android.content.Context; | ||||
| import android.content.res.ColorStateList; | ||||
| import android.content.res.TypedArray; | ||||
| import android.graphics.Color; | ||||
| import android.graphics.PorterDuff; | ||||
| import android.graphics.drawable.AnimatedVectorDrawable; | ||||
| import android.os.Build; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import android.util.AttributeSet; | ||||
| import android.view.MotionEvent; | ||||
| import android.view.View; | ||||
| @@ -19,6 +13,14 @@ import android.widget.ImageView; | ||||
| import android.widget.SeekBar; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
|  | ||||
| import com.airbnb.lottie.LottieAnimationView; | ||||
| import com.airbnb.lottie.LottieProperty; | ||||
| import com.airbnb.lottie.SimpleColorFilter; | ||||
| import com.airbnb.lottie.model.KeyPath; | ||||
| import com.airbnb.lottie.value.LottieValueCallback; | ||||
| import com.pnikosis.materialishprogress.ProgressWheel; | ||||
|  | ||||
| import org.greenrobot.eventbus.EventBus; | ||||
| @@ -36,23 +38,27 @@ import java.io.IOException; | ||||
| import java.util.Locale; | ||||
| import java.util.concurrent.TimeUnit; | ||||
|  | ||||
|  | ||||
| public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener { | ||||
| public final class AudioView extends FrameLayout implements AudioSlidePlayer.Listener { | ||||
|  | ||||
|   private static final String TAG = AudioView.class.getSimpleName(); | ||||
|  | ||||
|   private final @NonNull AnimatingToggle controlToggle; | ||||
|   private final @NonNull ViewGroup       container; | ||||
|   private final @NonNull ImageView       playButton; | ||||
|   private final @NonNull ImageView       pauseButton; | ||||
|   private final @NonNull ImageView       downloadButton; | ||||
|   private final @NonNull ProgressWheel   downloadProgress; | ||||
|   private final @NonNull SeekBar         seekBar; | ||||
|   private final @NonNull TextView        timestamp; | ||||
|   private static final int FORWARDS =  1; | ||||
|   private static final int REVERSE  = -1; | ||||
|  | ||||
|   private @Nullable SlideClickListener downloadListener; | ||||
|   private @Nullable AudioSlidePlayer   audioSlidePlayer; | ||||
|   private int backwardsCounter; | ||||
|   @NonNull private final AnimatingToggle     controlToggle; | ||||
|   @NonNull private final ViewGroup           container; | ||||
|   @NonNull private final View                progressAndPlay; | ||||
|   @NonNull private final LottieAnimationView playPauseButton; | ||||
|   @NonNull private final ImageView           downloadButton; | ||||
|   @NonNull private final ProgressWheel       downloadProgress; | ||||
|   @NonNull private final SeekBar             seekBar; | ||||
|   @NonNull private final TextView            timestamp; | ||||
|  | ||||
|   @Nullable private SlideClickListener downloadListener; | ||||
|   @Nullable private AudioSlidePlayer   audioSlidePlayer; | ||||
|             private int                backwardsCounter; | ||||
|             private int                lottieDirection; | ||||
|             private boolean            isPlaying; | ||||
|  | ||||
|   public AudioView(Context context) { | ||||
|     this(context, null); | ||||
| @@ -66,26 +72,19 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener | ||||
|     super(context, attrs, defStyleAttr); | ||||
|     inflate(context, R.layout.audio_view, this); | ||||
|  | ||||
|     this.container        = (ViewGroup) findViewById(R.id.audio_widget_container); | ||||
|     this.controlToggle    = (AnimatingToggle) findViewById(R.id.control_toggle); | ||||
|     this.playButton       = (ImageView) findViewById(R.id.play); | ||||
|     this.pauseButton      = (ImageView) findViewById(R.id.pause); | ||||
|     this.downloadButton   = (ImageView) findViewById(R.id.download); | ||||
|     this.downloadProgress = (ProgressWheel) findViewById(R.id.download_progress); | ||||
|     this.seekBar          = (SeekBar) findViewById(R.id.seek); | ||||
|     this.timestamp        = (TextView) findViewById(R.id.timestamp); | ||||
|     this.container         = findViewById(R.id.audio_widget_container); | ||||
|     this.controlToggle     = findViewById(R.id.control_toggle); | ||||
|     this.playPauseButton   = findViewById(R.id.play); | ||||
|     this.progressAndPlay   = findViewById(R.id.progress_and_play); | ||||
|     this.downloadButton    = findViewById(R.id.download); | ||||
|     this.downloadProgress  = findViewById(R.id.download_progress); | ||||
|     this.seekBar           = findViewById(R.id.seek); | ||||
|     this.timestamp         = findViewById(R.id.timestamp); | ||||
|  | ||||
|     this.playButton.setOnClickListener(new PlayClickedListener()); | ||||
|     this.pauseButton.setOnClickListener(new PauseClickedListener()); | ||||
|     lottieDirection = REVERSE; | ||||
|     this.playPauseButton.setOnClickListener(new PlayPauseClickedListener()); | ||||
|     this.seekBar.setOnSeekBarChangeListener(new SeekBarModifiedListener()); | ||||
|  | ||||
|     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||
|       this.playButton.setImageDrawable(context.getDrawable(R.drawable.play_icon)); | ||||
|       this.pauseButton.setImageDrawable(context.getDrawable(R.drawable.pause_icon)); | ||||
|       this.playButton.setBackground(context.getDrawable(R.drawable.ic_circle_fill_white_48dp)); | ||||
|       this.pauseButton.setBackground(context.getDrawable(R.drawable.ic_circle_fill_white_48dp)); | ||||
|     } | ||||
|  | ||||
|     if (attrs != null) { | ||||
|       TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.AudioView, 0, 0); | ||||
|       setTint(typedArray.getColor(R.styleable.AudioView_foregroundTintColor, Color.WHITE), | ||||
| @@ -117,20 +116,23 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener | ||||
|       downloadButton.setOnClickListener(new DownloadClickedListener(audio)); | ||||
|       if (downloadProgress.isSpinning()) downloadProgress.stopSpinning(); | ||||
|     } else if (showControls && audio.getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_STARTED) { | ||||
|       controlToggle.displayQuick(downloadProgress); | ||||
|       controlToggle.displayQuick(progressAndPlay); | ||||
|       seekBar.setEnabled(false); | ||||
|       downloadProgress.spin(); | ||||
|     } else { | ||||
|       controlToggle.displayQuick(playButton); | ||||
|       seekBar.setEnabled(true); | ||||
|       if (downloadProgress.isSpinning()) downloadProgress.stopSpinning(); | ||||
|       showPlayButton(); | ||||
|       lottieDirection = REVERSE; | ||||
|       playPauseButton.cancelAnimation(); | ||||
|       playPauseButton.setFrame(0); | ||||
|     } | ||||
|  | ||||
|     this.audioSlidePlayer = AudioSlidePlayer.createFor(getContext(), audio, this); | ||||
|   } | ||||
|  | ||||
|   public void cleanup() { | ||||
|     if (this.audioSlidePlayer != null && pauseButton.getVisibility() == View.VISIBLE) { | ||||
|     if (this.audioSlidePlayer != null && isPlaying) { | ||||
|       this.audioSlidePlayer.stop(); | ||||
|     } | ||||
|   } | ||||
| @@ -141,16 +143,14 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener | ||||
|  | ||||
|   @Override | ||||
|   public void onStart() { | ||||
|     if (this.pauseButton.getVisibility() != View.VISIBLE) { | ||||
|       togglePlayToPause(); | ||||
|     } | ||||
|     isPlaying = true; | ||||
|     togglePlayToPause(); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void onStop() { | ||||
|     if (this.playButton.getVisibility() != View.VISIBLE) { | ||||
|       togglePauseToPlay(); | ||||
|     } | ||||
|     isPlaying = false; | ||||
|     togglePauseToPlay(); | ||||
|  | ||||
|     if (seekBar.getProgress() + 5 >= seekBar.getMax()) { | ||||
|       backwardsCounter = 4; | ||||
| @@ -161,8 +161,7 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener | ||||
|   @Override | ||||
|   public void setFocusable(boolean focusable) { | ||||
|     super.setFocusable(focusable); | ||||
|     this.playButton.setFocusable(focusable); | ||||
|     this.pauseButton.setFocusable(focusable); | ||||
|     this.playPauseButton.setFocusable(focusable); | ||||
|     this.seekBar.setFocusable(focusable); | ||||
|     this.seekBar.setFocusableInTouchMode(focusable); | ||||
|     this.downloadButton.setFocusable(focusable); | ||||
| @@ -171,8 +170,7 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener | ||||
|   @Override | ||||
|   public void setClickable(boolean clickable) { | ||||
|     super.setClickable(clickable); | ||||
|     this.playButton.setClickable(clickable); | ||||
|     this.pauseButton.setClickable(clickable); | ||||
|     this.playPauseButton.setClickable(clickable); | ||||
|     this.seekBar.setClickable(clickable); | ||||
|     this.seekBar.setOnTouchListener(clickable ? null : new TouchIgnoringListener()); | ||||
|     this.downloadButton.setClickable(clickable); | ||||
| @@ -181,8 +179,7 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener | ||||
|   @Override | ||||
|   public void setEnabled(boolean enabled) { | ||||
|     super.setEnabled(enabled); | ||||
|     this.playButton.setEnabled(enabled); | ||||
|     this.pauseButton.setEnabled(enabled); | ||||
|     this.playPauseButton.setEnabled(enabled); | ||||
|     this.seekBar.setEnabled(enabled); | ||||
|     this.downloadButton.setEnabled(enabled); | ||||
|   } | ||||
| @@ -203,15 +200,9 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener | ||||
|   } | ||||
|  | ||||
|   public void setTint(int foregroundTint, int backgroundTint) { | ||||
|     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||
|       this.playButton.setBackgroundTintList(ColorStateList.valueOf(foregroundTint)); | ||||
|       this.playButton.setImageTintList(ColorStateList.valueOf(backgroundTint)); | ||||
|       this.pauseButton.setBackgroundTintList(ColorStateList.valueOf(foregroundTint)); | ||||
|       this.pauseButton.setImageTintList(ColorStateList.valueOf(backgroundTint)); | ||||
|     } else { | ||||
|       this.playButton.setColorFilter(foregroundTint, PorterDuff.Mode.SRC_IN); | ||||
|       this.pauseButton.setColorFilter(foregroundTint, PorterDuff.Mode.SRC_IN); | ||||
|     } | ||||
|     this.playPauseButton.addValueCallback(new KeyPath("**"), | ||||
|                                           LottieProperty.COLOR_FILTER, | ||||
|                                           new LottieValueCallback<>(new SimpleColorFilter(foregroundTint))); | ||||
|  | ||||
|     this.downloadButton.setColorFilter(foregroundTint, PorterDuff.Mode.SRC_IN); | ||||
|     this.downloadProgress.setBarColor(foregroundTint); | ||||
| @@ -230,49 +221,53 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener | ||||
|   } | ||||
|  | ||||
|   private void togglePlayToPause() { | ||||
|     controlToggle.displayQuick(pauseButton); | ||||
|  | ||||
|     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||
|       AnimatedVectorDrawable playToPauseDrawable = (AnimatedVectorDrawable)getContext().getDrawable(R.drawable.play_to_pause_animation); | ||||
|       pauseButton.setImageDrawable(playToPauseDrawable); | ||||
|       playToPauseDrawable.start(); | ||||
|     } | ||||
|     startLottieAnimation(FORWARDS); | ||||
|   } | ||||
|  | ||||
|   private void togglePauseToPlay() { | ||||
|     controlToggle.displayQuick(playButton); | ||||
|  | ||||
|     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||
|       AnimatedVectorDrawable pauseToPlayDrawable = (AnimatedVectorDrawable)getContext().getDrawable(R.drawable.pause_to_play_animation); | ||||
|       playButton.setImageDrawable(pauseToPlayDrawable); | ||||
|       pauseToPlayDrawable.start(); | ||||
|     } | ||||
|     startLottieAnimation(REVERSE); | ||||
|   } | ||||
|  | ||||
|   private class PlayClickedListener implements View.OnClickListener { | ||||
|     @TargetApi(Build.VERSION_CODES.LOLLIPOP) | ||||
|   private void startLottieAnimation(int direction) { | ||||
|     showPlayButton(); | ||||
|  | ||||
|     if (lottieDirection == direction) { | ||||
|       return; | ||||
|     } | ||||
|     lottieDirection = direction; | ||||
|  | ||||
|     playPauseButton.pauseAnimation(); | ||||
|     playPauseButton.setSpeed(direction * 2); | ||||
|     playPauseButton.resumeAnimation(); | ||||
|   } | ||||
|  | ||||
|   private void showPlayButton() { | ||||
|     downloadProgress.setInstantProgress(1); | ||||
|     downloadProgress.setVisibility(VISIBLE); | ||||
|     playPauseButton.setVisibility(VISIBLE); | ||||
|     controlToggle.displayQuick(progressAndPlay); | ||||
|   } | ||||
|  | ||||
|   private class PlayPauseClickedListener implements View.OnClickListener { | ||||
|  | ||||
|     @Override | ||||
|     public void onClick(View v) { | ||||
|       try { | ||||
|         Log.d(TAG, "playbutton onClick"); | ||||
|         if (audioSlidePlayer != null) { | ||||
|           togglePlayToPause(); | ||||
|           audioSlidePlayer.play(getProgress()); | ||||
|       if (lottieDirection == REVERSE) { | ||||
|         try { | ||||
|           Log.d(TAG, "playbutton onClick"); | ||||
|           if (audioSlidePlayer != null) { | ||||
|             togglePlayToPause(); | ||||
|             audioSlidePlayer.play(getProgress()); | ||||
|           } | ||||
|         } catch (IOException e) { | ||||
|           Log.w(TAG, e); | ||||
|         } | ||||
|       } else { | ||||
|         Log.d(TAG, "pausebutton onClick"); | ||||
|         if (audioSlidePlayer != null) { | ||||
|           togglePauseToPlay(); | ||||
|           audioSlidePlayer.stop(); | ||||
|         } | ||||
|       } catch (IOException e) { | ||||
|         Log.w(TAG, e); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private class PauseClickedListener implements View.OnClickListener { | ||||
|     @TargetApi(Build.VERSION_CODES.LOLLIPOP) | ||||
|     @Override | ||||
|     public void onClick(View v) { | ||||
|       Log.d(TAG, "pausebutton onClick"); | ||||
|       if (audioSlidePlayer != null) { | ||||
|         togglePauseToPlay(); | ||||
|         audioSlidePlayer.stop(); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| @@ -291,12 +286,16 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener | ||||
|   } | ||||
|  | ||||
|   private class SeekBarModifiedListener implements SeekBar.OnSeekBarChangeListener { | ||||
|  | ||||
|     private boolean wasPlaying; | ||||
|  | ||||
|     @Override | ||||
|     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {} | ||||
|  | ||||
|     @Override | ||||
|     public synchronized void onStartTrackingTouch(SeekBar seekBar) { | ||||
|       if (audioSlidePlayer != null && pauseButton.getVisibility() == View.VISIBLE) { | ||||
|       wasPlaying = isPlaying; | ||||
|       if (audioSlidePlayer != null && isPlaying) { | ||||
|         audioSlidePlayer.stop(); | ||||
|       } | ||||
|     } | ||||
| @@ -304,7 +303,7 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener | ||||
|     @Override | ||||
|     public synchronized void onStopTrackingTouch(SeekBar seekBar) { | ||||
|       try { | ||||
|         if (audioSlidePlayer != null && pauseButton.getVisibility() == View.VISIBLE) { | ||||
|         if (audioSlidePlayer != null && wasPlaying) { | ||||
|           audioSlidePlayer.play(getProgress()); | ||||
|         } | ||||
|       } catch (IOException e) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Alan Evans
					Alan Evans