创建具有特定滚动动画效果的自定义循环进度条

时间:2018-02-07 07:43:17

标签: android progress-bar android-animation customization shape

我正在尝试使用特定的滚动动画效果创建自定义进度条,该效果看起来或多或少与 mi fit Android应用中的效果类似,请参见下面的屏幕截图: 如果你仔细看到gif,你会注意到两件事 -

  
      
  1. 围绕进度条外环旋转的发光运动

  2.   
  3. 向下或向上滚动(折叠效果)时,效果如下   美丽

  4.   

mi progress enter image description here

我想在这里实现这两种效果,感谢任何帮助:)

编辑:我使进度条工作 - 请参阅下面的更新代码的屏幕截图:

worked on screen shot

我所关注的是创建三个图层,一个用于外圈,另一个用于短划圆圈,另一个用于填充虚线圆圈。 然后在三个进度条中使用这三个形状,请参阅下面的代码: layout.xml

<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
android:gravity="center">

<ProgressBar
                    android:id="@+id/progressBar1"
                    style="?android:attr/progressBarStyleHorizontal"
                    android:layout_width="250dp"
                    android:layout_height="250dp"
                    android:layout_centerInParent="true"
                    android:max="100"
                    android:progress="100"
                    android:progressDrawable="@drawable/circular_layer_outer" />

                <ProgressBar
                    android:id="@+id/progressBar2"
                    style="?android:attr/progressBarStyleHorizontal"
                    android:layout_width="230dp"
                    android:layout_height="230dp"
                    android:layout_centerInParent="true"
                    android:max="100"
                    android:progress="100"
                    android:progressDrawable="@drawable/circular_layer_dash_inner" />

                <ProgressBar
                    android:id="@+id/main_progressBar"
                    style="?android:attr/progressBarStyleHorizontal"
                    android:layout_width="226dp"
                    android:layout_height="226dp"
                    android:layout_centerInParent="true"
                    android:max="100"
                    android:progress="80"
                    android:progressDrawable="@drawable/circular_layer_dash_filler"
                    android:visibility="visible" />

两种进展的形状: circular_layer_dash_inner.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:paddingBottom="13dp"
    android:paddingLeft="13dp"
    android:paddingRight="13dp"
    android:paddingTop="13dp">
    <item>
        <rotate
            android:fromDegrees="270"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toDegrees="270">
            <shape
                android:dither="true"
                android:innerRadiusRatio="3"
                android:shape="ring"
                android:thickness="0sp"
                android:useLevel="true">
                <solid android:color="@color/white" />
                <stroke
                    android:width="1dp"
                    android:color="@color/white"
                    android:dashGap="2dp"
                    android:dashWidth="1dp" />
            </shape>
        </rotate>
    </item>
</layer-list>

circular_layer_dash_filler.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:paddingBottom="13dp"
    android:paddingLeft="13dp"
    android:paddingRight="13dp"
    android:paddingTop="13dp">
    <item>
        <rotate
            android:fromDegrees="270"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toDegrees="270">
            <shape
                android:dither="true"
                android:innerRadiusRatio="3"
                android:shape="ring"
                android:thickness="2sp"
                android:useLevel="true">
                <solid android:color="@color/white" />
            </shape>
        </rotate>
    </item>
</layer-list>

circular_layer_outer.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
    <shape
        android:innerRadiusRatio="3"
        android:shape="ring"
        android:thickness="8sp"
        android:useLevel="true">
        <solid android:color="@color/white" />
    </shape>
</item>

P.S。抱歉这篇长篇文章。

1 个答案:

答案 0 :(得分:2)

我能够通过以下方式创建动画:

<android.support.design.widget.AppBarLayout
    android:id="@+id/appBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/blue"
    android:fitsSystemWindows="true">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsingToolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        app:expandedTitleGravity="center_horizontal"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <RelativeLayout
            android:id="@+id/layers_progress"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/blue_safe"
            app:layout_collapseMode="parallax">

            <ProgressBar
                android:id="@+id/progressBar1"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="250dp"
                android:layout_height="250dp"
                android:layout_centerInParent="true"
                android:max="100"
                android:progress="100"
                android:progressDrawable="@drawable/circular_layer_outer" />

            <ProgressBar
                android:id="@+id/progressBar2"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="230dp"
                android:layout_height="230dp"
                android:layout_centerInParent="true"
                android:max="100"
                android:progress="100"
                android:progressDrawable="@drawable/circular_layer_dash_inner" />

            <ProgressBar
                android:id="@+id/main_progressBar"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="226dp"
                android:layout_height="226dp"
                android:layout_centerInParent="true"
                android:max="100"
                android:progress="80"
                android:progressDrawable="@drawable/circular_layer_dash_filler"
                android:visibility="visible" />

        </RelativeLayout>

        <TextView
            android:id="@+id/score_val"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="Score"
            android:textColor="@color/white"
            android:textSize="36sp"
            android:textStyle="bold"
            android:visibility="visible"
            app:layout_collapseMode="parallax" />

    </android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>

在这里可以看到CollapsingToolbarLayout内部使用了AppBarLayout,然后使用AppBarLayout并设置OnOffsetChangedListener来监听{{1}的高度值的变化,见下面的代码:

AppBarLayout

然后在AppBarLayout appbar = findViewById(R.id.appBar); appbar.addOnOffsetChangedListener(DashboardScore.this);

onOffsetChanged

此处@Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { if (mMaxScrollSize == 0) mMaxScrollSize = appBarLayout.getTotalScrollRange(); currentScrollPercentage = (Math.abs(verticalOffset)) * 100 / mMaxScrollSize; Log.d("Debug info", "% == " + currentScrollPercentage + " -- mMaxScrollSize == " + mMaxScrollSize + " vertical offset - " + verticalOffset); showAnim(oldScrollPercentage, currentScrollPercentage); oldScrollPercentage = currentScrollPercentage; }

对于private int mMaxScrollSize; private int currentScrollPercentage, oldScrollPercentage = 0;使用,此处showAnim()parentProgress的父母:

ProgressBars

void showAnim(int fromDegree, int toDegree) { final float centerX = parentProgress.getWidth() / 2.0f; final float centerY = parentProgress.getHeight() / 2.0f; final Rotate3dAnimation rotation = new Rotate3dAnimation(fromDegree, toDegree, centerX, centerY, 5.0f, false); rotation.setDuration(400); rotation.setFillAfter(true); rotation.setInterpolator(new AccelerateInterpolator()); parentProgress.startAnimation(rotation); if (currentScrollPercentage > 0) { if (fromDegree < 90) parentProgress.setAlpha(1 - Math.abs((float) currentScrollPercentage / 100f)); else parentProgress.setAlpha(0); Log.d("Debug info", "setAlpha == " + (1 - Math.abs((float) currentScrollPercentage / 100f))); } } 使用:

Rotate3dAnimation

另请查看thisthis以获取更多理解