हर कोई जिसने लाइव वॉलपेपर इंस्टॉल करने की कोशिश की, ने डेस्कटॉप के बीच चलते समय एक लंबन प्रभाव देखा। यह बहुत दिलचस्प लग रहा है, लेकिन इसके कार्यान्वयन में ऐसी समस्याएं हैं जिन्हें इस लेख में हाइलाइट किया जाएगा। हम एंड्रॉइड लाइव वॉलपेपर के लिए लंबन प्रभाव के कार्यान्वयन के बारे में बात करेंगे।
नीचे हम मानक और कस्टम कार्यान्वयन विधियों पर विचार करेंगे। उनमें से प्रत्येक के नुकसान और फायदे का संकेत दिया गया है।
मानक विधि
API7 के साथ शुरू,
WallpaperService.Engine वर्ग
ऑनऑफसेट्सचेंज विधि के साथ दिखाई दिया। हर बार जब डेस्कटॉप अपनी स्थिति बदलता है तो इस विधि को कहा जाता है। इसका उपयोग करने के लिए, यह
WallpaperService.Engine वर्ग के स्वयं के कार्यान्वयन में इसे ओवरराइड करने के लिए पर्याप्त है। विधि में निम्नलिखित हस्ताक्षर हैं:
onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset)
सभी स्थानांतरित मापदंडों में से, हम
xOffset और
yOffset में रुचि रखते हैं, और लाइव वॉलपेपर के संबंध में, यह
xOffset का उपयोग करने के लिए पर्याप्त है। यह पैरामीटर 0 से 1 तक भिन्न होता है, डेस्कटॉप के एक चरम स्थान पर 0 और डेस्कटॉप के दूसरे चरम स्थान पर 1 के बराबर होता है। यदि डेस्कटॉप डिफ़ॉल्ट स्थिति (मध्य में) में है, तो xOffset पैरामीटर 0.5 है। उदाहरण के लिए, 3 डेस्कटॉप के लिए,
xOffset क्रमशः 0, 0.5, 1 होगा। जब एक डेस्कटॉप से दूसरे में जा रहा है, तो पैरामीटर सुचारू रूप से बदल जाता
है , और
onOffsetsChanged विधि
को बार-बार कहा जाता है। हालाँकि, विभिन्न उपकरणों पर "चिकनाई" भिन्न हो सकती है।
इस प्रकार, अपने वॉलपेपर के रेंडरर को इस पैरामीटर को पास करते हुए, आप लंबन प्रभाव का एहसास करते हुए, उन्हें सही दिशा में स्थानांतरित कर सकते हैं। लाभ स्पष्ट हैं: एक न्यूनतम कोड और डेस्कटॉप के साथ तुल्यकालिक काम।
इस विधि के नुकसान के लिए नहीं तो सब कुछ ठीक हो जाएगा:
- जब डेस्कटॉप के माध्यम से स्क्रॉल किया जाता है, तो सभी डिवाइस (शेल) ऑनऑफ़सेटचैनड विधि को कॉल नहीं करते हैं। हैरानी की बात है, यह अक्सर नवीनतम उपकरणों (उदाहरण के लिए, एचटीसी वन एक्स) के साथ होता है।
- सभी डिवाइस इसे पर्याप्त संख्या में नहीं करते हैं, जिसके कारण वॉलपेपर की गति की चिकनाई तेजी से घट जाती है।
- यदि डिवाइस में डेस्कटॉप को लूप किया जाता है, तो अंतिम से पहली में स्विच करते समय, वॉलपेपर का एक तेज स्क्रॉल होता है।
मूल विधि, ZTouchMove कक्षा
इन सभी समस्याओं के कारण, यह निर्णय लिया गया कि सभी उपकरणों पर चलेगा। इसके लिए, उसी
WallpaperService.Engine वर्ग का
ऑनटचिव तरीका पाया गया। इस विधि का उपयोग करने के लिए, आपको पहले इसकी कॉल को सक्षम करना होगा:
@Override public void onCreate(SurfaceHolder surfaceHolder) { setTouchEventsEnabled(true); }
इसके अलावा, यह विधि स्क्रीन को छूने से संबंधित सभी घटनाओं को स्वीकार करेगी। हालाँकि, मैं स्पर्श को विस्थापन के पहले से ही पसंदीदा प्रारूप में 0 से 1 तक परिवर्तित करना चाहता हूं, जिसमें जड़ता, गति एनीमेशन और अन्य खुशियाँ शामिल हैं। इसके लिए, एक टच हैंडलर लिखा गया था, जिसने आउटपुट में "बिल्कुल वही दिया" जिसकी आवश्यकता है। नीचे दिए गए हैंडलर के लिए कोड है:
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Point; import android.os.Build; import android.os.Handler; import android.view.Display; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.ViewConfiguration; import android.view.WindowManager; import android.view.animation.Interpolator; import android.widget.Scroller; public class ZTouchMove { public interface ZTouchMoveListener { public void onTouchOffsetChanged(float xOffset); } private List<ZTouchMoveListener> mListeners = new ArrayList<ZTouchMoveListener>(); public class ZInterpolator implements Interpolator { public float getInterpolation(float input) {
मैं तुरंत एक आरक्षण करना चाहता हूं कि कोड सुपर साफ और सुव्यवस्थित होने का दिखावा नहीं करता है, मेरे लिए यह महत्वपूर्ण था कि यह अपना काम पूरा करे, एक केश के लिए समय नहीं था।
ZTouchMove क्लास में एक
onTouchEvent (MotionEvent e) मेथड है, एक इनपुट की तरह, जिसे
WallpaperService.Engine क्लास के
onTouchEvent से कॉल किया जाता है। इसके बाद, आपके रेंडरर को
ZTouchMoveListener इंटरफ़ेस को लागू करना चाहिए,
onTouchOffsetChanged (फ्लोट xOffset) पद्धति के साथ , जो सामान्य रूप से 0 से 1 तक परिणाम को स्वीकार करेगा।
यह भी आवश्यक है कि
ZTouchMove को
init (Context ctx) विधि कहकर, इसके संदर्भ में एप्लिकेशन को पास करके आरंभ किया जाए। स्क्रीन की चौड़ाई और कुछ अन्य मापदंडों को निर्धारित करने के लिए यह आवश्यक है। और रेंडरर को एक इवेंट श्रोता के रूप में भी पंजीकृत करें:
mTouchMove = new ZTouchMove(); mTouchMove.init(ctx); mTouchMove.addMovingListener(mRenderer);
चूंकि मुझे वर्चुअल डेस्कटॉप की संख्या निर्धारित करने का कोई तरीका नहीं मिला, इसलिए यह पैरामीटर चर
mNumVirtualScreens में हार्डकोड किया गया था। यदि वांछित है, तो आप इसे बदलने के लिए एक विधि जोड़ सकते हैं और अपने विवेक पर इसका उपयोग कर सकते हैं।
ZTouchMove वर्ग के एनीमेशन और जड़ता के कार्यान्वयन की विशेषताएं: धीमी गति से आंदोलनों के दौरान, "जड़ता" को ट्रिगर किया जाता है, तेज आंदोलनों के दौरान, अगले आभासी डेस्कटॉप के लिए "करीब" ट्रिगर होता है। चरम स्थिति में, "वसंत" काम करता है।
इस पद्धति की कमियों के बीच, यह डेस्कटॉप और वॉलपेपर के आंदोलन के गैर-सिंक्रनाइज़ेशन को ध्यान देने योग्य है। यही है, ऐसा हो सकता है कि डेस्कटॉप पहले से ही चरम स्थिति में "आराम" कर चुका है, और वॉलपेपर अभी भी स्थानांतरित किया जा सकता है। या डेस्कटॉप पर, एक निश्चित गति से, आसन्न स्क्रीन के लिए "करीब" काम करेगा, और वॉलपेपर का "करीब" काम नहीं कर सकता है। इन प्रभावों को बाहर करना संभव नहीं है, क्योंकि सिद्धांत रूप में हमें डेस्कटॉप की वर्तमान स्थिति के बारे में जानकारी नहीं है।
हाइब्रिड समाधान
उपयोगकर्ता स्वयं सेटिंग्स में "लंबन" विधि का चयन करेगा, या आप स्वचालित रूप से यह निर्धारित कर सकते हैं कि मानक विधि काम करती है, और यदि नहीं, तो
ZTouchMove पर स्विच करें। यहां स्वचालित पहचान का कार्यान्वयन है:
if(xOffset != 0 && xOffset != 0.5f && xOffset != 1 || mOffsetChangedEnabled) { mOffsetChangedEnabled = true; mXPos = xOffset - 0.5f;
यह इस तथ्य पर आधारित है कि मानक कार्यान्वयन में
xOffset 0, 0.5 और 1 के अलावा अन्य मानों को स्वीकार नहीं करता है, यदि मानक
onSffsetsChanged विधि के
WallpaperService.Engine वर्ग सही तरीके से काम नहीं करता है। तदनुसार,
mOffsetChangedEnabled ध्वज डिफ़ॉल्ट रूप से
गलत है, और इसका मतलब है कि
ZTouchMove वर्ग को काम करना चाहिए।
व्यक्तिगत रूप से, मैंने एक हाइब्रिड सेटिंग को चुना, जहां डिफ़ॉल्ट रूप से स्वचालित पहचान काम करती है, और दो और विकल्प हैं: "डेस्कटॉप मोड" और "टच मोड"।
अद्यतन: दो कार्यान्वयन विधियों का
एक वीडियो।