android toolbar - كيفية جعل تدوير الصورة على نحو سلس في الروبوت؟




example action (12)

جرب استخدام toDegrees="359" لأن 360 ° و 0 ° هما نفس الشيء.

أنا أستخدم RotateAnimation لتدوير صورة RotateAnimation دورانية مخصصة في Android. إليك ملف rotate_indefinitely.xml الذي وضعته في res/anim/ :

<?xml version="1.0" encoding="UTF-8"?>
<rotate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="infinite"
    android:duration="1200" />    

عند تطبيق هذا على ImageView بي باستخدام AndroidUtils.loadAnimation() ، فإنه يعمل بشكل رائع!

spinner.startAnimation( 
    AnimationUtils.loadAnimation(activity, R.anim.rotate_indefinitely) );

المشكلة الوحيدة هي أن دوران الصورة يبدو أنه توقف في أعلى كل دورة.

بمعنى آخر ، تدور الصورة بمقدار 360 درجة ، وتتوقف لفترة وجيزة ، ثم تدور 360 درجة مرة أخرى ، إلخ.

وأظن أن المشكلة تكمن في أن الرسم المتحرك يستخدم interpolator افتراضيًا مثل android:iterpolator="@android:anim/accelerate_interpolator" ( AccelerateInterpolator ) ، ولكن لا أعرف كيف أخبره بعدم تقريب الرسوم المتحركة.

كيف يمكنني إيقاف الاستيفاء (إذا كانت هذه هي المشكلة بالفعل) لجعل دورة الرسوم المتحركة الخاصة بي على نحو سلس؟


هذا يعمل بشكل جيد

<?xml version="1.0" encoding="UTF-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1600"
    android:fromDegrees="0"
    android:interpolator="@android:anim/linear_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="infinite"
    android:toDegrees="358" />

لعكس التدوير:

<?xml version="1.0" encoding="UTF-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1600"
    android:fromDegrees="358"
    android:interpolator="@android:anim/linear_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="infinite"
    android:toDegrees="0" />

كما ذكر hanry أعلاه وضع بطانة iterpolator على ما يرام. ولكن إذا كان التدوير داخل مجموعة يجب أن تضع android: shareInterpolator = "false" لجعله سلسًا.

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
**android:shareInterpolator="false"**
>
<rotate
    android:interpolator="@android:anim/linear_interpolator"
    android:duration="300"
    android:fillAfter="true"
    android:repeatCount="10"
    android:repeatMode="restart"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%" />
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator"
    android:duration="3000"
    android:fillAfter="true"
    android:pivotX="50%"
    android:pivotY="50%"
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:toXScale="0"
    android:toYScale="0" />
</set>

إذا كانت Sharedinterpolator غير خاطئة ، فإن الشفرة الواردة أعلاه تعطي مواطن الخلل.


ربما ، شيء من هذا القبيل سوف يساعد:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        imageView.animate().rotationBy(360).withEndAction(this).setDuration(3000).setInterpolator(new LinearInterpolator()).start();
    }
};

imageView.animate().rotationBy(360).withEndAction(runnable).setDuration(3000).setInterpolator(new LinearInterpolator()).start();

بالمناسبة ، يمكنك التدوير بأكثر من 360 مثل:

imageView.animate().rotationBy(10000)...

هل من الممكن أنه نظرًا لأنك انتقلت من 0 إلى 360 ، فأنت تقضي وقتًا أطول بقليل عند 0/360 مما تتوقع؟ ربما تم تعيينها إلى درجات إلى 359 أو 358.


حاول استخدام أكثر من 360 لتجنب إعادة التشغيل.

أستخدم 3600 مثبتًا على 360 وهذا يعمل جيدًا بالنسبة لي:

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="3600"
    android:interpolator="@android:anim/linear_interpolator"
    android:repeatCount="infinite"
    android:duration="8000"
    android:pivotX="50%"
    android:pivotY="50%" />

ObjectAnimatior.ofFloat(view,"rotation",0,360).start();

جرب هذا.


في Android ، إذا كنت ترغب في تحريك كائن وجعله يحرك كائنًا من location1 إلى location2 ، فإن واجهة برمجة تطبيقات الرسوم المتحركة تعرض المواقع المتوسطة (tweening) ثم تصطف على مؤشر الترابط الرئيسي عمليات النقل المناسبة في الأوقات المناسبة باستخدام جهاز ضبط وقت . هذا يعمل بشكل جيد باستثناء أن الخيط الرئيسي يستخدم عادة للعديد من الأشياء الأخرى - الطلاء ، فتح الملفات ، الاستجابة لمدخلات المستخدم إلخ. يمكن تأجيل جهاز ضبط الوقت في قائمة الانتظار في كثير من الأحيان. ستحاول البرامج المكتوبة بشكل جيد القيام بأكبر عدد ممكن من العمليات في الخلفية (غير الرئيسية) ، ولكن لا يمكنك دائمًا تجنب استخدام الموضوع الرئيسي. يجب دائمًا إجراء العمليات التي تتطلب منك العمل على كائن واجهة المستخدم على مؤشر الترابط الرئيسي. أيضا ، سوف العديد من واجهات برمجة التطبيقات عمليات القمع مرة أخرى إلى الموضوع الرئيسي كنوع من سلامة الصفحات.

يتم رسم جميع المشاهدات على نفس مؤشر ترابط واجهة المستخدم الرسومية والتي تستخدم أيضًا لجميع تفاعلات المستخدم.

لذلك إذا كنت بحاجة إلى تحديث واجهة المستخدم الرسومية بشكل سريع أو إذا كان العرض يستغرق الكثير من الوقت ويؤثر على تجربة المستخدم ، فيمكنك استخدام SurfaceView.

مثال على صورة التدوير:

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    private DrawThread drawThread;

    public MySurfaceView(Context context) {
        super(context);
        getHolder().addCallback(this);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {   
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        drawThread = new DrawThread(getHolder(), getResources());
        drawThread.setRunning(true);
        drawThread.start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        boolean retry = true;
        drawThread.setRunning(false);
        while (retry) {
            try {
                drawThread.join();
                retry = false;
            } catch (InterruptedException e) {
            }
        }
    }
}


class DrawThread extends Thread{
    private boolean runFlag = false;
    private SurfaceHolder surfaceHolder;
    private Bitmap picture;
    private Matrix matrix;
    private long prevTime;

    public DrawThread(SurfaceHolder surfaceHolder, Resources resources){
        this.surfaceHolder = surfaceHolder;

        picture = BitmapFactory.decodeResource(resources, R.drawable.icon);

        matrix = new Matrix();
        matrix.postScale(3.0f, 3.0f);
        matrix.postTranslate(100.0f, 100.0f);

        prevTime = System.currentTimeMillis();
    }

    public void setRunning(boolean run) {
        runFlag = run;
    }

    @Override
    public void run() {
        Canvas canvas;
        while (runFlag) {
            long now = System.currentTimeMillis();
            long elapsedTime = now - prevTime;
            if (elapsedTime > 30){

                prevTime = now;
                matrix.preRotate(2.0f, picture.getWidth() / 2, picture.getHeight() / 2);
            }
            canvas = null;
            try {
                canvas = surfaceHolder.lockCanvas(null);
                synchronized (surfaceHolder) {
                    canvas.drawColor(Color.BLACK);
                    canvas.drawBitmap(picture, matrix, null);
                }
            } 
            finally {
                if (canvas != null) {
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            }
        }
    }
}

نشاط:

public class SurfaceViewActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MySurfaceView(this));
    }
}

كان لي هذه المشكلة كذلك ، وحاولت ضبط interpolator الخطي في XML دون نجاح. كان الحل الذي نجح لي هو إنشاء الرسوم المتحركة على هيئة RotateAnimation في الكود.

RotateAnimation rotate = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(5000);
rotate.setInterpolator(new LinearInterpolator());

ImageView image= (ImageView) findViewById(R.id.imageView);

image.startAnimation(rotate);

بغض النظر عن ما حاولت ، لم أستطع الحصول على هذا الحق في العمل باستخدام التعليمات البرمجية (و setRotation) للرسوم المتحركة على نحو سلس التناوب. ما انتهى بي الأمر هو جعل التغييرات درجة صغيرة جدا ، أن توقفات صغيرة غير ملحوظ. إذا لم تكن بحاجة إلى إجراء عدد كبير جدًا من الدورات ، فإن وقت تنفيذ هذه الحلقة لا يكاد يذكر. التأثير هو دوران سلس:

        float lastDegree = 0.0f;
        float increment = 4.0f;
        long moveDuration = 10;
        for(int a = 0; a < 150; a++)
        {
            rAnim = new RotateAnimation(lastDegree, (increment * (float)a),  Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            rAnim.setDuration(moveDuration);
            rAnim.setStartOffset(moveDuration * a);
            lastDegree = (increment * (float)a);
            ((AnimationSet) animation).addAnimation(rAnim);
        }

تشذيب <set> -Element التي لفت <rotate> -Element يحل المشكلة!

شكرا لشالفي!

لذلك يجب أن يكون لديك Rotation_ccw.xml مستغربًا على هذا النحو:

<?xml version="1.0" encoding="utf-8"?>

<rotate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="-360"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="2000"
    android:fillAfter="false"
    android:startOffset="0"
    android:repeatCount="infinite"
    android:interpolator="@android:anim/linear_interpolator"
    />

يتم الحصول على معرف الجهاز الفريد الخاص بجهاز نظام التشغيل Android كسلسلة ، باستخدام TelephonyManagerو ANDROID_ID، بواسطة:

String deviceId;
final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null) {
    deviceId = mTelephony.getDeviceId();
}
else {
    deviceId = Secure.getString(
                   getApplicationContext().getContentResolver(),
                   Secure.ANDROID_ID);
}

ولكنني أوصي بشدة باستخدام طريقة مقترحة من Google ، راجع تحديد عمليات تثبيت التطبيقات .





android animation view