2012-07-01 15 views
7

किसी भी आकार (या तो भरे सर्कल, स्टार, त्रिकोण, पारदर्शी क्षेत्रों के साथ बिटमैप, आदि) को देखते हुए मैं जानना चाहता हूं कि यह संभव है (नवीनतम एंड्रॉइड एपीआई का उपयोग करके) यह जानने के लिए कि उपयोगकर्ता ने क्लिक किया है या नहीं दृश्य पर, या इसके बाहर।बटन का वास्तविक कस्टम आकार

उदाहरण के लिए, यदि मेरे पास एक गोलाकार बटन है, तो मैं जानना चाहता हूं कि उपयोगकर्ता ने सर्कल के अंदर क्लिक किया है, लेकिन इसके बाहर नहीं।

क्या यह संभव है?

यदि नहीं, तो शायद मैं स्पर्श ईवेंट के पिक्सेल को मतदान कर सकता हूं, और यदि यह पारदर्शी है, तो इसे अनदेखा करें, और यदि ऐसा नहीं है, तो इसे एक क्लिक ईवेंट के रूप में संभाल लें?

उत्तर

1

ठीक है, मुझे किसी भी प्रकार के दृश्य के लिए एक समाधान समाधान मिला है।

कुछ नोट:

  • उदासी यह देखने के आकार का एक बिटमैप का उपयोग करता है, लेकिन केवल समय की एक छोटी राशि के लिए।

    उसके बाद, यह उस स्थान पर है जहां इसे दृश्य क्षेत्र पर माना जाता है और जहां इसे दृश्य क्षेत्र के बाहर माना जाता है।

  • मैं इसे पूर्णांक की सरणी बनाकर अधिक मेमोरी दोस्ताना बना सकता हूं, जिसमें झंडे हैं। वर्तमान में यह एक साधारण बुलियन सरणी है।

  • मैं इसके बजाय जेएनआई में बिटमैप के अल्फा मानों की जांच कर सकता हूं, और (संक्षिप्त) समय से बचने के लिए जहां मेरे पास बिटमैप और सरणी दोनों एक साथ हैं।

  • यदि कोई इसे बेहतर बनाने में मदद कर सकता है, तो यह वास्तव में बहुत अच्छा हो सकता है।

    public class MainActivity extends Activity 
        { 
        boolean[] _inVisibleAreaMap; 
        private int _width,_height; 
    
        @Override 
        protected void onCreate(final Bundle savedInstanceState) 
        { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
        final View view=findViewById(R.id.imageView1); 
        view.setDrawingCacheEnabled(true); 
        runJustBeforeBeingDrawn(view,new Runnable() 
         { 
         @Override 
         public void run() 
          { 
          final Bitmap bitmap=view.getDrawingCache(); 
          _width=bitmap.getWidth(); 
          _height=bitmap.getHeight(); 
          _inVisibleAreaMap=new boolean[_width*_height]; 
          for(int y=0;y<_width;++y) 
          for(int x=0;x<_height;++x) 
           _inVisibleAreaMap[y*_width+x]=Color.alpha(bitmap.getPixel(x,y))!=0; 
          view.setDrawingCacheEnabled(false); 
          bitmap.recycle(); 
          } 
         }); 
        view.setOnTouchListener(new OnTouchListener() 
         { 
         @Override 
         public boolean onTouch(final View v,final MotionEvent event) 
          { 
          final int x=(int)event.getX(),y=(int)event.getY(); 
          boolean isIn=x>=0&&y>=0&&x<_width&&y<_height; 
          // if inside bounding box , check if in the visibile area 
          if(isIn) 
          isIn=_inVisibleAreaMap[y*_width+x]; 
          if(isIn) 
          Log.d("DEBUG","in"); 
          else Log.d("DEBUG","out"); 
          return true; 
          } 
         }); 
        } 
    
        private static void runJustBeforeBeingDrawn(final View view,final Runnable runnable) 
        { 
        final ViewTreeObserver vto=view.getViewTreeObserver(); 
        final OnPreDrawListener preDrawListener=new OnPreDrawListener() 
         { 
         @Override 
         public boolean onPreDraw() 
          { 
          runnable.run(); 
          final ViewTreeObserver vto=view.getViewTreeObserver(); 
          vto.removeOnPreDrawListener(this); 
          return true; 
          } 
         }; 
        vto.addOnPreDrawListener(preDrawListener); 
        } 
        } 
    

    मामले में imageView इसकी चौड़ाई & ऊंचाई wrap_content करने के लिए सेट किया गया है, और यह वास्तव में आकार इसकी आवश्यकता है, तो ही आप Adnan Zahid solution उपयोग कर सकते हैं, जो हो सकता है:

यहाँ कोड है इस तरह लिखा:

public class MainActivity extends Activity 
    { 
    private int _width,_height; 

    @Override 
    protected void onCreate(final Bundle savedInstanceState) 
    { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    final ImageView image=(ImageView)findViewById(R.id.imageView1); 
    final Bitmap bitmap=((BitmapDrawable)image.getDrawable()).getBitmap(); 
    _width=bitmap.getWidth(); 
    _height=bitmap.getHeight(); 
    image.setOnTouchListener(new OnTouchListener() 
     { 
     @Override 
     public boolean onTouch(final View v,final MotionEvent event) 
      { 
      final int x=(int)event.getX(),y=(int)event.getY(); 
      boolean isIn=x>=0&&y>=0&&x<_width&&y<_height; 
      if(isIn) 
      { 
      final int pixel=bitmap.getPixel((int)event.getX(),(int)event.getY()); 
      final int alphaValue=Color.alpha(pixel); 
      isIn=alphaValue!=0; 
      } 
      if(isIn) 
      Log.d("DEBUG","in"); 
      else Log.d("DEBUG","out"); 
      return true; 
      } 
     }); 
    } 
    } 
2

मैं भी ऐसा कुछ करना चाहता था और मैं फ्रेमलेआउट के साथ tweaking समाप्त हो गया। फ्रेमलेआउट आपको एक-दूसरे के शीर्ष पर कई दृश्य जोड़ने की अनुमति देता है।

फ़्रेमलेआउट जोड़ें। अंदर आप एक 'व्यू' जोड़ सकते हैं और इसकी ऊंचाई और चौड़ाई match_parent पर सेट कर सकते हैं। दृश्य के शीर्ष पर, इच्छित बटन जोड़ें।

फिर अपने कोड में, दृश्य का संदर्भ प्राप्त करें और उस पर क्लिक करें क्लिक करें ताकि जब भी उपयोगकर्ता उस दृश्य को छूता है, तो आप उस ईवेंट को संभाल सकते हैं। अन्य बटनों पर श्रोताओं को भी क्लिक करें।

अब बस अपनी स्पर्श घटनाओं को संभाल लें। अब आप जान लेंगे कि उपयोगकर्ता ने बटन पर या उसके बाहर क्लिक किया है (उपयोगकर्ता ने व्यू पर क्लिक किया है)।

यदि आप पारदर्शी या पारदर्शी बटन बनाना चाहते हैं, तो https://stackoverflow.com/a/11689915/1117338 देखें। मुझे उम्मीद है कि यह मदद करता है।

1
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    FrameLayout root = (FrameLayout)findViewById(R.id.root); 
    root.setOnTouchListener(new OnTouchListener() {   
     public boolean onTouch(View v, MotionEvent event) { 
      if (v.getId() == ID){ 
       // Your code 
      } 
      return true; 
     } 
    }); 
} 
8
ImageView image=(ImageView) findViewById(R.id.imageView1); 
image.setOnTouchListener(this); 
Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();  

@Override 
public boolean onTouch(View v, MotionEvent event) { 
    // TODO Auto-generated method stub 
    int pixel = bitmap.getPixel((int)event.getX(), (int)event.getY()); 
    int alphaValue=Color.alpha(pixel); 
    return true; 
} 

इस तरह आप पिक्सेल छुआ के अल्फा मूल्य मिल सकता है। अब आप आसानी से जांच सकते हैं कि पिक्सेल स्पर्श किया गया है या नहीं।

+0

यह वास्तव में आशाजनक लगता है! हालांकि, मैं आपका जवाब टिकने से पहले इसे जांचना होगा। एक समस्या हो सकती है: विभिन्न डिवाइस स्क्रीन (विभिन्न घनत्व/संकल्प) पर क्या होगा? क्या यह अभी भी काम करेगा? भी, क्या यह विधि बिटमैप के लिए इस तरह से अधिक स्मृति का उपयोग करती है? –

+0

भी, क्या यह काम करेगा यदि मैं दृश्य में दिखाए जाने के लिए बिटमैप का उपयोग नहीं करता हूं? –

+0

यदि आप विभिन्न स्क्रीन के लिए डिज़ाइन कर रहे हैं, तो आपको फिर भी टुकड़ों का उपयोग करना होगा। और बिटमैप के लिए, मुझे लगता है कि एक सादे बटन छवि का उपयोग करने से अधिक मेमोरी का उपयोग नहीं होता है क्योंकि इसे अधिक विस्तार से खोए बिना आसानी से स्केल किया जा सकता है। अंत में, हाँ आप drawbitmap विधि का उपयोग कर सकते हैं लेकिन इसके लिए कैनवास की आवश्यकता होगी, इसलिए मैं इसके बजाय एक छविदृश्य का उपयोग करने की अनुशंसा करता हूं। –

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