在每个listview项目中旋转进度条

mag*_*lar 13 android listview asynchronous cycle progress-bar

我已经很长时间以来一直在摸不着头脑,并且没有任何运气就寻找答案!这似乎是微不足道的,但据我所知,事实并非如此.

我在我的Android应用程序中使用listview,其中每个项目(视图)在加载和显示内容之前显示旋转的ProgressBar(内容通过http调用和json检索,因此可能需要一段时间才能处理).问题在于旋转进度条彼此独立地旋转,从而产生旋转混乱的效果,而不是同步的一排好看的装载标记.

我已经尝试了所有我能想出来的东西......没有在getView()中循环使用ProgressBar ...只有一个相同ProgressBar的实例...重置ProgressBars android:每当列表项可见时进度(通过onScroll ()在活动中)...等等,但由于它们在创建时间开始旋转(当在适配器中调用getView时),它们将永远不会具有相同的循环同步.

在此输入图像描述

欢迎任何建议!

Ole*_*ich 2

编辑:现在完美运行!- 插入的动画监听器在第一次重复后调用 setStartOffset() 返回到 0,这样它就不会保持随机“跳跃”。


我找到了解决此问题的有效解决方案,该解决方案通过将动画计时到当前系统毫秒来工作。这有点像黑客,因为它使用反射来mAnimation获取ProgressBar. 话虽如此,该字段自创建以来一直保留在 Android 源代码中(适用于 4.2)。

创建该类android.widget.SyncedProgressBar,并使用它而不是ProgressBar在 .xml 文件中。它本质上使动画在动画持续时间开始时开始。您还可以尝试一下setDuration(500)以验证它是否有效(进度轮会旋转得非常快)。希望这可以帮助!

package android.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;

import java.lang.reflect.Field;

/**
* @author Oleg Vaskevich
*
*/
public class SyncedProgressBar extends ProgressBar {

    public SyncedProgressBar(Context context) {
        super(context);
        modifyAnimation();
    }

    public SyncedProgressBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        modifyAnimation();
    }

    public SyncedProgressBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        modifyAnimation();
    }

    @Override
    public void setVisibility(int v) {
        super.setVisibility(v);
        modifyAnimation();
    }

    @SuppressLint("NewApi")
    @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        modifyAnimation();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        modifyAnimation();
    }

    @Override
    public synchronized void setIndeterminate(boolean indeterminate) {
        super.setIndeterminate(indeterminate);
        modifyAnimation();
    }

    public void modifyAnimation() {
        Field mAnim;
        try {
            mAnim = ProgressBar.class.getDeclaredField("mAnimation");
            mAnim.setAccessible(true);
            AlphaAnimation anim = (AlphaAnimation) mAnim.get(this);
            if (anim == null)
                return;

            // set offset to that animations start at same time
            long duration = anim.getDuration();
            long timeOffset = System.currentTimeMillis() % duration;
            anim.setDuration(duration);
            anim.setStartOffset(-timeOffset);
            anim.setAnimationListener(new AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                    animation.setStartOffset(0);
                }

                @Override
                public void onAnimationEnd(Animation animation) {
                }
            });
        } catch (Exception e) {
            Log.d("SPB", "that didn't work out...", e);
            return;
        }
        postInvalidate();
    }

}
Run Code Online (Sandbox Code Playgroud)