बिना स्केलिंग बैकग्राउंड के एंड्रॉइड बटन के हिट एरिया को कैसे बढ़ाएं?


82

मेरे पास एक कस्टम ड्रॉबल वाला बटन है।

<Button
    android:layout_width="22dip"
    android:layout_height="23dip"
    android:background="@drawable/triangle" />

ड्रॉबल पारदर्शी पृष्ठभूमि वाला एक त्रिकोण है।

|\
| \
|__\

मुझे यह बटन टैप करने में मुश्किल लगता है। सबसे पहले, यह अपेक्षाकृत छोटा है। दूसरा, पारदर्शी पिक्सेल टॅपेबल नहीं हैं। मैं ड्रॉबल को एक ही आकार में रखना चाहता हूं, लेकिन हिट क्षेत्र को त्रिकोण के आकार से दो गुना अधिक चौकोर आकार देता हूं।

_____________
|            |
|    |\      |
|    | \     |
|    |__\    |
|____________|

1
मार्जिन ने हिट क्षेत्र को भी नहीं बढ़ाया।
— जोजो

पैडिंग का उपयोग करके देखें। यह निश्चित रूप से काम करेगा।
— अर्जुन व्यास 11

जवाबों:


68

आप टचडेलगेट एपीआई का उपयोग कर सकते हैं।

final View parent = (View) button.getParent();  // button: the view you want to enlarge hit area
parent.post( new Runnable() {
    public void run() { 
        final Rect rect = new Rect(); 
        button.getHitRect(rect); 
        rect.top -= 100;    // increase top hit area
        rect.left -= 100;   // increase left hit area
        rect.bottom += 100; // increase bottom hit area           
        rect.right += 100;  // increase right hit area
        parent.setTouchDelegate( new TouchDelegate( rect , button)); 
    } 
}); 

1
यहाँ मान लेने के लिए कोई मूल्य कैसे निर्धारित किया जाता है? button.getHitRect (rect) का कोई रिटर्न मान नहीं है!
— १।

@ amitav13 rectको एक पैरामीटर के रूप में पारित किया जा रहा है।
— not_again_stackoverflow

हे, आपके उपयोग के 100 मूल्य, क्या यह एक dp मूल्य होना चाहिए जो मुझे आयाम फ़ोल्डर से मिलता है? क्या घनत्व के आधार पर मूल्य में परिवर्तन का मूल्य सही होगा?
— j2emanue

@ j2emanue यह सही है। तुम भी प्रोग्राम के यह गणना कर सकते हैं stackoverflow.com/a/8399445/2523667
— निकोलस

45

आप "पैडिंग" चाहते हैं यह अंतरिक्ष को दृश्य के अंदर रखेगा। मार्जिन बाहर की जगह लगाएगा, जिससे हिट एरिया नहीं बढ़ेगा।

 <Button
    android:layout_width="22dip"
    android:layout_height="23dip"
    android:background="@drawable/triangle"
    android:padding="10dp" />

मैंने डिवाइस और एमुलेटर पर यहां परीक्षण किया, यह काम नहीं करता है। क्या आपने इसका परीक्षण किया है?
— लियांगवांग

18
पैडिंग को लेआउट के अंदर जोड़ा जाता है। इस प्रकार यह बटन अभी भी 22x23 बड़ा है। तो यह कोई मदद नहीं करता है।
— साइमन वार्टा

1
यह बहुत अच्छा काम करता है। पैडिंग ने टेप किए गए क्षेत्र को वांछित के रूप में विस्तारित किया और मेरी छवि को उसी आकार में छोड़ दिया, जैसा कि जोजो (मूल लेखक) ने पूछा था।
— एल्योसक

यह उत्तर इतने सारे उत्थान को क्यों मिला, यह स्पष्ट है कि सीमाओं के अंदर पैडिंग सामग्री बाहर नहीं है ?!
— फरीद

1
मेरी पिछली टिप्पणी के बाद, मुझे लगता है कि इससे पृष्ठभूमि भी बढ़ेगी। यदि हां, तो शायद आप पृष्ठभूमि को "इनसेट" ड्रॉबल के अंदर रख सकते हैं। पुनश्च। मैं टचडेलगेट की तुलना में इसे पसंद करता हूं, क्योंकि टचडेलगेट को पूर्वज के साथ खिलवाड़ करने की जरूरत है और यह अधिक जटिल हो जाता है अगर बच्चे का दृश्य बढ़ रहा हो ...
— हेनरी

24

आपको TouchDelegateएपीआई डॉक्स में "उन स्थितियों को संभालने के लिए हेल्पर क्लास के रूप में परिभाषित किया गया है, जहां आपको अपने वास्तविक दृश्य सीमा की तुलना में एक बड़ा स्पर्श क्षेत्र का दृश्य चाहिए"

http://developer.android.com/reference/android/view/TouchDelegate.html


@ mxcl, मुझे आपकी टिप्पणी में ऐसा कुछ भी नहीं दिख रहा है जो इस उत्तर को अमान्य या "गलत" करार दे।
— dbm

7
के बारे में TouchDelegateऔर एक स्निपेट कोड: डेवलपर.
— android.com/training/gestures/viewgroup.html#delegate

16

मैं इस समाधान को पसंद करता हूं:

बस एक सकारात्मक पैडिंग और लेआउट संसाधन फ़ाइल के अंदर एक नकारात्मक मार्जिंग जोड़ें:

<some.View
  ..
  android:padding="12dp"
  android:margin="-12dp"
  .. />

यह टचडेलगेट्स के उपयोग की तुलना में बहुत छोटा बदलाव है। मैं अपने जावा कोड के अंदर क्लिक करने योग्य क्षेत्र को जोड़ने के लिए एक रननेबल भी नहीं चलाना चाहता।

एक बात जिस पर आप विचार कर सकते हैं यदि पिक्सेल पिक्सेल-पूर्ण होनी चाहिए: पैडिंग हमेशा मार्जिन के बराबर नहीं हो सकती है । गद्दी हमेशा वास्तव में निर्दिष्ट के रूप में होना चाहिए। मार्जिन आसपास के विचारों पर निर्भर करता है और साथ ऑफसेट किया जाएगा मार्जिन अन्य दृश्यों के मूल्यों।


यह एक प्यार करता था: डी
— आयमान सलाह

यह काम नहीं कर सका। मेरे पास रैखिकलेयआउट में एक-दूसरे के बगल में दो पाठ हैं और चाहते हैं कि दाहिना हाथ एक स्पर्श योग्य क्षेत्र को पाठ की तुलना में थोड़ा बड़ा हो ... लेकिन इन 2 अतिरिक्त लाइनों का उपयोग करने से मेरा पाठ ऑफसेट हो जाता है जो कि मैं नहीं दिख रहा हूं के लिए जा रहा है
— किब्बी

@ किबी को एक दृश्य (यहां TextView) को एक में शामिल LinearLayoutनहीं करना चाहिए। फिर भी, क्या आपने इन दो पंक्तियों को अपने में जोड़ने की कोशिश की है LinearLayout? जैसा कि पहले कहा गया है कि मार्जिन आसपास के विचारों पर निर्भर करता है।
— तिमो बेहर

धन्यवाद @ TimoBähr लेकिन (शुरू में) मैं नहीं चाहता था कि पूरा लिनलेयआउट क्लिक करने योग्य हो, क्योंकि बाईं तरफ का पाठ क्लिकबेलर नहीं होना चाहिए था ... अंत में मैंने jsut jave up और mad पूरे LinearLayout को क्लिक करने योग्य और निश्चित रूप से पागल कर दिया काम करता है।
— किबी सेप

8

उत्तर के आधार पर मैंने इसके साथ मदद करने के लिए एक कोटलिन एक्सटेंशन फ़ंक्शन बनाया।

/**
 * Increase the click area of this view
 */
fun View.increaseHitArea(dp: Float) {
    // increase the hit area
    val increasedArea = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().displayMetrics).toInt()
    val parent = parent as View
    parent.post {
        val rect = Rect()
        getHitRect(rect)
        rect.top -= increasedArea
        rect.left -= increasedArea
        rect.bottom += increasedArea
        rect.right += increasedArea
        parent.touchDelegate = TouchDelegate(rect, this)
    }
}


6

बस बटन में पैडिंग जोड़कर

 <Button
android:layout_width="wrap_contant"
android:layout_height="wrap_contant"
android:background="@drawable/triangle"
android:padding="20dp" />

तो ऐसा करने से .. आपका बटन त्रिकोण छवि की ऊँचाई और चौड़ाई ले लेगा और छवि को खींचे बिना बटन में 20dp पैडिंग जोड़ देगा। और यदि आप कुछ न्यूनतम चौड़ाई या कुछ उच्च ऊंचाई चाहते हैं तो आप minWidthऔर minHeightटैग का उपयोग कर सकते हैं


5

मामले में आप डेटा बाइंडिंग का उपयोग कर रहे हैं। आप बाइंडिंग एडाप्टर का उपयोग कर सकते हैं।

@BindingAdapter("increaseTouch")
fun increaseTouch(view: View, value: Float) {
    val parent = view.parent
    (parent as View).post({
        val rect = Rect()
        view.getHitRect(rect)
        val intValue = value.toInt()
        rect.top -= intValue    // increase top hit area
        rect.left -= intValue   // increase left hit area
        rect.bottom += intValue // increase bottom hit area
        rect.right += intValue  // increase right hit area
        parent.setTouchDelegate(TouchDelegate(rect, view));
    });
}

और फिर आप इस तरह के विचारों पर विशेषता का उपयोग कर सकते हैं

increaseTouch="@{8dp}"

2

मुझे पक्का पता नहीं है कि आपके द्वारा "बैकग्राउंड ड्रॉबल को बढ़ाए बिना" का क्या मतलब है। अगर आपका मतलब है कि आप अपने ड्रॉबल को लंबा नहीं खींचना चाहते हैं, तो आपके पास एक विकल्प यह है कि आप अपने बैकग्राउंड पींग को लें और उस पर एक अतिरिक्त पारदर्शी पिक्सेल बॉर्डर जोड़ें। यह आपके हिट जोन को बढ़ाएगा लेकिन आपकी छवि को नहीं बढ़ाएगा।

हालांकि अगर आपका मतलब है कि आप उस आकर्षित को बिल्कुल बदलना नहीं चाहते हैं, तो मुझे लगता है कि आपका एकमात्र विकल्प ऊंचाई और चौड़ाई के लिए बड़े कठिन कोडित मूल्यों का उपयोग करना है।


मेरे कहने का मतलब यह है कि मुझे X द्वारा Y दिखाई देने के लिए बटन ग्राफ़िक की आवश्यकता है लेकिन हिट क्षेत्र X + 10 द्वारा Y + 10 है। मुझे नहीं लगता कि पारदर्शी पिक्सेल हिट क्षेत्र में जुड़ते हैं। मेरा ग्राफिक एक त्रिकोणीय आकार है। जब मैं पारदर्शी क्षेत्रों पर टैप करता हूं, तो ऑनक्लिक ट्रिगर नहीं होता है।
— जोजो

मुझे पता है कि पृष्ठभूमि img में पारदर्शी पिक्सल हिट क्षेत्र में जोड़ देगा। मैंने अदृश्य बटन बनाने से पहले इसका उपयोग किया है। शायद यह आकार नहीं जोड़ रहा है क्योंकि आपने ऊँचाई और चौड़ाई को कठोर रूप से कोडित किया है? शायद उन लोगों के लिए wra_content कोशिश करें।
— FoamyGuy

यह बहुत अजीब है। मैंने परीक्षण के लिए अपनी पूरी स्क्रीन को भरने के लिए बटन को उड़ा दिया। जब मैं अपारदर्शी पिक्सेल को टैप करता हूं, तो LogCat मेरे ऑनक्लिक लॉग को प्रिंट करता है। जब मैं पारदर्शी क्षेत्रों को टैप करता हूं, तो यह रजिस्टर नहीं होता है।
— जोजो

इसके अलावा, यदि आप स्क्रीन पर बहुत अधिक दबाव डालते हैं जैसे कि आपकी उंगली की सतह का क्षेत्र बटन की तुलना में अधिक है, तो ऑनक्लिक ट्रिगर नहीं करता है। मुझे जिंजली बटन पर टैप करना होगा ताकि ऑनक्लिक पर ट्रिगर किया जा सके। क्या कोई ऐसी संपत्ति है जो इस "फैट फिंगर सिंड्रोम" को समायोजित करती है?
— जोजो

2

इसके साथ प्रयास करें

  <Button
        android:id="@+id/btn_profile"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentLeft="true"
        android:background="@android:color/transparent"
        android:drawableBottom="@drawable/moreoptionicon"
        android:onClick="click"
        android:paddingBottom="15dp"
        android:visibility="visible" />

इस विचारधारा को पसंद किया .. स्वच्छ .. सरल .. आप केंद्र में फिट होने के लिए पैडिंग और आकर्षित करने के साथ काम कर सकते हैं .. अच्छा ..
— गुइलहर्मे ओलिवेरा

1

देखें Can मैं प्रोग्राम के रूप में एक बटन onclick-क्षेत्र में वृद्धि? । यह सुनिश्चित करने के लिए मेरे लिए सबसे आसान तरीका है। यहां तक ​​कि पृष्ठभूमि को क्लिक प्राप्त करने की अनुमति देते समय केवल वास्तविक क्लिक करने योग्य वस्तु को एनिमेट करने पर थोड़ा सा भी शामिल है। मैं इसे जल्द ही अपने कोड में लागू करूंगा।


1

यह मेरे लिए काम किया:

public void getHitRect(Rect outRect) {
    outRect.set(getLeft(), getTop(), getRight(), getBottom() + 30);
}

हालाँकि वास्तव में आपको बटन की ऊँचाई का कुछ प्रतिशत घटने या करने के लिए 30 को परिवर्तित करना चाहिए।


स्पष्टीकरण चाहिए। ओपी ने एक बटन के लिए लेआउट xml का एक स्निपेट पोस्ट किया (जो कुछ दृश्य के लेआउट xml का हिस्सा होगा)। लेकिन मैं मानता हूं कि उपरोक्त विधि को बटन के साथ जुड़ा होना चाहिए, न कि उस दृश्य वर्ग के साथ जिसमें बटन होता है? आप उस बटन के साथ उपरोक्त विधि को कैसे जोड़ते हैं?
— टूलमेकरसैट

1

मुझे बस वही चाहिए: बटन की छवि से बड़ा क्लिक करने योग्य क्षेत्र। मैंने इसे फ्रेमलेयआउट में बैकग्राउंड ड्रॉएबल से बड़ा किया और इनर बटन टैग को टेक्स्ट व्यू में बदल दिया। से पहले मैंने इस फ़्रेमलेआउट के साथ काम करने के लिए एक क्लिक हैंडलर को निर्देशित किया, न कि आंतरिक टेक्स्ट व्यू के साथ। सभी अच्छी तरह से काम करता है!


भयानक होने के बावजूद, यह सबसे अच्छा समाधान एंड्रॉइड ऑफर है।
— आई_म_जॉर्फ़

1

आप इस तरह पारदर्शी बटन का उपयोग कर सकते हैं ...

<Button
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:background="@android:color/transparent" /> 

आप अपनी आवश्यकता के अनुसार बटन का आकार बढ़ा या घटा सकते हैं और एक enter code hereImageView बटन का उपयोग कर सकते हैं ...।

<ImageView
    android:layout_width="22dip"
    android:layout_height="23dip"
    android:background="@drawable/triangle" />

1

मैंने कोटलिन में इसके लिए शीर्ष-स्तरीय समारोह बनाया:

fun increaseTouchArea(view: View, increaseBy: Int) {
    val rect = Rect()
    view.getHitRect(rect)
    rect.top -= increaseBy    // increase top hit area
    rect.left -= increaseBy   // increase left hit area
    rect.bottom += increaseBy // increase bottom hit area
    rect.right += increaseBy  // increase right hit area
    view.touchDelegate = TouchDelegate(rect, view)
}

2
आप Viewइसके बजाय विस्तार समारोह बना सकते हैं
— वादिम कोटोव

0

इस उद्देश्य के लिए मैं ImageButton का उपयोग कर रहा था। Xml डिफेंसेशन में आप इन दो विशेषताओं को देखेंगे:

  • Android: बैकग्राउंड - बैकग्राउंड के रूप में उपयोग करने योग्य।
  • android: scr - इस ImageView की सामग्री के रूप में एक ड्रॉबल सेट करता है।

तो हमारे पास दो ड्रॉबल्स हैं: बैकग्राउंड वन और सोर्स। आप उदाहरण के स्रोत में त्रिभुज (ड्रॉएबल / ट्रायंगल) होंगे:

|\
| \
|__\

और बैकग्राउंड चौकोर है (ड्रॉएबल / स्क्वायर):

_____________
|            |
|            |
|            |
|            |
|____________|

यहाँ ImageButton xml का उदाहरण दिया गया है:

<ImageButton
   ...
   android:src="@drawable/triangle"
   android:background="@drawable/square">

परिणाम:

_____________
|            |
|    |\      |
|    | \     |
|    |__\    |
|____________|

इसके अलावा वर्गाकार, कई अलग-अलग राज्यों (दबाया, केंद्रित) हो सकता है। और आप पैडिंग का उपयोग करके बैकग्राउड ड्रॉएबल आकार का विस्तार कर सकते हैं।

बस मामले में, यहाँ Android संगत Actionbar से पृष्ठभूमि के लिए उदाहरण दिया गया है:

<?xml version="1.0" encoding="utf-8"?>    
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
    <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/abc_list_selector_disabled_holo_dark" />
    <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/abc_list_selector_disabled_holo_dark" />
    <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/abc_list_selector_background_transition_holo_dark" />
    <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/abc_list_selector_background_transition_holo_dark" />
    <item android:state_focused="true" android:drawable="@drawable/abc_list_focused_holo" />
    <item android:drawable="@android:color/transparent" />
 </selector>

किसी कारण से मेरे src का उपयोग नहीं किया जा रहा है, भले ही पृष्ठभूमि सिर्फ पारदर्शी हो।
— MLProgrammer-CiM

0

आप पैडिंग को व्यू यानि अपने बटन पर सेट कर सकते हैं।

<Button
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/transparent"
        android:padding="15dp" />

उम्मीद है इससे आपका काम बनेगा।


0

तो सही जवाब, टाउचेबल क्षेत्र में पैडिंग को बड़ा करें और अपनी तस्वीर को पृष्ठभूमि से srcCompact में बदलें ।

<Button
    android:layout_width="22dip"
    android:layout_height="23dip"
    android:padding="6dp"
    app:srcCompat="@drawable/triangle"/>

एप्लिकेशन का उपयोग करने के लिए: xCom में आपको xmlns:app="http://schemas.android.com/apk/res-auto"अपने मुख्य / मूल तत्व को जोड़ने की आवश्यकता है ।

उदाहरण पूरा:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/height_btn_bottom_touch_area"
android:background="@color/bg_white"
android:clipToPadding="false"
android:elevation="7dp">

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:stateListAnimator="@animator/selected_raise"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" >

    <ImageView
        android:id="@+id/bottom_button_bg"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:contentDescription=
            "@string/service_request_background_contentDescription"
        android:elevation="1dp"
        android:padding="6dp"
        app:srcCompat="@drawable/btn_round_blue"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" >
    </ImageView>

    <TextView
        android:id="@+id/bottom_button_text"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:elevation="1dp"
        android:gravity="center"
        android:text="@string/str_continue_save"
        android:textColor="@color/text_white"
        android:textSize="@dimen/size_text_title"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>

0

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

<CheckBox
        android:id="@+id/checkbox"
        android:layout_width="30dp"
        android:layout_height="45dp"
        android:paddingLeft="15dp"
        android:paddingTop="15dp"
        android:paddingBottom="15dp"
        android:button="@drawable/checkbox"
        android:checked="false"
        android:gravity="center"
       />

0

मुझे लगता है कि सही उत्तर को बटन के बजाय इमेजबटन का उपयोग करना चाहिए। त्रिकोण ड्राअबल को इमेजबटन के "src" के रूप में सेट करें, और आकार (लेआउट_प्रकार और लेआउट_हाइट) सेट करें जैसा कि आप आसान स्पर्श के लिए चाहते हैं और त्रिकोण आकार को बनाए रखने के लिए स्केलटेप को केंद्र में सेट करें।


0

मैं ईमानदारी से लगता है कि यह सबसे आसान तरीका है: -

मान लें कि आपकी छवि का आकार 26dp * 26dp है और आप 30dp * 30dp का हिट क्षेत्र चाहते हैं, बस अपने ImageButton / बटन में 2dp का एक पैडिंग जोड़ें और 30dp * 30dp पर आयाम सेट करें


मूल

<ImageButton
    android:layout_width="26dp"
    android:layout_height="26dp"
    android:src="@drawable/icon"/>

बड़ा हिट इलाका

<ImageButton
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:padding="2dp"
    android:src="@drawable/icon_transcript"/>

0

सरलतम उपाय width and heightआपके आइटम (जैसे छवि, बटन आदि) की वृद्धि और जोड़ देगा padding; तो क्लिक करने योग्य क्षेत्र बड़ा है, लेकिन मूल आकार में दिखता है।

उदाहरण:

<Button
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:padding="8dp"
    android:background="@drawable/triangle" />

बधाई हो, आपने एक ही बटन का आकार हासिल किया, लेकिन क्लिक करने योग्य आकार को दोगुना कर दिया!

_____________
|            |
|    |\      |
|    | \     |
|    |__\    |
|____________|

-2
<Button
    android:layout_width="32dp"
    android:layout_height="36dp"
    android:layout_margin="5dp"
    android:background="@drawable/foo" 
/>

पृष्ठभूमि का आकार अभी भी 22x26dp है। बस मार्जिन जोड़ें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.