Android Animated Vector Drawable doesn't work properly - android

I have the following ImageView
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/image_header_toggle"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_marginEnd="10dp"
app:layout_constraintBottom_toBottomOf="#+id/text_header_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="#+id/text_header_name"
android:src="#drawable/ic_header_off_to_on"
app:tint="?attr/colorPrimary"/>
and two animated drawables that I made through https://shapeshifter.design/
ic_header_off_to_on.xml
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:name="group"
android:pivotX="12"
android:pivotY="12">
<path
android:name="path_1"
android:pathData="M 15.41 16.58 L 10.83 12 L 15.41 7.41 L 14 6 L 8 12 L 14 18 L 15.41 16.58 Z"
android:fillColor="#000"
android:strokeWidth="1"/>
</group>
</vector>
</aapt:attr>
<target android:name="group">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="rotation"
android:duration="300"
android:valueFrom="0"
android:valueTo="-90"
android:valueType="floatType"
android:interpolator="#android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
</animated-vector>
ic_header_on_to_off.xml
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:name="group"
android:pivotX="12"
android:pivotY="12"
android:rotation="270">
<path
android:name="path_1"
android:pathData="M 15.41 16.58 L 10.83 12 L 15.41 7.41 L 14 6 L 8 12 L 14 18 L 15.41 16.58 Z"
android:fillColor="#000"
android:strokeWidth="1"/>
</group>
</vector>
</aapt:attr>
<target android:name="group">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="rotation"
android:duration="300"
android:valueFrom="270"
android:valueTo="0"
android:valueType="floatType"
android:interpolator="#android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
</animated-vector>
and this code that I use to toggle the icons
val res = if (isExpanded) R.drawable.ic_header_off_to_on else R.drawable.ic_header_on_to_off
image_header_toggle.setImageResource(res)
(view.image_header_toggle.drawable as? AnimatedVectorDrawable)?.start()
image_header_toggle.setOnClickListener { isExpanded = !isExpanded }
The off_to_on animation seems to play nicely but the on_to_off one doesn't, the image simply gets replace.
It looks like this >_<

I just found this question and tried something out. A more elegant solution is to remove your Kotlin code with mine. This will achieve a smooth transition and you even can change the duration of it. Instead of needing 2 drawables you can just use one. If you are using Fragment instead of Activity, don't forget to set view.findViewById instead of findViewById:
class MainActivity : AppCompatActivity() {
private var isExpanded = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val imageView = findViewById<ImageView>(R.id.image_header_toggle)
imageView.setOnClickListener {
if (!isExpanded) {
imageView.animate().apply {
duration = 500
rotation(0f)
isExpanded = true}
}else{
imageView.animate().apply {
duration = 500
rotation(-90f)
isExpanded = false}
}
}
}
}

Related

How to make loading animation in android xml

I would like to create an Animation with 3 dots (one Is bigger than the other two and have different color), this animation should loop at start center one should be bigger after that dot on the right should be bigger and change color.
I created this XML:
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
xmlns:android="http://schemas.android.com/apk/res/android">
<aapt:attr name="android:drawable">
<vector
android:width="300dp"
android:height="80dp"
android:viewportWidth="300"
android:viewportHeight="80">
<path
android:name="left_selected"
android:pathData="M30,44m-30,0a30,30 0,1 1,60 0a30,30 0,1 1,-60 0"
android:fillColor="#CBA818"/>
<path
android:name="center"
android:pathData="M150,40m-40,-0a40,40 0,1 0,80 -0a40,40 0,1 0,-80 -0"
android:fillColor="#757575"/>
<path
android:name="right"
android:pathData="M270,44m-30,-0a30,30 0,1 0,60 -0a30,30 0,1 0,-60 -0"
android:fillColor="#757575"/>
</vector>
</aapt:attr>
<target android:name="path">
<aapt:attr name="android:animation">
<set>
<objectAnimator
android:duration="217"
android:interpolator="#android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:valueFrom="..."
android:valueTo=..."
android:valueType="pathType" />
<objectAnimator
android:duration="144"
android:interpolator="#android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:startOffset="217"
android:valueFrom="..."
android:valueTo="..."
android:valueType="pathType" />
<objectAnimator
android:duration="239"
android:interpolator="#android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:startOffset="361"
android:valueFrom="..."
android:valueTo="..."
android:valueType="pathType" />
</set>
</aapt:attr>
</target>
</animated-vector>
How could I change a color of dot in animation tag? Is my way of thinking correct with this approach?
You can try this approach
XML:-
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/clCenterArrows"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="#id/ivImage"
app:layout_constraintEnd_toEndOf="#id/ivImage"
app:layout_constraintStart_toStartOf="#id/ivImage"
app:layout_constraintTop_toTopOf="#id/ivImage">
<ImageView
android:id="#+id/ivArrows"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_tag_instruction_arrows"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/vTagCenter"
android:layout_width="#dimen/d12"
android:layout_height="#dimen/d12"
android:background="#drawable/rounded_fill_red"
app:layout_constraintBottom_toBottomOf="#id/ivArrows"
app:layout_constraintEnd_toEndOf="#id/ivArrows"
app:layout_constraintStart_toStartOf="#id/ivArrows"
app:layout_constraintTop_toTopOf="#id/ivArrows" />
<View
android:id="#+id/vAnim1"
android:layout_width="#dimen/d12"
android:layout_height="#dimen/d12"
android:background="#drawable/rounded_fill_red"
app:layout_constraintBottom_toBottomOf="#id/ivArrows"
app:layout_constraintEnd_toEndOf="#id/ivArrows"
app:layout_constraintStart_toStartOf="#id/ivArrows"
app:layout_constraintTop_toTopOf="#id/ivArrows" />
<View
android:id="#+id/vAnim2"
android:layout_width="#dimen/d12"
android:layout_height="#dimen/d12"
android:background="#drawable/rounded_fill_red"
app:layout_constraintBottom_toBottomOf="#id/ivArrows"
app:layout_constraintEnd_toEndOf="#id/ivArrows"
app:layout_constraintStart_toStartOf="#id/ivArrows"
app:layout_constraintTop_toTopOf="#id/ivArrows" />
</androidx.constraintlayout.widget.ConstraintLayout>
Kotlin:-
val runnableAnim = object : Runnable {
override fun run() {
vAnim1?.visibility = View.VISIBLE
vAnim2?.visibility = View.VISIBLE
vAnim1
?.animate()
?.scaleX(3f)
?.scaleY(3f)
?.alpha(0f)
?.setDuration(1000)
?.withEndAction {
kotlin.run {
vAnim1?.scaleX = 1f
vAnim1?.scaleY = 1f
vAnim1?.alpha = 1f
}
}
vAnim2
?.animate()
?.scaleX(3f)
?.scaleY(3f)
?.alpha(0f)
?.setDuration(700)
?.withEndAction {
kotlin.run {
vAnim2?.scaleX = 1f
vAnim2?.scaleY = 1f
vAnim2?.alpha = 1f
}
}
animationHandler.postDelayed(this, 1500)
}
}
runnableAnim.run()
This is the output of the animation

How to animate gradient in vector drawable?

I need to animate a path in a vector using a gradient, but I cannot find a solution on how to do this. Any help is appreciated.
<?xml version="1.0" encoding="utf-8"?>
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="80dp"
android:height="88dp"
android:viewportWidth="80"
android:viewportHeight="88">
<path
android:name="curve"
android:pathData="M79.6,54.8623V54.3618C79.7,52.8601 79.8,50.9579 79.9,48.8555V48.6553C79.9,47.1536 80,45.6519 80,44.0501C80,42.4482 80,40.8464 79.9,39.4448V39.2446C79.8,37.1422 79.7,35.24 79.6,33.7383V32.537C79.5,30.9352 79.4,29.934 79.4,29.8339C79.4,29.6337 79.4,29.5336 79.3,29.3333V29.2332C79.3,28.9329 79.2,28.6325 79.2,28.4323V28.3322C78.5,24.9283 76.6,21.2241 74.3,18.521C73.4,17.4198 72.4,16.5188 71.4,15.7179C71.3,15.6177 70.2,14.8168 68.3,13.5154C66.1,12.0137 63.0999,10.0114 59.5999,8.0091C53.5,4.3049 48,1.802 47.2999,1.5017H47.2C45.6,0.8009 43.5999,0.3003 41.5,0.1001C41.0999,0.1001 40.7,0 40.2999,0H38.5999C35.7999,0.1001 33.2,0.6007 31.1,1.5017C30.8,1.6018 25.2999,4.1047 19,7.8089C19,7.8089 18.9,7.909 18.7999,7.909C12.4,11.7133 7.3,15.4175 7.0999,15.6177C5.4999,16.8191 4.0999,18.3208 2.7999,20.223C2.4999,20.6234 2.4999,21.7247 3.7999,21.7247H6.9999C8.4,21.7247 8.7,20.9238 10.2,19.8225C11.9,18.6212 15.2,16.1183 21.4,12.4141C25.7999,9.8111 30,7.7088 32,6.8077C32,6.8077 32.0999,6.8077 32.0999,6.7076H32.4C32.9,6.5074 33.2,6.3072 33.2,6.3072C34.6,5.7065 36.6,5.306 38.7,5.2059H39.5C40.0999,5.2059 40.7,5.306 41.2999,5.306C42.5999,5.5063 43.7,5.7065 44.7,6.1069C44.7999,6.1069 44.9,6.207 45,6.207C45,6.207 45.1,6.207 45.2,6.3072C46.1,6.7076 51.3,9.1103 56.9,12.4141C60.2,14.3163 63.1999,16.3185 65.1999,17.7201C66.9999,18.9215 68.1,19.7224 68.1,19.8225C68.9,20.4232 69.7,21.2241 70.4,22.1251C72.3,24.5279 73.8,27.8316 74,30.3345C74,30.3345 74.1,31.4357 74.2,33.0375V36.4414C74.2999,38.6439 74.4,41.1468 74.4,43.8498C74.4,46.5529 74.2999,49.1559 74.2,51.2582V54.6621C74.1,56.364 74,57.3652 74,57.3652C73.7,59.868 72.2,63.1718 70.4,65.5745C69.7,66.4755 68.9,67.3766 68.1,67.8771C68.1,67.8771 66.9999,68.678 65.1999,69.9795C63.1999,71.3811 60.2,73.3834 56.9,75.2855C51.3,78.5893 46.1,80.992 45.2,81.3925C45.1,81.3925 45.0999,81.4926 45,81.4926C44.9,81.4926 44.7999,81.5927 44.7,81.5927C43.7999,81.9932 42.5999,82.2935 41.2999,82.3936C40.7,82.4937 40.0999,82.4937 39.5,82.4937H38.7C36.6,82.4937 34.6,82.0933 33.2,81.3925C33.2,81.3925 32.9,81.2924 32.4,80.992C32.3,80.992 32.3,80.8919 32.2,80.8919C32.2,80.8919 32.0999,80.8919 32.0999,80.7918H32C32,80.7918 31.9,80.7918 31.9,80.6917C31.7999,80.6917 31.8,80.6917 31.7,80.5916C29.6,79.5904 25.5999,77.5882 21.4,75.0853C15.2,71.4812 11.9,68.9784 10.2,67.6769C8.7,66.9761 8.4,66.1752 6.9999,66.1752H3.9C2.6,66.1752 2.6999,67.2764 2.9,67.6769C4.2,69.5791 5.5999,71.0808 7.2,72.2821C7.4,72.4824 12.5,76.1866 18.9,79.9909C19.1999,80.1911 19.6,80.3913 19.9,80.5916C25.7999,83.9954 30.9,86.2981 31.2,86.4983C33.2,87.3993 35.9,88 38.7,88H40.4C40.8,88 41.1999,88 41.5999,87.8999C43.6999,87.6997 45.7,87.1991 47.2999,86.4983H47.4C48.1,86.198 53.6,83.6951 59.7,80.091C63.1,78.0887 66.2,76.0865 68.3,74.5848C70.1,73.2833 71.3,72.4824 71.4,72.3823C72.4,71.6815 73.4,70.6803 74.3,69.5791C76.6,66.7759 78.5,63.0717 79.2,59.7679V59.6678C79.2999,59.3675 79.3,59.0671 79.3,58.8669V58.7668C79.3,58.5666 79.3,58.4664 79.4,58.2662C79.4,58.1661 79.5,57.165 79.6,55.5631V54.8623Z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="-0.32032"
android:startX="41.2774"
android:endY="87.8803"
android:endX="41.2774"
android:type="linear">
<item android:offset="0" android:color="#FF666666"/>
<item android:offset="0.4" android:color="#FF777777"/>
<item android:offset="0.66" android:color="#FF818181"/>
<item android:offset="1" android:color="#FF919191"/>
</gradient>
</aapt:attr>
</path>
</vector>
</aapt:attr>
<target
android:name="curve" >
<!-- There should be an animated gradient -->
</target>
</animated-vector>
The solution does not have to be in an XML file, it may be in code.

How to add Animated Vector Drawable Animation?

I am trying to animate a vector path to a different path in my android app for testing but its not working properly . no animation is displayed on screen and neither any animation is shown.
My vector file is:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="8dp"
android:height="5dp"
android:viewportWidth="8"
android:viewportHeight="5">
<path
android:name="redot"
android:pathData="M2.5,2.5L6,2.5"
android:strokeWidth="4"
android:fillColor="#00000000"
android:strokeColor="#E61B1B"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
</vector>
And my VectorAnimation file is:
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:targetApi="lollipop"
android:drawable="#drawable/ic_reddot">
<target
android:animation="#anim/redanim"
android:name="redot"/>
</animated-vector>
My Animation file in anim folder is:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="10000"
android:propertyName="pathData"
android:valueFrom="M2.5,2.5L6,2.5"
android:valueTo="M2.5,2.5L31,2.5"
android:valueType="pathType" />
</set>
And finally my MainActivityCode is as following:
public class MainActivity extends AppCompatActivity {
private TextView testObj;
private ImageView reddot;
private AnimatedVectorDrawable animation;
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// testObj = (TextView) findViewById(R.id.testObj);
// testObj.setVisibility(View.INVISIBLE);
reddot = (ImageView) findViewById(R.id.reddot);
Drawable d = reddot.getBackground();
if (d instanceof AnimatedVectorDrawable) {
Log.d("testanim", "onCreate: instancefound" );
animation = (AnimatedVectorDrawable) d;
animation.start();
}
}
}
Use Shape Shifter tool and than export the animated vector drawable file generated by shape shifter . add this file in your drawable folder and than add this as background to your imageview which you want to animate
my avd_anim.xml file:
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="80dp"
android:height="12dp"
android:viewportWidth="80"
android:viewportHeight="12">
<path
android:name="path"
android:pathData="M 6 6 L 74 6"
android:strokeColor="#e61b1b"
android:strokeWidth="12"
android:strokeLineCap="round"
android:fillType="evenOdd"/>
</vector>
</aapt:attr>
<target android:name="path">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="pathData"
android:duration="1000"
android:valueFrom="M 6 6 L 74 6"
android:valueTo="M 6 6 L 1 6"
android:valueType="pathType"
android:interpolator="#android:anim/linear_interpolator"/>
</aapt:attr>
</target>
My activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="#+id/object"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:src="#drawable/avd_anim"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
and finally my MainActivity.class
public class MainActivity extends AppCompatActivity {
private ImageView image;
private AnimatedVectorDrawable animation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image = (ImageView) findViewById(R.id.object);
}
#Override
protected void onStart() {
super.onStart();
Drawable d = image.getDrawable();
if (d instanceof AnimatedVectorDrawable) {
Log.d("testanim", "onCreate: instancefound" + d.toString());
animation = (AnimatedVectorDrawable) d;
animation.start();
}
}
}
You should use redot.getDrawable() instead of getBackground()
And if you are using app:srcCompat="#drawable/..." instead of android:src=#drawable/... for ImageView you should add
if (d instanceof AnimatedVectorDrawableCompat) {
AnimatedVectorDrawableCompat avd = (AnimatedVectorDrawableCompat) d;
avd.start();
}
And android:animation="#anim/redanim" should be android:animation="#animator/redanim". Use animator folder

Imported SVG from Inkscape isn't rendering

A SVG imported from Inkscape doesn't render in Android Studio. I'm not sure how to begin to trouble shoot this. Is there any in the xml code that gives a hint as to why?
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="10dp"
android:viewportWidth="188.56328"
android:viewportHeight="80.877213">
<path
android:strokeColor="#2cb71a"
android:strokeWidth="2.05815887"
android:strokeLineJoin="round"
android:pathData="M-185.37,134.151 L-0.63217,134.151 L-0.63217,213.584 L-185.37,213.584 L-185.37,134.151 Z" />
<path
android:fillColor="#2cb71a"
android:strokeWidth="2.41540718"
android:strokeLineJoin="round"
android:pathData="M-34.9949,145.281 C-32.1268,145.281,-29.8018,147.606,-29.8018,150.475 C-29.8018,153.343,-32.1268,155.668,-34.9949,155.668 C-37.863,155.668,-40.188,153.343,-40.188,150.475 C-40.188,147.606,-37.863,145.281,-34.9949,145.281 Z" />
<path
android:fillColor="#2cb71a"
android:strokeWidth="2.42433667"
android:strokeLineJoin="round"
android:pathData="M-35.1156,156.996 L-34.8741,156.996 Q-26.7825,156.996,-26.7825,165.088 L-26.7825,177.889 Q-26.7825,185.981,-34.8741,185.981 L-35.1156,185.981 Q-43.2073,185.981,-43.2073,177.889 L-43.2073,165.088 Q-43.2073,156.996,-35.1156,156.996 Z" />
<path
android:fillColor="#2cb71a"
android:strokeWidth="2.41540718"
android:strokeLineJoin="round"
android:pathData="M-104.59,121.139 L-104.59,121.139 Q-102.235,121.139,-102.235,123.494 L-102.235,133.155 Q-102.235,135.51,-104.59,135.51 L-104.59,135.51 Q-106.945,135.51,-106.945,133.155 L-106.945,123.494 Q-106.945,121.139,-104.59,121.139 Z" />
<path
android:fillColor="#2cb71a"
android:strokeWidth="2.41540718"
android:strokeLineJoin="round"
android:pathData="M128.593,104.735 L128.593,104.735 Q130.948,104.735,130.948,107.09 L130.948,116.752 Q130.948,119.107,128.593,119.107 L128.593,119.107 Q126.238,119.107,126.238,116.752 L126.238,107.09 Q126.238,104.735,128.593,104.735 Z" />
<path
android:fillColor="#2cb71a"
android:strokeWidth="2.41540718"
android:strokeLineJoin="round"
android:pathData="M-169.218,-6.47664 L-169.218,-6.47664 Q-166.863,-6.47664,-166.863,-4.12162 L-166.863,5.54001 Q-166.863,7.89503,-169.218,7.89503 L-169.218,7.89503 Q-171.573,7.89503,-171.573,5.54001 L-171.573,-4.12162 Q-171.573,-6.47664,-169.218,-6.47664 Z" />
<path
android:fillColor="#2cb71a"
android:fillAlpha="0.48387098"
android:strokeAlpha="0.48387098"
android:strokeWidth="2.41540718"
android:strokeLineJoin="round"
android:pathData="M-173.866,-7.92172 L-173.866,-7.92172 Q-171.511,-7.92172,-171.511,-5.5667 L-171.511,4.09493 Q-171.511,6.44995,-173.866,6.44995 L-173.866,6.44995 Q-176.221,6.44995,-176.221,4.09493 L-176.221,-5.5667 Q-176.221,-7.92172,-173.866,-7.92172 Z" />
<path
android:fillColor="#2cb71a"
android:fillAlpha="0.98999999"
android:strokeAlpha="0.98999999"
android:strokeWidth="2.41540718"
android:strokeLineJoin="round"
android:pathData="M-107.292,124.489 L-107.292,124.489 Q-104.937,124.489,-104.937,126.844 L-104.937,136.505 Q-104.937,138.86,-107.292,138.86 L-107.292,138.86 Q-109.647,138.86,-109.647,136.505 L-109.647,126.844 Q-109.647,124.489,-107.292,124.489 Z" />
<path
android:fillColor="#2cb71a"
android:strokeWidth="2.52457666"
android:strokeLineJoin="round"
android:pathData="M-70.6076,172.683 L-71.0429,172.683 Q-68.4702,172.683,-68.4702,175.256 L-68.4702,185.811 Q-68.4702,188.383,-71.0429,188.383 L-70.6076,188.383 Q-73.1803,188.383,-73.1803,185.811 L-73.1803,175.256 Q-73.1803,172.683,-70.6076,172.683 Z" />
<path
android:fillColor="#2cb71a"
android:strokeWidth="2.52457666"
android:strokeLineJoin="round"
android:pathData="M19.419,-211.623 L18.9836,-211.623 Q21.5563,-211.623,21.5563,-209.051 L21.5563,-198.496 Q21.5563,-195.923,18.9836,-195.923 L19.419,-195.923 Q16.8462,-195.923,16.8462,-198.496 L16.8462,-209.051 Q16.8462,-211.623,19.419,-211.623 Z" />
<path
android:fillColor="#2cb71a"
android:strokeWidth="2.52457666"
android:strokeLineJoin="round"
android:pathData="M-83.4017,169.639 L-83.8371,169.639 Q-81.2644,169.639,-81.2644,172.212 L-81.2644,182.766 Q-81.2644,185.339,-83.8371,185.339 L-83.4017,185.339 Q-85.9744,185.339,-85.9744,182.766 L-85.9744,172.212 Q-85.9744,169.639,-83.4017,169.639 Z" />
<path
android:fillColor="#2cb71a"
android:strokeWidth="2.52457666"
android:strokeLineJoin="round"
android:pathData="M-133.339,-163.758 L-133.774,-163.758 Q-131.202,-163.758,-131.202,-161.186 L-131.202,-150.631 Q-131.202,-148.058,-133.774,-148.058 L-133.339,-148.058 Q-135.912,-148.058,-135.912,-150.631 L-135.912,-161.186 Q-135.912,-163.758,-133.339,-163.758 Z" />
<path
android:fillType="evenOdd"
android:strokeColor="#000000"
android:strokeWidth="0.12077035"
android:pathData="M-71.2256,158.659 C-68.039,153.392,-64.1607,154.191,-64.0522,154.218" />
<path
android:fillType="evenOdd"
android:strokeColor="#000000"
android:strokeWidth="0.12077035"
android:pathData="M-68.8345,158.232 C-67.756,156.715,-66.4003,155.521,-63.9668,155.585" />
<path
android:fillColor="#2cb71a"
android:strokeWidth="2.42433643"
android:strokeLineJoin="round"
android:pathData="M-179.123,159.942 C-181.165,159.946,-183.173,160.725,-184.698,162.189 L-184.578,162.189 C-184.411,162.189,-184.276,162.324,-184.276,162.491 L-184.276,186.524 C-184.276,186.598,-184.304,186.665,-184.347,186.717 C-182.371,186.293,-180.55,185.131,-179.329,183.313 L-172.19,172.687 C-169.69,168.966,-170.673,163.958,-174.394,161.458 L-174.595,161.323 C-175.99,160.386,-177.567,159.938,-179.124,159.941 Z M-187.12,186.827 C-186.402,186.924,-185.678,186.922,-184.968,186.827 Z" />
<path
android:fillColor="#2cb71a"
android:strokeWidth="2.41540718"
android:strokeLineJoin="round"
android:pathData="M-168.567,153.011 C-165.699,153.011,-163.374,155.336,-163.374,158.204 C-163.374,161.072,-165.699,163.397,-168.567,163.397 C-171.435,163.397,-173.76,161.072,-173.76,158.204 C-173.76,155.336,-171.435,153.011,-168.567,153.011 Z" />
<path
android:fillColor="#ff0000"
android:strokeColor="#ffcc00"
android:strokeWidth="0.26458332"
android:pathData="M-228.855,129 L-227.806,129 L-227.806,130.313 L-228.855,130.313 Z M-228.855,122.597 L-227.806,122.597 L-227.806,125.982 L-227.909,127.827 L-228.746,127.827 L-228.855,125.982 Z" />
<path
android:fillColor="#ff0000"
android:strokeColor="#ffcc00"
android:strokeWidth="0.26458332"
android:pathData="M-228.855,129 L-227.806,129 L-227.806,130.313 L-228.855,130.313 Z M-228.855,122.597 L-227.806,122.597 L-227.806,125.982 L-227.909,127.827 L-228.746,127.827 L-228.855,125.982 Z" />
<path
android:fillColor="#ff0000"
android:strokeColor="#ffcc00"
android:strokeWidth="0.26458332"
android:pathData="M-228.855,129 L-227.806,129 L-227.806,130.313 L-228.855,130.313 Z M-228.855,122.597 L-227.806,122.597 L-227.806,125.982 L-227.909,127.827 L-228.746,127.827 L-228.855,125.982 Z" />
</vector>
Are there any tips one would be willing to give to help with trouble shooting? Is there anything I could do in inkcape to ensure the file renders in Android Studio?
Looks like it is not well formed, there are lots of negative coords.
Check it out without negative coordinates and bigger dimens:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="240dp"
android:height="100dp"
android:viewportWidth="400"
android:viewportHeight="200">
<path
android:pathData="M185.37,134.151 L0.63217,134.151 L0.63217,213.584 L185.37,213.584 L185.37,134.151 Z"
android:strokeWidth="2.05815887"
android:strokeColor="#2cb71a"
android:strokeLineJoin="round" />
<path
android:fillColor="#2cb71a"
android:pathData="M34.9949,145.281 C32.1268,145.281,29.8018,147.606,29.8018,150.475 C29.8018,153.343,32.1268,155.668,34.9949,155.668 C37.863,155.668,40.188,153.343,40.188,150.475 C40.188,147.606,37.863,145.281,34.9949,145.281 Z"
android:strokeWidth="2.41540718"
android:strokeLineJoin="round" />
<path
android:fillColor="#2cb71a"
android:pathData="M35.1156,156.996 L34.8741,156.996 Q26.7825,156.996,26.7825,165.088 L26.7825,177.889 Q26.7825,185.981,34.8741,185.981 L 35.1156,185.981 Q 43.2073,185.981, 43.2073,177.889 L 43.2073,165.088 Q43.2073,156.996,35.1156,156.996 Z"
android:strokeWidth="2.42433667"
android:strokeLineJoin="round" />
<path
android:fillColor="#2cb71a"
android:pathData="M104.59,121.139 L104.59,121.139 Q102.235,121.139,102.235,123.494 L102.235,133.155 Q102.235,135.51,104.59,135.51 L104.59,135.51 Q 106.945,135.51,106.945,133.155 L106.945,123.494 Q106.945,121.139,104.59,121.139 Z"
android:strokeWidth="2.41540718"
android:strokeLineJoin="round" />
<path
android:fillColor="#2cb71a"
android:pathData="M128.593,104.735 L128.593,104.735 Q130.948,104.735,130.948,107.09 L130.948,116.752 Q130.948,119.107,128.593,119.107 L128.593,119.107 Q126.238,119.107,126.238,116.752 L126.238,107.09 Q126.238,104.735,128.593,104.735 Z"
android:strokeWidth="2.41540718"
android:strokeLineJoin="round" />
<path
android:fillColor="#2cb71a"
android:pathData="M169.218,6.47664 L169.218,6.47664 Q166.863,6.47664,166.863,4.12162 L166.863,5.54001 Q166.863,7.89503,169.218,7.89503 L169.218,7.89503 Q171.573,7.89503,171.573,5.54001 L171.573,4.12162 Q171.573,6.47664,169.218,6.47664 Z"
android:strokeWidth="2.41540718"
android:strokeLineJoin="round" />
<path
android:fillAlpha="0.48387098"
android:fillColor="#2cb71a"
android:pathData="M173.866, 7.92172 L 173.866, 7.92172 Q 171.511, 7.92172, 171.511, 5.5667 L 171.511,4.09493 Q 171.511,6.44995, 173.866,6.44995 L 173.866,6.44995 Q 176.221,6.44995, 176.221,4.09493 L 176.221, 5.5667 Q 176.221, 7.92172, 173.866, 7.92172 Z"
android:strokeWidth="2.41540718"
android:strokeAlpha="0.48387098"
android:strokeLineJoin="round" />
<path
android:fillAlpha="0.98999999"
android:fillColor="#2cb71a"
android:pathData="M107.292,124.489 L 107.292,124.489 Q 104.937,124.489, 104.937,126.844 L 104.937,136.505 Q 104.937,138.86, 107.292,138.86 L 107.292,138.86 Q 109.647,138.86, 109.647,136.505 L 109.647,126.844 Q 109.647,124.489, 107.292,124.489 Z"
android:strokeWidth="2.41540718"
android:strokeAlpha="0.98999999"
android:strokeLineJoin="round" />
<path
android:fillColor="#2cb71a"
android:pathData="M70.6076,172.683 L 71.0429,172.683 Q 68.4702,172.683, 68.4702,175.256 L 68.4702,185.811 Q 68.4702,188.383, 71.0429,188.383 L 70.6076,188.383 Q 73.1803,188.383, 73.1803,185.811 L 73.1803,175.256 Q 73.1803,172.683, 70.6076,172.683 Z"
android:strokeWidth="2.52457666"
android:strokeLineJoin="round" />
<path
android:fillColor="#2cb71a"
android:pathData="M19.419, 211.623 L18.9836, 211.623 Q21.5563, 211.623,21.5563, 209.051 L21.5563, 198.496 Q21.5563, 195.923,18.9836, 195.923 L19.419, 195.923 Q16.8462, 195.923,16.8462, 198.496 L16.8462, 209.051 Q16.8462, 211.623,19.419, 211.623 Z"
android:strokeWidth="2.52457666"
android:strokeLineJoin="round" />
<path
android:fillColor="#2cb71a"
android:pathData="M83.4017,169.639 L 83.8371,169.639 Q 81.2644,169.639, 81.2644,172.212 L 81.2644,182.766 Q 81.2644,185.339, 83.8371,185.339 L 83.4017,185.339 Q 85.9744,185.339, 85.9744,182.766 L 85.9744,172.212 Q 85.9744,169.639, 83.4017,169.639 Z"
android:strokeWidth="2.52457666"
android:strokeLineJoin="round" />
<path
android:fillColor="#2cb71a"
android:pathData="M133.339, 163.758 L 133.774, 163.758 Q 131.202, 163.758, 131.202, 161.186 L 131.202, 150.631 Q 131.202, 148.058, 133.774, 148.058 L 133.339, 148.058 Q 135.912, 148.058, 135.912, 150.631 L 135.912, 161.186 Q 135.912, 163.758, 133.339, 163.758 Z"
android:strokeWidth="2.52457666"
android:strokeLineJoin="round" />
<path
android:fillType="evenOdd"
android:pathData="M71.2256,158.659 C 68.039,153.392, 64.1607,154.191, 64.0522,154.218"
android:strokeWidth="0.12077035"
android:strokeColor="#000000" />
<path
android:fillType="evenOdd"
android:pathData="M68.8345,158.232 C 67.756,156.715, 66.4003,155.521, 63.9668,155.585"
android:strokeWidth="0.12077035"
android:strokeColor="#000000" />
<path
android:fillColor="#2cb71a"
android:pathData="M179.123,159.942 C 181.165,159.946, 183.173,160.725, 184.698,162.189 L 184.578,162.189 C 184.411,162.189, 184.276,162.324, 184.276,162.491 L 184.276,186.524 C 184.276,186.598, 184.304,186.665, 184.347,186.717 C 182.371,186.293, 180.55,185.131, 179.329,183.313 L 172.19,172.687 C 169.69,168.966, 170.673,163.958, 174.394,161.458 L 174.595,161.323 C 175.99,160.386, 177.567,159.938, 179.124,159.941 Z M 187.12,186.827 C 186.402,186.924, 185.678,186.922, 184.968,186.827 Z"
android:strokeWidth="2.42433643"
android:strokeLineJoin="round" />
<path
android:fillColor="#2cb71a"
android:pathData="M168.567,153.011 C 165.699,153.011, 163.374,155.336, 163.374,158.204 C 163.374,161.072, 165.699,163.397, 168.567,163.397 C 171.435,163.397, 173.76,161.072, 173.76,158.204 C 173.76,155.336, 171.435,153.011, 168.567,153.011 Z"
android:strokeWidth="2.41540718"
android:strokeLineJoin="round" />
<path
android:fillColor="#ff0000"
android:pathData="M228.855,129 L 227.806,129 L 227.806,130.313 L 228.855,130.313 Z M 228.855,122.597 L 227.806,122.597 L 227.806,125.982 L 227.909,127.827 L 228.746,127.827 L 228.855,125.982 Z"
android:strokeWidth="0.26458332"
android:strokeColor="#ffcc00" />
<path
android:fillColor="#ff0000"
android:pathData="M228.855,129 L227.806,129 L 227.806,130.313 L 228.855,130.313 Z M 228.855,122.597 L 227.806,122.597 L 227.806,125.982 L 227.909,127.827 L 228.746,127.827 L 228.855,125.982 Z"
android:strokeWidth="0.26458332"
android:strokeColor="#ffcc00" />
<path
android:fillColor="#ff0000"
android:pathData="M228.855,129 L227.806,129 L227.806,130.313 L228.855,130.313 Z M228.855,122.597 L227.806,122.597 L227.806,125.982 L227.909,127.827 L228.746,127.827 L228.855,125.982 Z"
android:strokeWidth="0.26458332"
android:strokeColor="#ffcc00" />
</vector>
This is what I can see now:
img

Android FloatingActionButton Speed Dial

I am currently working on an Android app in which I use a FloatingActionButton. I would like to use the speed dial to have multiple actions that spin/jump out of the action button as described in this page by Google on Android design, or as could be seen in an earlier version of the Keep app (sorry, but I can only post one link). I am using the Android Design Support library specifically version 23.1.1 (com.android.support:design:23.1.1). I already searched using Google and looked at the reference for the FloatingActionButton but couldn't find anything concerning the speed dial.
I would like to know if there is a way to easily achieve this using the default FloatingActionButton, or if I have to program all transitions/animations manually?
Additionally I would like to have little labels next to the buttons, describing the action, if possible.
Thank you in advance!
I'm here to add my 2 cents because this is where I landed after Googling for that exact title.
I hope it doesn't come too late to help someone like me.
First off, the solution comes from here, so is not mine. I just tried and it works nicely. So i thought i share with you in a single post rather have you go dig the code up from there.
The solution uses com.android.support:design:25.3.1 library so be sure to add that to build.gradle and it requires API 21 onwards.
The bad news is that it is composed from several small moving parts: 5 animators, 5 drawables plus the icons and layouts and of course, the code, the good news is that it works as it should, is highly customizable and doesn't require any coding outside MainActivity.
Some notes:
The big fab's image morphs between more and minus signs and rotates when tapped.
Buttons can have text, provided you put both the text and each small fab inside a LineaLayout and move the button id to the LinearLayout so it gets animated instead of the fab, but it requires code to hide and show the text when necessary.
This is the result:
So, the ingredients:
Drawables (res/drawable/).
animated_minus.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
android:height="24dp">
<group android:name="plus_group" android:pivotX="12" android:pivotY="12">
<path
android:name="plus_path"
android:strokeColor="#android:color/white"
android:strokeWidth="3"
android:pathData="M12,0L12,24M0,12,L24,12" />
</group>
</vector>
animated_plus.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="#drawable/plus">
<target
android:animation="#animator/rotate_clockwise"
android:name="plus_group" />
<target
android:animation="#animator/plus_to_minus"
android:name="plus_path" />
</animated-vector>
fab_background.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:colorControlHighlight">
<item>
<shape android:shape="oval">
<solid android:color="?android:colorAccent" />
</shape>
</item>
</ripple>
minus.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
android:height="24dp">
<group android:name="plus_group" android:pivotX="12" android:pivotY="12">
<path
android:name="plus_path"
android:strokeColor="#android:color/white"
android:strokeWidth="3"
android:pathData="M12,12L12,12M0,12,L24,12" />
</group>
</vector>
plus.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
android:height="24dp">
<group android:name="plus_group" android:pivotX="12" android:pivotY="12">
<path
android:name="plus_path"
android:strokeColor="#android:color/white"
android:strokeWidth="3"
android:pathData="M12,0L12,24M0,12,L24,12" />
</group>
</vector>
Animators (res/animator/).
fab_state_list_animator.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:state_enabled="true">
<set>
<objectAnimator
android:propertyName="translationZ"
android:duration="100"
android:valueTo="3dp"
android:valueType="floatType" />
<objectAnimator
android:propertyName="elevation"
android:duration="0"
android:valueTo="5dp"
android:valueType="floatType" />
</set>
</item>
<!-- base state -->
<item android:state_enabled="true">
<set>
<objectAnimator
android:propertyName="translationZ"
android:duration="100"
android:valueTo="0"
android:startDelay="100"
android:valueType="floatType" />
<objectAnimator
android:propertyName="elevation"
android:duration="0"
android:valueTo="5dp"
android:valueType="floatType" />
</set>
</item>
<item>
<set>
<objectAnimator
android:propertyName="translationZ"
android:duration="0"
android:valueTo="0"
android:valueType="floatType" />
<objectAnimator
android:propertyName="elevation"
android:duration="0"
android:valueTo="0"
android:valueType="floatType" />
</set>
</item>
</selector>
minus_to_plus.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="pathData"
android:valueFrom="M12,0L12,24M12,12,L12,12"
android:valueTo="M12,0L12,24M0,12,L24,12"
android:valueType="pathType"
android:duration="#android:integer/config_mediumAnimTime" />
plus_to_minus.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="pathData"
android:valueFrom="M12,0L12,24M0,12,L24,12"
android:valueTo="M12,0L12,24M12,12,L12,12"
android:valueType="pathType"
android:duration="#android:integer/config_mediumAnimTime" />
rotate_anticlockwise.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="rotation"
android:valueFrom="90"
android:valueTo="0"
android:valueType="floatType"
android:duration="#android:integer/config_mediumAnimTime" />
rotate_clockwise.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="90"
android:valueType="floatType"
android:duration="#android:integer/config_mediumAnimTime" />
Layouts. (res/layout/)
fab.xml. All fabs are declared here. Replace android:src with your own icon on the first 3 ImageButtons.
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:id="#+id/fab_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/activity_vertical_margin"
android:layout_marginEnd="#dimen/activity_horizontal_margin"
android:clipChildren="false" >
<!-- Please note that the #id are defined the first time they're referenced from top to bottom -->
<ImageButton
android:id="#+id/fab_action_3"
style="#style/FloatingActionButton.Mini"
android:src="#drawable/ic_volume_up_white_24dp"
android:layout_above="#+id/fab_action_2"
android:layout_alignEnd="#+id/fab"
android:contentDescription="#null"
android:backgroundTint="#color/sa_gray"
android:width="24dp"
android:height="24dp"
android:onClick="fabAction3" />
<ImageButton
android:id="#id/fab_action_2"
style="#style/FloatingActionButton.Mini"
android:src="#drawable/ic_credit_card_white_24dp"
android:layout_above="#+id/fab_action_1"
android:layout_alignEnd="#id/fab"
android:contentDescription="#null"
android:backgroundTint="#color/sa_gray"
android:width="24dp"
android:height="24dp"
android:onClick="fabAction2" />
<ImageButton
android:id="#id/fab_action_1"
style="#style/FloatingActionButton.Mini"
android:src="#drawable/ic_add_shopping_cart_white_24dp"
android:layout_above="#id/fab"
android:layout_alignEnd="#id/fab"
android:contentDescription="#null"
android:backgroundTint="#color/sa_gray"
android:width="24dp"
android:height="24dp"
android:onClick="fabAction1" />
<ImageButton
android:id="#id/fab"
style="#style/FloatingActionButton"
android:src="#mipmap/ic_add_w"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:contentDescription="#null"
android:visibility="visible"
android:layout_marginTop="8dp" />
</RelativeLayout>
</merge>
And lastly.
The code (java//MainActivity.java)
a) Some declarations:
private static final String TAG = "Floating Action Button";
private static final String TRANSLATION_Y = "translationY";
private ImageButton fab;
private boolean expanded = false;
private View fabAction1;
private View fabAction2;
private View fabAction3;
private float offset1;
private float offset2;
private float offset3;
b) Delete the usual fab code on MainActivity's onCreate:
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
and replace it with:
final ViewGroup fabContainer = (ViewGroup) findViewById(R.id.fab_container);
fab = (ImageButton) findViewById(R.id.fab);
fabAction1 = findViewById(R.id.fab_action_1);
// insert onClickListener here
fabAction2 = findViewById(R.id.fab_action_2);
// insert onClickListener here
fabAction3 = findViewById(R.id.fab_action_3);
// insert onClickListener here
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
expanded = !expanded;
if (expanded) {
expandFab();
} else {
collapseFab();
}
}
});
fabContainer.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
fabContainer.getViewTreeObserver().removeOnPreDrawListener(this);
offset1 = fab.getY() - fabAction1.getY();
fabAction1.setTranslationY(offset1);
offset2 = fab.getY() - fabAction2.getY();
fabAction2.setTranslationY(offset2);
offset3 = fab.getY() - fabAction3.getY();
fabAction3.setTranslationY(offset3);
return true;
}
});
c) Add supporting functions on MainActivity (animation code mostly and the 3 small fab's onClick methods):
private void collapseFab() {
fab.setImageResource(R.drawable.animated_minus);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(createCollapseAnimator(fabAction1, offset1),
createCollapseAnimator(fabAction2, offset2),
createCollapseAnimator(fabAction3, offset3));
animatorSet.start();
animateFab();
}
private void expandFab() {
fab.setImageResource(R.drawable.animated_plus);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(createExpandAnimator(fabAction1, offset1),
createExpandAnimator(fabAction2, offset2),
createExpandAnimator(fabAction3, offset3));
animatorSet.start();
animateFab();
}
private Animator createCollapseAnimator(View view, float offset) {
return ObjectAnimator.ofFloat(view, TRANSLATION_Y, 0, offset)
.setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));
}
private Animator createExpandAnimator(View view, float offset) {
return ObjectAnimator.ofFloat(view, TRANSLATION_Y, offset, 0)
.setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));
}
private void animateFab() {
Drawable drawable = fab.getDrawable();
if (drawable instanceof Animatable) {
((Animatable) drawable).start();
}
}
public void fabAction1(View view) {
Log.d(TAG, "Action 1");
Toast.makeText(this, "Go shopping!", Toast.LENGTH_SHORT).show();
}
public void fabAction2(View view) {
Log.d(TAG, "Action 2");
Toast.makeText(this, "Gimme money!", Toast.LENGTH_SHORT).show();
}
public void fabAction3(View view) {
Log.d(TAG, "Action 3");
Toast.makeText(this, "Turn it up!", Toast.LENGTH_SHORT).show();
}
d) Reference the fab.xml layout from res/layout/activity_main.xml
Delete the fab declaration:
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#android:drawable/ic_dialog_email" />
Replace with:
<include layout="#layout/fab" />
Last notes:
Feel free to scrap the onClick code for the fabs and replace it with
onClickListener. Those should go right where the comment that says
// insert onClickListener here. Just remember to delete the
onClick attribute for each fab in fab.xml file and get rid of
the last 3 functions in MainActivity (fabAction1, fabAction2
and fabAction3).
Most measures, dimensions, etc. I put them right in the code to avoid including even more files.
The code is not optimized on changed in any way.
I hope this helps someone and sorry for the wall of text.
I would like to know if there is a way to easily achieve this using the default FloatingActionButton
FAB from Design Library does not have this feature. You need to look for 3rd party FABs (there's a few on android-arsenal to choose from)
This library is implementing the Speed Dial from the Material Design guidelines:
https://github.com/leinardi/FloatingActionButtonSpeedDial

Categories

Resources