कस्टम व्यू को इंटरैक्टिव बनाना

लिखने का तरीका आज़माएं
Android के लिए, Jetpack Compose हमारा सुझाया गया यूज़र इंटरफ़ेस (यूआई) टूलकिट है. Compose में लेआउट इस्तेमाल करने का तरीका जानें.

यूज़र इंटरफ़ेस (यूआई) बनाना, कस्टम व्यू बनाने का सिर्फ़ एक हिस्सा है. आपको यह भी करना होगा अपने व्यू को उपयोगकर्ता के इनपुट पर इस तरह से रिस्पॉन्स दें कि असल दुनिया में की जाने वाली वह गतिविधि हो जिसकी नकल की जा रही हो.

अपने ऐप्लिकेशन में मौजूद ऑब्जेक्ट को असली ऑब्जेक्ट जैसा बनाएं. उदाहरण के लिए, आपके ऐप्लिकेशन में मौजूद इमेज, खोज के नतीजों में दिखती हैं और किसी दूसरी जगह पर फिर से दिखती हैं. इसकी वजह यह है कि असली दुनिया में ऐसा नहीं करते. इसके बजाय, अपनी इमेज को एक जगह से दूसरी जगह ले जाएं कोई दूसरा.

उपयोगकर्ता किसी इंटरफ़ेस में सूक्ष्म व्यवहार या अनुभव को महसूस करते हैं और उन पर सबसे अच्छी प्रतिक्रिया देते हैं ऐसी बारीकियां दिखाना जो असल दुनिया जैसी ही दिखती हों. उदाहरण के लिए, जब उपयोगकर्ता किसी यूज़र इंटरफ़ेस (यूआई) ऑब्जेक्ट को फ़्लिंग करते हैं, शुरुआत में उन्हें जड़त्व का एहसास होगा, जिसकी वजह से गति धीमी हो जाती है. आखिर में उन्हें ऐसी गति का अनुभव दें, जो ऑब्जेक्ट को फ़्लिंग करें.

यह पेज बताता है कि अलग-अलग वर्शन में ये वास्तविक दुनिया के व्यवहार को आपके कस्टम व्यू से जोड़ सकते हैं.

इससे जुड़ी अन्य जानकारी यहां देखी जा सकती है: इनपुट इवेंट के बारे में खास जानकारी और प्रॉपर्टी ऐनिमेशन खास जानकारी.

इनपुट जेस्चर मैनेज करें

कई अन्य यूज़र इंटरफ़ेस (यूआई) फ़्रेमवर्क की तरह, Android भी इनपुट इवेंट मॉडल के साथ काम करता है. उपयोगकर्ता कार्रवाइयां, कॉलबैक को ट्रिगर करने वाले इवेंट में बदल जाती हैं और कॉलबैक का इस्तेमाल करें, ताकि यह कस्टमाइज़ किया जा सके कि आपका ऐप्लिकेशन लोगों को कैसे जवाब देता है. सबसे सामान्य इनपुट Android सिस्टम में, टच इवेंट होता है, जो ट्रिगर होता है onTouchEvent(android.view.MotionEvent). इवेंट को मैनेज करने के लिए, इस तरीके को नीचे बताए गए तरीके से बदलें:

Kotlin

override fun onTouchEvent(event: MotionEvent): Boolean {
    return super.onTouchEvent(event)
}

Java

@Override
   public boolean onTouchEvent(MotionEvent event) {
    return super.onTouchEvent(event);
   }

अपने-आप होने वाले टच इवेंट, खास तौर पर मददगार नहीं होते. मॉडर्न टच यूज़र इंटरफ़ेस (यूआई) इंटरैक्शन को जेस्चर के रूप में परिभाषित किया जा सकता है, जैसे कि टैप करना, खींचना, धकेलना, फ़्लिंग, और ज़ूमिंग. रॉ टच इवेंट को हाथ के जेस्चर में बदलने के लिए, Android उपलब्ध कराता है GestureDetector.

किसी क्लास के इंस्टेंस में पास करके GestureDetector बनाना जो लागू करता है GestureDetector.OnGestureListener. अगर आपको हाथ के कुछ जेस्चर ही प्रोसेस करने हैं, तो GestureDetector.SimpleOnGestureListener अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है GestureDetector.OnGestureListener को लागू करने के बजाय इंटरफ़ेस पर कॉपी करने की सुविधा मिलती है. उदाहरण के लिए, यह कोड एक ऐसी क्लास बनाता है जो GestureDetector.SimpleOnGestureListener और बदलाव onDown(MotionEvent).

Kotlin

private val myListener =  object : GestureDetector.SimpleOnGestureListener() {
    override fun onDown(e: MotionEvent): Boolean {
        return true
    }
}

private val detector: GestureDetector = GestureDetector(context, myListener)

Java

class MyListener extends GestureDetector.SimpleOnGestureListener {
   @Override
   public boolean onDown(MotionEvent e) {
       return true;
   }
}
detector = new GestureDetector(getContext(), new MyListener());

आप GestureDetector.SimpleOnGestureListener का इस्तेमाल करें या न करें, हमेशा किसी onDown() true रिटर्न करने वाला तरीका. यह ज़रूरी है, क्योंकि हाथ के सभी जेस्चर onDown() संदेश से शुरू करें. false वापस करने पर onDown() से, जैसे GestureDetector.SimpleOnGestureListener लागू करता है, जबकि सिस्टम आपको बाकी के जेस्चर और GestureDetector.OnGestureListener पर कॉल नहीं किया गया. सिर्फ़ वापस जाएं अगर आप पूरी जानकारी को अनदेखा करना चाहते हैं, तो onDown() के false हाथ के जेस्चर.

GestureDetector.OnGestureListener को लागू करने और बनाने के बाद GestureDetector का एक इंस्टेंस है, तो आप अपने आपको मिलने वाले टच इवेंट को समझने के लिए, GestureDetector onTouchEvent().

Kotlin

override fun onTouchEvent(event: MotionEvent): Boolean {
    return detector.onTouchEvent(event).let { result ->
        if (!result) {
            if (event.action == MotionEvent.ACTION_UP) {
                stopScrolling()
                true
            } else false
        } else true
    }
}

Java

@Override
public boolean onTouchEvent(MotionEvent event) {
   boolean result = detector.onTouchEvent(event);
   if (!result) {
       if (event.getAction() == MotionEvent.ACTION_UP) {
           stopScrolling();
           result = true;
       }
   }
   return result;
}

onTouchEvent() को टच इवेंट पास करने पर, ऐसा नहीं किया जा सकता हाथ के जेस्चर से पहचानने पर, यह false दिखाता है. इसके बाद, आप दौड़ सकते हैं जेस्चर की पहचान करने वाला एक कस्टम कोड है.

शारीरिक रूप से भरोसेमंद मोशन बनाएं

टचस्क्रीन डिवाइसों को कंट्रोल करने के लिए, हाथ के जेस्चर बेहतरीन तरीके से कंट्रोल किए जाते हैं. हालांकि, इन तरीकों से भी यह साधारण और याद रखने में तब तक मुश्किल है, जब तक कि संभावित नतीजे.

उदाहरण के लिए, मान लीजिए कि आपको ऐसा हॉरिज़ॉन्टल फ़्लिंग जेस्चर लागू करना है जो व्यू में बनाए गए आइटम को उसके वर्टिकल ऐक्सिस के आस-पास घूमते हुए सेट करता है. हाथ का यह जेस्चर यह तब समझ में आता है जब यूज़र इंटरफ़ेस (यूआई), फ़्लिंग की दिशा में तेज़ी से जवाब देता हो, तो धीमा हो जाता है, जैसे कि उपयोगकर्ता फ़्लाईव्हील पर धकेलता है और उसे घुमाता है.

दस्तावेज़: स्क्रोल को ऐनिमेट करें जेस्चर से, अपने स्कॉल को लागू करने के तरीके के बारे में पूरी जानकारी मिलती है व्यवहार. हालांकि, फ़्लाइव्हील की तरह काम करना कोई आसान काम नहीं है. फ़िज़िक्स पर बहुत ज़्यादा और फ्लाईव्हील मॉडल को ठीक से काम करने के लिए गणित ज़रूरी है. अच्छी बात यह है कि Android इस तरह की गतिविधि और इससे जुड़ी अन्य गतिविधियों को सिम्युलेट करने के लिए, हेल्पर क्लास उपलब्ध कराता है. कॉन्टेंट बनाने Scroller अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है क्लास, फ़्लायव्हील-स्टाइल फ़्लिंग जेस्चर को हैंडल करने का आधार है.

फ़्लिंग शुरू करने के लिए, कॉल करें fling() अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है शुरुआती वेलोसिटी के साथ-साथ, सबसे कम और ज़्यादा से ज़्यादा x और y फ़्लिंग की वैल्यू डालें. वेलोसिटी वैल्यू के लिए, आप GestureDetector.

Kotlin

fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
    scroller.fling(
            currentX,
            currentY,
            (velocityX / SCALE).toInt(),
            (velocityY / SCALE).toInt(),
            minX,
            minY,
            maxX,
            maxY
    )
    postInvalidate()
    return true
}

Java

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
   scroller.fling(currentX, currentY, velocityX / SCALE, velocityY / SCALE, minX, minY, maxX, maxY);
   postInvalidate();
    return true;
}

fling() को कॉल करने पर, फ़्लिंग के लिए फ़िज़िक्स मॉडल सेट अप हो जाता है हाथ के जेस्चर. इसके बाद, कॉल करके Scroller को अपडेट करें Scroller.computeScrollOffset() नियमित अंतराल पर. computeScrollOffset() इसे अपडेट करता है: मौजूदा समय को पढ़कर और Scroller ऑब्जेक्ट की अंदरूनी स्थिति भौतिकी के मॉडल का इस्तेमाल करके, उस समय x और y की स्थिति का पता लगाना समय. कॉल करें getCurrX() अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है और getCurrY() का इस्तेमाल करें.

ज़्यादातर व्यू, Scroller ऑब्जेक्ट के x और y ऑब्जेक्ट को पास करते हैं सीधे पोज़िशन पर ले जाएं scrollTo(). यह उदाहरण कुछ अलग है: इसमें स्क्रोल करने की मौजूदा x पोज़िशन का इस्तेमाल किया गया है का इस्तेमाल करें.

Kotlin

scroller.apply {
    if (!isFinished) {
        computeScrollOffset()
        setItemRotation(currX)
    }
}

Java

if (!scroller.isFinished()) {
    scroller.computeScrollOffset();
    setItemRotation(scroller.getCurrX());
}

Scroller क्लास, स्क्रोल करने की पोज़िशन का पता लगाती है, लेकिन आपके दृश्य पर उन स्थितियों को अपने आप लागू नहीं करता. नए निर्देशांक लागू करना अक्सर इतना काफ़ी होता है कि स्क्रोल करने वाला ऐनिमेशन एक जैसा दिखता है. इसके दो तरीके हैं यह करें:

  • कॉल करके फिर से जनरेट करने के लिए कहें postInvalidate() अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है fling() पर कॉल करने के बाद. इस तकनीक का इस्तेमाल करने के लिए ज़रूरी है कि इसमें स्क्रोल ऑफ़सेट की गिनती करें onDraw() अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है और हर बार स्क्रोल ऑफ़सेट करने पर postInvalidate() को कॉल करें बदलाव.
  • सेट अप करें ValueAnimator अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है फ़्लिंग की अवधि के दौरान ऐनिमेट किया जा सके और प्रोसेस में लिसनर को जोड़ा जा सके कॉल करने पर ऐनिमेशन अपडेट addUpdateListener(). इस तकनीक से आपको View.

अपने ट्रांज़िशन को आसान बनाएं

उपयोगकर्ता एक मॉडर्न यूज़र इंटरफ़ेस (यूआई) की मदद से अलग-अलग स्थितियों के बीच आसानी से ट्रांज़िशन करने की उम्मीद करते हैं: यूज़र इंटरफ़ेस (यूआई) एलिमेंट दिखने और गायब होने के बजाय फ़ेड आउट होने लगता है, और शुरू हो जाता है और अचानक से शुरू और बंद होने के बजाय, आसानी से खत्म हो रहा हो. Android प्रॉपर्टी ऐनिमेशन फ़्रेमवर्क से, ट्रांज़िशन को बिना किसी रुकावट के आसानी से पूरा किया जा सकता है.

ऐनिमेशन सिस्टम का इस्तेमाल करने के लिए, जब भी कोई प्रॉपर्टी बदलती है, जो आपकी व्यू कैसा दिखता है, प्रॉपर्टी को सीधे तौर पर न बदलें. इसके बजाय, बदलाव करने के लिए ValueAnimator. नीचे दिए गए उदाहरण में, व्यू में चुने गए चाइल्ड कॉम्पोनेंट में बदलाव करने से, पूरी प्रोसेस रेंडर हो जाती है दृश्य घुमाता है ताकि चयन पॉइंटर मध्य हो जाए. ValueAnimator कई सौ की अवधि के लिए घूर्णन बदलता है नई रोटेशन वैल्यू को तुरंत सेट करने के बजाय, मिलीसेकंड में.

Kotlin

autoCenterAnimator = ObjectAnimator.ofInt(this, "Rotation", 0).apply {
    setIntValues(targetAngle)
    duration = AUTOCENTER_ANIM_DURATION
    start()
}

Java

autoCenterAnimator = ObjectAnimator.ofInt(this, "Rotation", 0);
autoCenterAnimator.setIntValues(targetAngle);
autoCenterAnimator.setDuration(AUTOCENTER_ANIM_DURATION);
autoCenterAnimator.start();

अगर जिस वैल्यू को बदलना है वह View में से एक है प्रॉपर्टी के लिए, ऐनिमेशन करना और भी आसान है, क्योंकि व्यू में बिल्ट-इन ViewPropertyAnimator जिसे कई प्रॉपर्टी के साथ-साथ ऐनिमेशन के लिए ऑप्टिमाइज़ किया गया हो, जैसा कि नीचे दिया गया उदाहरण:

Kotlin

animate()
    .rotation(targetAngle)
    .duration = ANIM_DURATION
    .start()

Java

animate().rotation(targetAngle).setDuration(ANIM_DURATION).start();