Подтвердить что ты не робот

Кнопка пользовательской формы Android

Как я могу создать настраиваемый клик для просмотра или кнопку в Android?

Когда я нажимаю, я хочу не касаться пустой области.

enter image description here

пожалуйста, помогите. Спасибо.

4b9b3361

Ответ 1

Интересный вопрос. Я попробовал некоторые решения, и это то, что я обнаружил, что имеет тот же результат, которого вы пытаетесь достичь. Решение ниже решает две проблемы:

  • Пользовательская форма, представленная вами.
  • Верхнюю правую часть кнопки нельзя кликать.

Итак, это решение в 3 этапа:

Шаг 1

Создайте две фигуры.

  • Первая простая форма прямоугольника для кнопки: shape_button_beer.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <gradient
            android:angle="90"
            android:endColor="#C5D9F4"
            android:startColor="#DCE5FD" />
    
        <corners
            android:bottomLeftRadius="5dp"
            android:bottomRightRadius="5dp"
            android:topLeftRadius="5dp" >
        </corners>
    
    </shape>
    
  • Вторая форма используется в качестве маски для верхней правой части кнопки: shape_button_beer_mask.xml. Это простой круг с черным сплошным цветом.

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="oval" >
    
        <solid android:color="#000000" />
    
    </shape>
    

Шаг 2

В вашем основном макете добавьте кнопку следующим путем:

  • RelativeLayout - это контейнер этой настраиваемой кнопки
  • Первая LinearLayout - это синяя кнопка с пивным значком и текстом внутри
  • Второй ImageView - это маска над синей кнопкой. И вот идет грязный трюк:
    • Поля отрицательные, чтобы установить маску в нужном месте.
    • Мы определяем id для возможности переопределения при щелчке (см. шаг 3)
    • android:soundEffectsEnabled="false" - так, что пользователь не почувствует, что он что-то нажал.

XML:

    <!-- Custom Button -->
    <RelativeLayout
        android:layout_width="120dp"
        android:layout_height="80dp" >

        <LinearLayout
            android:id="@+id/custom_buttom"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="@drawable/shape_button_beer" >

            <!-- Beer icon and all other stuff -->

            <ImageView
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:layout_marginLeft="5dp"
                android:layout_marginTop="15dp"
                android:src="@drawable/beer_icon" />
        </LinearLayout>

        <ImageView
            android:id="@+id/do_nothing"
            android:layout_width="120dp"
            android:layout_height="100dp"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_marginRight="-50dp"
            android:layout_marginTop="-50dp"
            android:background="@drawable/shape_button_beer_mask"
            android:soundEffectsEnabled="false" >
        </ImageView>
    </RelativeLayout>
    <!-- End Custom Button -->

Шаг 3

В вашей основной деятельности вы определяете события click для обеих: кнопки и маски следующим образом:

LinearLayout customButton = (LinearLayout) findViewById(R.id.custom_buttom);
customButton.setOnClickListener(new View.OnClickListener()
{
    @Override
    public void onClick(View arg0)
    {
        Toast.makeText(getApplicationContext(), "Clicked", Toast.LENGTH_SHORT).show();
    }
});

// Mask on click will do nothing
ImageView doNothing = (ImageView) findViewById(R.id.do_nothing);
doNothing.setOnClickListener(new View.OnClickListener()
{
    @Override
    public void onClick(View arg0)
    {
        // DO NOTHING
    }
});

Что это. Я знаю, что это не идеальное решение, но в описанном вами случае использования он может помочь. Я тестировал его на своем мобильном устройстве, и это выглядит так, когда вы нажимаете на синюю область, и ничего не произойдет в других областях:

  • enter image description here

Надеюсь, это помогло как-то:)

Ответ 2

Используйте OnTouch вместо OnClick и проверьте альфа-значение изображения, которое вы использовали в кнопке. Если оно не равно нулю, сделайте все, что захотите. Проверьте следующий код,

final Bitmap bitmap;  //Declare bitmap     
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.TheImage);


public boolean onTouch(View v, MotionEvent event) {

        int eventPadTouch = event.getAction();
        float iX=event.getX();
    float iY=event.getY();

        switch (eventPadTouch) {

            case MotionEvent.ACTION_DOWN:
                if (iX>=0 & iY>=0 & iX<bitmap.getWidth() & iY<bitmap.getHeight()) { //Makes sure that X and Y are not less than 0, and no more than the height and width of the image.                
                    if (bitmap.getPixel((int) iX, (int) iY)!=0) {
                        // actual image area is clicked(alpha not equal to 0), do something 
                    }               
                }
                return true;                
        }           
        return false;
}

Ответ 3

используйте список слоев, вы можете создать любую фигуру любой вершины кнопки градиента вот пример

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle">
            <corners

                android:topLeftRadius="0dp"
                android:topRightRadius="0dp"
                android:bottomLeftRadius="2dp"
                android:bottomRightRadius="15dp"
                />            
            <!-- The border color -->
            <solid android:color="#ffffff" />
        </shape>
    </item>

    <item android:right="2dp"
        android:left="2dp"
        android:bottom="2dp">
            <shape>            
            <gradient                
                android:startColor="#002a36"
                android:centerColor="#457c8e"
                android:endColor="#e6ffff"               
                android:angle="90" 
                  android:centerY="1"
                android:centerX="0.5"           
                />          

            <corners

                android:topLeftRadius="0dp"
                android:topRightRadius="0dp"
                android:bottomLeftRadius="2dp"
                android:bottomRightRadius="15dp"
                />            
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" 
                />                        
        </shape>
    </item>
</layer-list> 

используйте значения радиуса -ve, чтобы сделать форму кнопки, как указано выше.

Ответ 4

u может попробовать следующее:

        <Button
        android:id="@+id/logout"
        android:layout_width="240dp"
        android:layout_height="28dp"
        android:layout_weight="1"
        android:gravity="center"
        android:text="ContactsDetails"
        android:textColor="#ffffff" android:layout_marginLeft="50dp" android:background="@drawable/round"/>

и создайте файл round.xml в папке с возможностью переноса:

        <?xml version="1.0" encoding="utf-8"?>
      <shape xmlns:android="http://schemas.android.com/apk/res/android"
      android:shape="rectangle" android:padding="0dp" android:useLevel = "false">
    <!-- you can use any color you want I used here gray color-->
     <solid android:color="#ABABAB"/> 
       <corners
       android:bottomRightRadius="0dp"
         android:bottomLeftRadius="0dp"
       android:topLeftRadius="0dp"
      android:topRightRadius="70dp"/>
       </shape>

Ответ 5

У меня была аналогичная проблема, но я не хотел зависеть от кода, чтобы изучить значение пикселя. Мне нужен простой способ (а не перегрузка классов), чтобы ограничить событие касания только вспомогательной частью drawable. Ниже я использую LinearLayout для рисования, а затем внутри, где я помещаю прозрачную кнопку (с текстом). Я могу отрегулировать край кнопки, чтобы поместить область, на которую можно щелкнуть.

    <LinearLayout
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:background="@drawable/circle">
        <Button
            android:layout_height="match_parent"
            android:layout_width="match_parent"
            android:id="@+id/btnTimer1"
            android:text="0:00"
            android:textColor="#ffffff"
            android:textSize="22dp"
            android:layout_margin="20dp"
            android:background="@android:color/transparent"/>
    </LinearLayout>

Ответ 6

Самое лучшее и простое решение (as4me) Я нашел здесь - это подклассифицированная кнопка и, следовательно, она поддерживает селектор. Итак, все, что вам нужно сделать, это рисовать/добавлять соответствующие png для каждого состояния кнопки, чтобы использовать селектор и объявлять onClick в xml или добавлять OnClickListener в код, и вы готовы к работе.

Ответ 7

Вместо того, чтобы делать все эти изменения, вы должны использовать рамочную компоновку на части, которая окружает кнопку, и замаскировать верхнюю правую часть с помощью какой-либо вещи (круговой, как закругленная кнопка) и не назначать прослушиватель кликов на этой части. Это фактически скрывает нижний фрейм (т.е. Исходную кнопку) и маскирует его с помощью неактивной части.

Ответ 8

Я попробовал ответить @Basim Sherif (ссылка), и он отлично работает, только если размер кнопки совпадает с исходным изображением. Если кнопка была растянута, зона с клики будет меньше, и если бы кнопка была установлена ​​на меньший размер, область с клики будет больше, чем фактическая кнопка.

Решение простое, чтобы масштабировать значения iX и iY в соответствии с исходным растровым изображением.

И вот моя модифицированная версия кода:

final Bitmap bitmap;  //Declare bitmap     
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.TheImage);

public boolean onTouch(View v, MotionEvent event) {

    int eventPadTouch = event.getAction();
    float iX=event.getX();
    float iY=event.getY();

    // Get the dimensions used in the view
    int realW = this.getWidth();
    int realH = this.getHeight();

    // Get the dimensions of the actual image
    int bitmapW = bitmap.getWidth();
    int bitmapH = bitmap.getHeight();

    // Scale the coordinates from the view to match the actual image
    float scaledX = iX * bitmapW / realW;
    float scaledY = iY * bitmapH / realH;

    switch (eventPadTouch) {
        case MotionEvent.ACTION_DOWN:
            if (scaledX >= 0 & scaledY >= 0 & scaledX < bitmap.getWidth() & scaledY < bitmap.getHeight()) { //Makes sure that X and Y are not less than 0, and no more than the height and width of the image.                
                if (bitmap.getPixel((int) scaledX, (int) scaledY)!=0) {
                    // actual image area is clicked(alpha not equal to 0), do something 
                }
            }
            return true;
    }
    return false;
}