Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/215.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 创建具有特定滚动动画效果的自定义圆形进度条_Android_Progress Bar_Android Animation_Customization_Shape - Fatal编程技术网

Android 创建具有特定滚动动画效果的自定义圆形进度条

Android 创建具有特定滚动动画效果的自定义圆形进度条,android,progress-bar,android-animation,customization,shape,Android,Progress Bar,Android Animation,Customization,Shape,我正在尝试创建一个带有特定滚动动画效果的自定义进度条,该效果或多或少与android应用程序中的mi-fit类似,请参见下面的屏幕截图: 如果你仔细看gif,你会注意到两件事- 绕着进度条外环旋转的发光运动 向下或向上滚动(折叠效果)时,效果为 美丽的 我正在努力实现这两个效果,任何帮助都将不胜感激:) 编辑:我使进度条正常工作-请参见下面更新代码的屏幕截图: 下面我将创建三个层,一个用于外圆,另一个用于虚线圆,另一个用于用实心圆填充虚线。 然后在三个进度条中使用这三个形状,请参见下面的代码

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

  • 绕着进度条外环旋转的发光运动

  • 向下或向上滚动(折叠效果)时,效果为 美丽的

  • 我正在努力实现这两个效果,任何帮助都将不胜感激:)

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

    下面我将创建三个层,一个用于外圆,另一个用于虚线圆,另一个用于用实心圆填充虚线。 然后在三个进度条中使用这三个形状,请参见下面的代码:
    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" />
    
    <?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>
    
    <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>
    
    circular\u layer\u dash\u 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>
    


    p、 很抱歉这篇文章太长。

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

    <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>
    
    然后在
    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
    progressbar
    的父级:

    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)));
        }
    }
    
    还要检查和了解更多信息

    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)));
        }
    }
    
    public class Rotate3dAnimation extends Animation {
    private final float mFromDegrees;
    private final float mToDegrees;
    private final float mCenterX;
    private final float mCenterY;
    private final float mDepthZ;
    private final boolean mReverse;
    private Camera mCamera;
    
    /**
     * Creates a new 3D rotation on the Y axis. The rotation is defined by its
     * start angle and its end angle. Both angles are in degrees. The rotation
     * is performed around a center point on the 2D space, definied by a pair
     * of X and Y coordinates, called centerX and centerY. When the animation
     * starts, a translation on the Z axis (depth) is performed. The length
     * of the translation can be specified, as well as whether the translation
     * should be reversed in time.
     *
     * @param fromDegrees the start angle of the 3D rotation
     * @param toDegrees   the end angle of the 3D rotation
     * @param centerX     the X center of the 3D rotation
     * @param centerY     the Y center of the 3D rotation
     * @param reverse     true if the translation should be reversed, false otherwise
     */
    public Rotate3dAnimation(float fromDegrees, float toDegrees,
                             float centerX, float centerY, float depthZ, boolean reverse) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;
        mCenterX = centerX;
        mCenterY = centerY;
        mDepthZ = depthZ;
        mReverse = reverse;
    }
    
    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        mCamera = new Camera();
    }
    
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        final float fromDegrees = mFromDegrees;
        float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
    
        final float centerX = mCenterX;
        final float centerY = mCenterY;
        final Camera camera = mCamera;
    
        final Matrix matrix = t.getMatrix();
    
        camera.save();
        if (mReverse) {
            camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
        } else {
            camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
        }
        //camera.rotateY(degrees);
        camera.rotateX(degrees);
        camera.getMatrix(matrix);
        camera.restore();
    
        matrix.preTranslate(-centerX, -centerY);
        matrix.postTranslate(centerX, centerY);
    }
    }