2012-06-18 28 views
8

मैंने दबाए गए और दबाए गए राज्यों के लिए चयनकर्ता के साथ एक छवि बटन बनाया, और यह ठीक काम करता है।विभिन्न क्लिक राज्यों के साथ अनियमित आकार वाले छवि बटन बनाना

लेकिन बटन एक अनियमित आकृति है और मैं केवल यह क्लिक करने योग्य चाहते हैं, जहां अंतर्निहित आयताकार छवि गैर पारदर्शी है।

इसलिए मैंने एक ऑन टच लिस्टनर लागू किया जो बिटमैप के पिक्सेल मानों के खिलाफ टच इवेंट के समन्वय की जांच करता है (जैसा कि पहले उत्तर में वर्णित है: link)। यह तर्क करता है कि बटन दबाए जाने पर निर्णय लेने के संदर्भ में, लेकिन अब बटन की छवि अब दबाए गए चित्र में नहीं बदली है।

चयनकर्ता xml फ़ाइल:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" > 
    <item android:state_pressed="true" android:drawable="@drawable/button_start_call_pressed" /> 
    <item android:drawable="@drawable/button_start_call_normal" /> 
</selector> 

आंशिक रूप से पारदर्शी ImageButton लेआउट में:

<ImageButton 
    android:id="@+id/dashboardStartCallButton" 
    android:background="@null" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/start_call_button_selector" 
    /> 

गतिविधि में:

public void onCreate(Bundle savedInstance) { 
    super.onCreate(savedInstance); 
    ... 
    ImageButton startCallButton = (ImageButton) this.findViewById(R.id.dashboardStartCallButton); 
    startCallButton.setOnTouchListener(new OnTouchListener() { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      return OnStartCallButtonTouch(v,event); 
     }   
    }); 
} 


public boolean OnStartCallButtonTouch(View v, MotionEvent event) 
{ 
    Bitmap TheBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.button_start_call_normal); 
    int eventPadTouch = event.getAction(); 
    int iX = (int) event.getX(); 
    int iY = (int) event.getY(); 
    switch (eventPadTouch) { 
     case MotionEvent.ACTION_DOWN: 
      if (iX>=0 & iY>=0 & iX<TheBitmap.getWidth() & iY<TheBitmap.getHeight()) {     
       if (TheBitmap.getPixel(iX,iY)!=0) { 
        onStartCallButtonClicked(v); 
        return false; 
       } 
      } 
    }   
    return true; 
} 
+0

क्यों नहीं 'ऑनस्टार्टकॉलबटन टच (वी, घटना) वापस लौटें startCallButton.onTouch() '? –

उत्तर

10

यहाँ मैं क्या है मुझे लगता है तुम वास्तव में इस के लिए देख रहे हैं ':

View.dispatchTouchEvent(...)

आप झूठी वापस जाने के लिए करता है, तो बिंदु वांछित क्षेत्र में नहीं है अपने कस्टम बटन में इस विधि ओवरराइड करने के लिए की जरूरत है। मेरा सुझाव है कि आप इसके बारे में इस तरह जाना:

public static class MyButton extends ImageButton { 
    ... 
    @Override 
    public boolean dispatchTouchEvent(MotionEvent event) { 
     int iX = (int) event.getX(); 
     int iY = (int) event.getY(); 
     // TODO Or use a more sophisticated, pixel value-based condition 
     if (!(iX>=0 & iY>=0 & iX<TheBitmap.getWidth() & iY<TheBitmap.getHeight())) { 
      return false; 
     } 
     return super.dispatchTouchEvent(event) 
    } 
} 

OnTouchListener का उपयोग नहीं क्यों: क्योंकि आप View.onTouchEvent() (जो super.dispatchTouchEvent (घटना) में किया जाता है) के माध्यम से कॉल करने की आवश्यकता बताने के लिए देखें drawable राज्यों संभाल (यह (onTouchEvent में किया है) View.refreshDrawableState() विधि का उपयोग कर, और वहाँ भी कुछ अधिक जटिल तर्क है)

onTouchEvent() क्यों नहीं ओवरराइड: View.dispatchTouchEvent() में नहीं है क्योंकि एक शर्त है कि अगर ऑनटचलिस्टर है, तो श्रोता को सबकुछ संभालने दें और सत्य वापस आएं। तो यदि बाद में आप किसी कारण से बटन पर ऑन टच लिस्टनर सेट करते हैं, तो टचएवेंट() में आपकी समन्वय-आधारित स्थिति जांच नहीं की जाएगी, क्योंकि टचएवेंट() को कभी भी कॉल नहीं किया जाएगा। dispatchTouchEvent अधिभावी द्वारा() तुम बहुत शीर्ष पर अंतिम रूप से फिल्टर और जगह में अन्य सभी तर्क छोड़ - आप बटन के लिए किसी भी श्रोताओं को जोड़ सकते हैं और वे के रूप में वे सामान्य बटन के लिए होगा काम करेंगे, लेकिन केवल जब अपनी हालत सच है।

+0

अरे, यह कैसा चल रहा है? अगर उत्तर आपके लिए किया गया है, तो कृपया इसे स्वीकार करने पर विचार करें। –

1

मैं तुम्हें स्पर्श अपने बटन के अंदर है या नहीं करने के लिए अपने टक्कर पता लगाने संशोधित करने की आवश्यकता है। फोल्डिंग दृष्टिकोण का प्रयोग करें।

public boolean OnStartCallButtonTouch(View v, MotionEvent event) 
{ 
    Bitmap TheBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.button_start_call_normal); 
    int eventPadTouch = event.getAction(); 
    int iX = (int) event.getX(); 
    int iY = (int) event.getY(); 

    int[] location = new int[2]; 
    v.getLocationOnScreen(location); 

    int viewX = location[0]; 
    int viewY = location[1]; 


    switch (eventPadTouch) { 
     case MotionEvent.ACTION_DOWN: 
      if (iX>=viewX & iY>=viewY & iX<=(viewX+TheBitmap.getWidth()) & iY<=(viewY+TheBitmap.getHeight())) {     
       if (TheBitmap.getPixel(iX,iY)!=0) { 
        onStartCallButtonClicked(v); 
        showPressedState(); 
        return false; 
       } 
      } 
      break; 
     case MotionEvent.ACTION_UP: 
     case MotionEvent.ACTION_CANCEL: 
      showNormalState(); 
      break; 
    }   
    return true; 
} 

private void showNormalState() { 
    // set your button background drawable to show normal state 
} 

private void showPressedState() { 
    // set your button background drawable to show pressed state 
}