2015-08-26 31 views
7

रंग # 1 से रंग # 2 तक ढाल को एनिमेट कैसे करें?ढाल को एनिमेट कैसे करें?

enter image description here

को कुछ इसी तरह मैं (हरे रंग के साथ शुरू करने और लाल रंग से समाप्त हां, तो यह finit किया जाएगा एनीमेशन)

उत्तर

22

हालांकि यह googling इकाई के लिए स्वास्थ्य बार के रूप में उपयोग करने की योजना बना रहा हूँ, मैं एंड्रॉइड के लिए इसे करने के 2 तरीके पाए गए: use ShaderFactory या new Shader(new LinearGradient()) का उपयोग करके व्यू बढ़ाता है। दोनों उत्तर वही करते हैं - new Shader() प्रत्येक View.onDraw(Canvas canvas) विधि कॉल को कॉल करना। यह वास्तव में महंगा है अगर ऐसे एनिमेटेड ग्रेडियेंट्स की संख्या ~ 3 से अधिक है।

तो मैंने इसे एक और तरीका किया। मैंने new को प्रत्येक onDraw() पर कॉल करने से बचाया, एकल सटीक LinearGradient का उपयोग करके। यही कारण है कि यह की तरह लग रहा है तरीका बताया गया है (GIF, इसलिए एनीमेशन सड़ा हुआ):

enter image description here

चाल LinearGradient जो colorsCount बार View.getWidth() से बड़ा है बनाने के लिए है। उसके बाद आप canvas.translate() का उपयोग कर सकते हैं, जबकि ग्रेडिएंट ड्राइंग करते हैं, इसके रंग को बदलने के लिए, इसलिए में कॉल नहीं करते हैं।

ढाल बनाने के लिए, आपको वर्तमान चौड़ाई और ऊंचाई की आवश्यकता है। मैंने इसे onSizeChanged() में किया था। इसके अलावा मैंने यहां भी Shader सेट किया है।

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    super.onSizeChanged(w, h, oldw, oldh); 

    width = getWidth(); 
    height = getHeight(); 

    LinearGradient gradient = new LinearGradient(
      0, height/2, width * colors.length - 1, height/2, 
      colors, null, Shader.TileMode.REPEAT); 
    fillPaint.setShader(gradient); 

    shapePath = getParallelogrammPath(width, height, sidesGap); 
    shapeBorderPath = getParallelogrammPath(width, height, sidesGap); 
} 

मैं समानांतर दृश्यों के कारण पथ का उपयोग करता हूं, आप जो चाहें उसका उपयोग कर सकते हैं। जब ड्राइंग को लागू करने के लिए, आप 2 बातें नोटिस देना चाहिए:

@Override 
protected void onDraw(Canvas canvas) { 
    canvas.save(); 
    canvas.translate(-gradientOffset, 0); 
    shapePath.offset(gradientOffset, 0f, tempPath); 
    canvas.drawPath(tempPath, fillPaint); 
    canvas.restore(); 

    canvas.drawPath(shapeBorderPath, borderPaint); 

    super.onDraw(canvas); // my View is FrameLayout, so need to call it after 
} 

इसके अलावा, आप canvas.save() & canvas.restore() उपयोग करना चाहिए: आप ऑफसेट और offset() अपने भरने आकार वर्तमान पर translate() पूरे canvas की जरूरत है। यह कैनवास के आंतरिक मैट्रिक्स को ढेर करने और इसे संगत रूप से बहाल करने के लिए बचाएगा।

तो आखिरी चीज़ जो आपको करने की ज़रूरत है gradientOffset को एनिमेट करना है। आप ObjectAnimator (Property Animation) जैसे सभी चीजों का उपयोग कर सकते हैं। मैंने TimeAnimator का उपयोग किया, क्योंकि मुझे updateTick को नियंत्रित करने और सीधे ऑफ़सेट शुरू करने की आवश्यकता थी। यहाँ मेरी प्राप्ति (थोड़ा कठिन और कठोर) है:

static public final int LIFETIME_DEAFULT = 2300; 
private long lifetime = LIFETIME_DEAFULT, updateTickMs = 25, timeElapsed = 0; 
private long accumulatorMs = 0; 
private float gradientOffset = 0f; 

public void startGradientAnimation() { 
    stopGradientAnimation(); 
    resolveTimeElapsed(); 

    final float gradientOffsetCoef = (float) (updateTickMs)/lifetime; 
    final int colorsCount = this.colors.length - 1; 
    gradientAnimation.setTimeListener(new TimeAnimator.TimeListener() { 
     @Override 
     public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) { 
      final long gradientWidth = width * colorsCount; 
      if (totalTime > (lifetime - timeElapsed)) { 
       animation.cancel(); 
       gradientOffset = gradientWidth; 
       invalidate(); 
      } else { 
       accumulatorMs += deltaTime; 

       final long gradientOffsetsCount = accumulatorMs/updateTickMs; 
       gradientOffset += (gradientOffsetsCount * gradientWidth) * gradientOffsetCoef; 
       accumulatorMs %= updateTickMs; 

       boolean gradientOffsetChanged = (gradientOffsetsCount > 0) ? true : false; 
       if (gradientOffsetChanged) { 
        invalidate(); 
       } 
      } 
     } 
    }); 

    gradientAnimation.start(); 
} 

पूर्ण View कोड आप here

+0

मुझे समझ नहीं आता पा सकते हैं ... आप प्रश्न पूछा और पर एक ही समय में यह जवाब उसी दिन? यह कभी सवाल नहीं था। –

+4

@ क्रिस-जूनियर, मैंने बहुत कुछ खोजा और मुझे वह जवाब नहीं मिला जो मैं चाहता था। तो मैंने कुछ प्रकार का शोध किया और अंत में इसे मिला। तब मैंने सोचा "एचएम, हो सकता है कि कोई और भविष्य में इसे खोजे और मेरे साथ फंस जाए जैसा मैं करता हूं?" - इसलिए मैंने जवाब के साथ सवाल बनाया। इसके अलावा, ऐसा करने के लिए एक अंतर्निहित सुविधा है। 'प्रश्न पूछें' पर क्लिक करने का प्रयास करें। एक चेक है 'अपने स्वयं के प्रश्न का उत्तर दें - अपना ज्ञान, क्यू एंड ए-स्टाइल' – Nexen

+0

साझा करें आह, ठीक है, मैं समय से उलझन में था। इसके लिए धन्यवाद, और आपके समाधान को साझा करने के लिए धन्यवाद। –

संबंधित मुद्दे