Змушення 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.