English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
هذا المقال يشرح مثالًا على تأثير التحميل المماثل لـ iQIYI في Android، والكود المحدد كما يلي:
الصورة التوضيحية:
المفاهيم المستخدمة:
إذا كنت غير مألوف مع Path و ValueAnimator، يُنصح بزيارة Blogs الكبار هؤلاء حول تصميم واجهات المستخدم الخاصة، المقالة الأكثر ملاءمة لي حول تصميم واجهات المستخدم الخاصة، التعليمات والتطبيق العملي، هذا هو التعليمات والتطبيق العملي أيضًا، شكرًا لهم على جهودهم!(نأمل أن يتمكن الجميع من قراءتها بعناية والحصول على الكثير من الإلهام).
تفكيك الحركة
النقطة الصعبة هنا هي حساب الإحداثيات، وسأوضح ذلك بشكل مفصل لاحقًا:
أعتقد أن هذا الرسم قد تم عرضه، بالإضافة إلى وظائف السين والكوسين، وستظهر أيضًا إحداثيات p1،p2،p3.
p1.x = -(int) ((radius / 2 * Math.tan(30 * Math.PI / 180)));
p1.y = -radius / 2;
p2.x = p1.x;
p2.y = radius / 2;
p3.x = (int) (radius / 2 / Math.sin(60 * Math.PI / 180));
p3.y = 0;
تحديد بعض الخصائص
private static final String DEFAULT_COLOR = "#00ba9b"; private static final int DEFAULT_SIZE = 50; // الحجم الافتراضي private static final int DRAW_CIRCLE = 10001; // علامة الحالة رسم المستدير والمثلث تنفيذ رسم المستدير private static final int ROTATE_TRIANGLE = 10002; // علامة الحالة تنفيذ دوران المثلث والعودة إلى شكل المستدير private Context mContext; private Paint trianglePaint; // ريشة المثلث private Paint circlePaint; // ريشة المستدير private float paintStrokeWidth = 1; // ضبط عرض الخط المستدير private long duration = 800; //مدة التنفيذ private int mWidth; //عرض وارتفاع الرؤية private int mHeight; private Path trianglePath; //مسار المثلث private Path circlePath; //مسار الدائرة private Path dst; //path بعد حساب pathwayMeasure private Point p1, p2, p3; //ثلاث نقاط المثلث private ValueAnimator animator; //حركة متدرجة 0-1 للحصول على القيمة لتنفيذ الحركة private float mAnimatorValue = 0; //المتغير الذي يحتوي على القيمة من 0 إلى 1 private int mCurrentState = 0; //الحالة الحالية private int radius = 0; //قطر الدائرة private float startSegment; //طول البداية للدائرة private PathMeasure mMeasure; //قياس pathway private int triangleColor = -1; private int circleColor = -1;
ضبط pathway
1. لأن المثلث موجود دائمًا، نبدأ أولاً برسم المثلث، باستخدام pathway، نعرف بالفعل أordinates الثلاثة للنقاط المكونة للمثلث، يصبح رسم المثلث سهلًا جدًا.
trianglePath = new Path(); p1 = new Point(); p2 = new Point(); p3 = new Point(); trianglePath.moveTo(p1.x, p1.y); trianglePath.lineTo(p2.x, p2.y); trianglePath.lineTo(p3.x, p3.y); trianglePath.close();
بهذا يتم ضبط مسار المثلث، وبمجرد استدعاء canvans.drawPath() يمكن رسم المثلث على القناع.
2. ثم يبدأ رسم الدائرة، كما ذكرنا سابقًا أن هناك فجوة في الدائرة، نضيف الدائرة أيضًا إلى مسار pathway، السبب في عدم رسمها مباشرة على قناع الكanvas هو أننا سنقوم بحساب طول دائرة لاحقًا، سيساعدنا pathway في تنفيذ هذه العمليات،
circlePath = new Path(); RectF circleRect = new RectF(-radius, -radius, radius, radius); circlePath.addArc(circleRect, 268, 358); // يبدأ الرسم من 268 درجة من الدائرة ويدوم 258 درجة مع حجب درجتين
ضبط تأثير التحرك
بما أن الحركة تحتاج إلى مجموعة من البيانات بين 0 و 1
في هذه الحالة نستخدم القيم التي تقدمها لنا تأثير التحرك لإنشاء الحركة.
private void initAnimation() { TimeInterpolator timeInterpolator = new AccelerateDecelerateInterpolator(); animator = ValueAnimator.ofFloat(0, 1).setDuration(duration); animator.setInterpolator(timeInterpolator); animator.setRepeatMode(ValueAnimator.RESTART); animator.setRepeatCount(ValueAnimator.INFINITE); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mAnimatorValue = (float) animation.getAnimatedValue(); // هنا سنحصل على قيمة بين 0 و 1 invalidate(); // هنا يتم إعادة الرسم } }); animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { //هنا نقوم بالتحويل بين الحالات، تنفيذ مختلف الحركات switch (mCurrentState) { case DRAW_CIRCLE: mCurrentState = ROTATE_TRIANGLE; breake; case ROTATE_TRIANGLE: mCurrentState = DRAW_CIRCLE; breake; default: breake; } } }); }
onDraw
تحليل عملية onDraw
protected void onDraw(Canvas canvas) { super.onDraw(canvas); //تحريك النقطة المرجعية إلى المركز canvas.translate(mWidth / 2, mHeight / 2); //إعادة تعيين path dst dst.reset(); //تحديد الحالة الحالية switch (mCurrentState) { //هنا هو ما نقوله بالحالة الأولى case DRAW_CIRCLE: //هذه السطر هي للحصول على موقع البداية لـ path (dst) الذي يجب قطعه، إذا نظرنا بعناية إلى الحركة، يمكننا رؤية أن البداية للدائرة هي من موقع إلى //يتم رسمه من الجانبين، هذا الموقع هو حوالي 1/5 من الدائرة، عندما يتم رسم نقطة البداية للدائرة، يبدأ الرسم من نقطة البداية للدائرة، سأقوم بتنفيذ هذا الحركة //يتم تعيين الوقت تقريباً من 0 إلى 1 في الموقع 0.3.左右. startSegment = (float) (mMeasure.getLength() / 5 * ((0.3 - mAnimatorValue) > 0 ? (0.3 - mAnimatorValue) : 0)); //هناك شيء لا يهم فقط رسم مثلث trianglePaint.setStyle(Paint.Style.FILL_AND_STROKE); canvas.drawPath(trianglePath, trianglePaint); //هذه الطريقة هي للحصول على الجزء الذي تريد قطعه، أول parameter هو موقع البداية، الثاني هو موقع النهاية، الثالث هو //العدد هو جزء من path، أضف إلى path (dst)، انتبه أننا لا نستبدل بل نضيف لذا يجب إعادة تعيين، الرقم الرابع هو، هو //هل يجب تحريك نقطة البداية إلى نقطة البداية الحالية للحفاظ على مسار dst غير المعدل (مثال، إذا كان هناك path في dst من قبل، هنا //قام بتعيين القيمة على false، مما يؤكد على استمرارية dst وإضافة نقطة البداية للطريق الذي تم إضافته بعد التحريك إلى نهاية الطريق السابق، مما يضمن الاستمرارية) mMeasure.getSegment(startSegment, mMeasure.getLength() * mAnimatorValue, dst, true); canvas.drawPath(dst, circlePaint); breake; //نوع ثاني من الرسوم المتحركة case ROTATE_TRIANGLE: //تحفظ اللوحة، لأن هناك حاجة إلى تنفيذ اثنين من الرسوم المتحركة، تحفظ حالة اللوحة الابتدائية canvas.save(); //ثم تنفيذ دوران المثلث أولاً trianglePaint.setStyle(Paint.Style.FILL_AND_STROKE); canvas.rotate(360 * mAnimatorValue); canvas.drawPath(trianglePath, trianglePaint); //استعادة اللوحة canvas.restore(); //ثم يبدأ في اختفاء الدائرة الخارجية، والاختفاء مشابه لرسم الدائرة، هنا لدينا مجموعة من القيم التي تتغير بين 0 و 1، ونحتاج فقط //عند قطع الفقرة، تجعل النقطة البداية تتحرك نحو الطول الإجمالي، مما يسبب ظهور التأثير mMeasure.getSegment(mMeasure.getLength() * mAnimatorValue, mMeasure.getLength(), dst, true); canvas.drawPath(dst, circlePaint); breake; default: breake; } }
هذا هو نهاية محتويات هذا المقال، نأمل أن تكون قد ساعدتكم في التعلم، ونأمل أن تحصلوا على الدعم والمزيد من التشجيع لتدريب النفخ.
بيان: محتويات هذا المقال تم جمعها من الإنترنت، وتحتفظ الملكية للمالك الأصلي، تم جمع المحتويات من قبل المستخدمين عبر الإنترنت بشكل متعاوني وتحميلها بشكل مستقل، ويحتفظ الموقع بعدم امتلاك الملكية، ولا يتم تعديل المحتويات بشكل يدوي، ولا يتحمل الموقع أي مسؤولية قانونية متعلقة بذلك. إذا كنت قد وجدت محتويات تتضمن حقوق النسخ، فلا تتردد في إرسال بريد إلكتروني إلى: notice#oldtoolbag.com (عند إرسال البريد الإلكتروني، يرجى استبدال # ب @) للإبلاغ، وتقديم الدليل على ذلك، إذا تم التحقق من ذلك، فإن الموقع سيزيل المحتويات المزعجة فوراً.