Змушення LinearLayout діяти як кнопка


100

У мене є LinearLayoutте, що я створив так, щоб виглядати як button, і він містить кілька елементів text / ImageView. Я хотів би зробити весь LinearLayoutакт схожим на button, зокрема, надати йому констатації, які визначені в так, щоб він мав інше тло при натисканні.

Чи є кращий спосіб, ніж зробити ImageButtonрозмір цілого макета і абсолютно позиціонувати?


У разі , якщо хто - то шукає спосіб , щоб виділити рядок таблиці (яка успадковується від LinearLayout) на пресі (наприклад , кнопки), см stackoverflow.com/a/8204768/427545
Lekensteyn

1
якщо хтось хоче отримати повне рішення, перегляньте це сховище: github.com/shamanland/AndroidLayoutSelector є користувацька можливість натискання / перевірки на LinearLayoutзразокToggleButton
Олексій К.

Відповіді:


154

Я зіткнувся з цією проблемою саме зараз. Вам доведеться встановити LinearLayout таким, що його можна натискати. Ви можете це зробити в XML за допомогою

android:clickable="true"

Або в коді з

yourLinearLayout.setClickable(true);

Ура!


2
Відповідь нижче набагато краща!
Zach Sperske

2
Крім того, якщо у вас є дочірній елемент, який можна натиснути, не забудьте додати android:clickable="false"його, щоб запобігти блокуванню подій клацання.
TheKalpit

не потрібно, додавання слухача кліків було мені достатньо, і якщо ви не хочете слухача кліків, чому ви хочете, щоб щось можна було натискати?
hmac

158

Якщо ви хочете додати фонову поведінку за замовчуванням для Android, щоб зробити Layoutтакі дії, як "klikable" View, встановіть націлене Layout:

API 11+ (чистий Android):

android:background="?android:attr/selectableItemBackground"

API 7+ (Бібліотека підтримки Android + AppCompat):

android:background="?attr/selectableItemBackground"

Будь-який API:

android:background="@android:drawable/list_selector_background"

Наведені вище відповіді все ще вірні, але не допомогли мені просто додати стан тиску та звільненого інтерфейсу за замовчуванням (як, ListViewнаприклад,)


+1 для вас, це чудово, якщо ви хочете зворотного зв’язку з дотиком до інтерфейсу користувача, але хочете самостійно обробляти логіку кліку (і не змушувати вказувати метод onClickX, для чого потрібен android:
clickkable

2
Це також працює з бризками конструкції матеріалу. Найкраща відповідь.
Miro Markaravanes

3
Добре! При натисканні виходить такий колір, як помаранчевий / жовтий, як ефект натискання. Я хочу змінити колір на зелений. Як це зробити?
Хан Уайткінг

@HanWhiteking ви дізналися?
Яків Санчес

16

Я використав першу та другу відповідь. Але в моєму лінійному розташуванні є зображення та текст із кольором тла, тому мені довелося змінити "фон" на "передній план"

лінійний розклад

android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"

9

Спочатку вам потрібно, щоб селектор визначав різні стани. Наприклад, у XML-файлі:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/button_pressed"
          android:state_pressed="true" />
    <item android:drawable="@drawable/button_focused"
          android:state_focused="true" />
    <item android:drawable="@drawable/button_normal" />
</selector>

Я не пробував цього, але ви, можливо, можете встановити андроїд LinearLayout: фон для цього селектора та встановити android: clickkable до істинного, і він буде працювати.

Якщо це не так, ви можете перейти на використання RelativeLayout і зробити перший елемент кнопкою з цим селектором як фоном і заповненням прозорого для його ширини та висоти макета. У цьому випадку просто скористайтеся звичайною кнопкою та встановіть на ваш селектор андроїд: фон. Не потрібно ставити текст на кнопку.


Так, я голосую за використання фактичного Button. Ви можете змінити onDraw(Canvas)значення будь-яких спеціальних речей (наприклад, намалювати зображення або текст у межах кнопки).
Дейв

1
Дякую! Встановлення фону LinearLayout працює, і він реагує на події, що торкаються, майже - якщо я натискаю LinearLayout безпосередньо, його стан оновлюється. Якщо я натискаю TextView всередині нього, подія дотику, здається, не дорівнює LinearLayout. Будь-яка ідея, як зробити хіт-тест макета?
Джейсон Прадо

Спробуйте Android: clickkable = "false" у TextView. Я цього не намагався, але у мене не було проблеми з натисканням на TextViews. Можливо, це тому, що ваш TextView має тло.
Tenfour04

Це зробило трюк, хоча це не дає звуку клацання. Чи є спосіб, щоб це зробити?
Стівен

@Steven Щойно побачив ваш старий коментар, вибачте. Я думаю, що звук клацання пов'язаний із призначенням onClickListener. У мене було щось із onTouchListener, і воно не натискатиме, поки я також не додав onClickListener (з порожнім методом onClick).
Tenfour04

7

У додатку, над яким я працюю, мені потрібно створити LinearLayout динамічно. У цьому випадку команда

ll.setClickable(true);

не працює, як належить зробити. Хоча я можу щось пропустити, мені вдалося використати setOnTouchListener, щоб отримати той самий результат, і я подаю код у випадку, якщо хтось має однакові потреби.

Наступний код створює LinearLayout з двома текстовими оглядами та круглими кутами, змінюючи колір при натисканні.

Спочатку створіть два файли xml у папці, що перетягується, один для нормального та один для натиснутого стану лінійного виходу.

Нормальний стан xml (малювальний / округлий_edges_normal.xml)

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#FFFFFF" />
            <corners android:radius="7dp" />
            <padding android:left="5dip" android:top="5dip" android:right="5dip" android:bottom="5dip" />
        </shape>
    </item>
    <item android:bottom="3px">
        <shape android:shape="rectangle">
            <solid android:color="#F1F1F1" />
            <corners android:radius="7dp" />
        </shape>
    </item>
</layer-list>

Нажатий стан xml (Dravable / rounded_edges_press.xml). Різниця лише в кольорі ...

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#FFFFFF" />
            <corners android:radius="7dp" />
            <padding android:left="5dip" android:top="5dip" android:right="5dip" android:bottom="5dip" />
        </shape>
    </item>
    <item android:bottom="3px">
        <shape android:shape="rectangle">
            <solid android:color="#add8e6" />
            <corners android:radius="7dp" />
        </shape>
    </item>
</layer-list>

Тоді наступний код виконує роботу

Глобальна змінна:

public int layoutpressed = -1;

В onCreate():

// Create some textviews to put into the linear layout...
TextView tv1 = new TextView(this);
TextView tv2 = new TextView(this);
tv1.setText("First Line");
tv2.setText("Second Line");

// LinearLayout definition and some layout properties...
final LinearLayout ll = new LinearLayout(context);
ll.setOrientation(LinearLayout.VERTICAL);

// it is supposed that the linear layout will be in a table.
// if this is not the case for you change next line appropriately...
ll.setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

ll.setBackgroundResource(R.drawable.rounded_edges_normal);
ll.addView(tv1);
ll.addView(tv2);
ll.setPadding(10, 10, 10, 10);
// Now define the three button cases
ll.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View arg0, MotionEvent arg1) {
                if (arg1.getAction()==MotionEvent.ACTION_DOWN){
                        ll.setBackgroundResource(R.drawable.rounded_edges_pressed);
                        ll.setPadding(10, 10, 10, 10);
                        layoutpressed = arg0.getId();
                }
                else if (arg1.getAction()== MotionEvent.ACTION_UP){
                        ll.setBackgroundResource(R.drawable.rounded_edges_normal);
                        ll.setPadding(10, 10, 10, 10);
                        if(layoutpressed == arg0.getId()){
                            //  ...........................................................................
                            // Code to execute when LinearLayout is pressed...
                            //  ........................................................................... 
                     }
          }
          else{
                ll.setBackgroundResource(R.drawable.rounded_edges_showtmimata);
                ll.setPadding(10, 10, 10, 10);
                layoutpressed = -1;
          }
          return true;
                }
  });           

6

Просто встановіть ці атрибути

<LinearLayout 
    ...
    android:background="@android:drawable/btn_default" 
    android:clickable="true"
    android:focusable="true"
    android:onClick="onClick"
    >
...
</LinearLayout>

5

Просто додайте фон attr / selectableItemBackground до лінійного макета, а також зробіть цей лінійний розміт клікабельним

приклад:

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/linear1"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true">

Це змушує лінійний розклад діяти як кнопка при натисканні. :)


1

Це було корисно, але якщо ви хочете ввести колір фону і зробити лінійний макет клікабельним, як елемент списку. Встановіть фон із бажаним кольором та встановіть колір переднього плану на? Android: attr / selectableItemBackground, встановіть фокусируемую істину та натискайте правду

зразок коду

   <LinearLayout

        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:background="#FF0"
        android:orientation="horizontal"
        android:paddingBottom="10dp"
         android:paddingTop="10dp"
        android:onClick="onClickMethod"
        android:clickable="true"
        android:focusable="true"
        android:foreground="?android:attr/selectableItemBackground"
        />

0

Попередні відповіді про те, як встановити фон за замовчуванням у файлі xml. Ось те саме в коді:

linearLayout1.setBackgroundResource(android.R.drawable.list_selector_background);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.