androidbuttonnumpad

How to increase padding on custom view extending Button without scaling drawable?


I understand that it's easier to set padding without changing drawable size on ImageButton, however I am extending Button for my custom view as I need to override the OnTextChanged method (since Button extends TextView).

I have tried to set the padding programatically also, without success.

Part of my xml below:

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?attr/backgroundColor">

    <TableRow
        android:layout_weight="1"
        android:gravity="center">

        <org.linphone.views.Digit
            android:id="@+id/Digit1"
            style="@style/DialerDigit"
            android:background="@drawable/ws_numpad_1"
            android:soundEffectsEnabled="true"
            android:layout_weight="1"
            android:text="1"/>

        <org.linphone.views.Digit
            android:id="@+id/Digit2"
            style="@style/DialerDigit"
            android:background="@drawable/ic_num2_group"
            android:soundEffectsEnabled="true"
            android:text="2"
            android:layout_weight="1" />

        <org.linphone.views.Digit
            android:id="@+id/Digit3"
            style="@style/DialerDigit"
            android:background="@drawable/ic_num3_group"
            android:soundEffectsEnabled="true"
            android:text="3"
            android:layout_weight="1" />

    </TableRow>

Right now the buttons extend to match parent, but the drawables stretch as well. My aim is to achieve a dialpad similar to the native android one (i.e. where there is no gap in between digits and the numbers on the dialpad don't distort for different screen sizes).

Edit 1 (dialpad image added):

This is the current view of my dialpad

Edit 2 (dialpad listener implementation):

@Override
    protected void onTextChanged(CharSequence text, int start, int before, int after) {
        super.onTextChanged(text, start, before, after);

        if (text == null || text.length() < 1) {
            return;
        }

        DialKeyListener lListener = new DialKeyListener();
        setOnClickListener(lListener);
        setOnTouchListener(lListener);

        // Assign button long clicks here
        if ("0".equals(text.toString())) { // This was 0+, but they were separated, hence
            // changed to 0 only
            setOnLongClickListener(lListener);
        }

        if ("1".equals(text.toString())) {
            setOnLongClickListener(lListener);
        }
    }
private class DialKeyListener implements OnClickListener, OnTouchListener, OnLongClickListener {
        final char mKeyCode;
        boolean mIsDtmfStarted;

        DialKeyListener() {
            mKeyCode = Digit.this.getText().subSequence(0, 1).charAt(0);
        }

        private boolean linphoneServiceReady() {
            if (!LinphoneContext.isReady()) {
                Log.e("[Numpad] Service is not ready while pressing digit");
                return false;
            }
            return true;
        }
   ...
}

Solution

  • Because you are working with a Button custom view and defining a background then the size of the button will be the size of the drawable you put as background.

    Now you can just change your custom view to extend ImageButton and not Button and you'll be able to get it to work like this -

       <TableRow
            android:layout_weight="1"
            android:gravity="center">
    
            <ImageButton
                android:id="@+id/Digit1"
                style="@style/DialerDigit"
                android:layout_weight="1"
                android:background="@android:color/transparent"
                android:src="@drawable/ic_num1_group"
                android:tag="1" />
    
            <ImageButton
                android:id="@+id/Digit2"
                style="@style/DialerDigit"
                android:layout_weight="1"
                android:background="@android:color/transparent"
                android:soundEffectsEnabled="true"
                android:src="@drawable/ic_num2_group"
                android:tag="2" />
    
            <ImageButton
                android:id="@+id/Digit3"
                style="@style/DialerDigit"
                android:layout_weight="1"
                android:background="@android:color/transparent"
                android:soundEffectsEnabled="true"
                android:src="@drawable/ic_num3_group"
                android:tag="3" />
    
        </TableRow>
    

    If you'd like to keep your implementation after changing to ImageButton the only difference will be -

    Instead of initiating the listeners inside the onTextChange callback you can do it in an initListeners() method from the called once the view is created and adds its self the listeners it needs -

    private void initListeners() {
        DialKeyListener lListener = new DialKeyListener();
        setOnClickListener(lListener);
        setOnTouchListener(lListener);
        setOnLongClickListener(lListener);
    
        // Assign button long clicks here
        if (Digit.this.getTag().toString().equals("0")) { 
            setOnLongClickListener(lListener);
        }
    
        if (Digit.this.getTag().toString().equals("1")) {
            setOnLongClickListener(lListener);
        }
    }
    

    And instead of getting the clicked button's number from the text of the button you put in the xml you can use tags exactly the same way.

    I added tags to the xml example above and then once you have the view in the onClick callback you can just use getTag() to see what number it is