Làm cho một LinearLayout hoạt động giống như một nút


100

Tôi có một LinearLayoutcái mà tôi đã tạo kiểu để trông giống buttonvà nó chứa một vài phần tử text / ImageView. Tôi muốn làm cho toàn bộ LinearLayouthoạt động giống như một button, đặc biệt là cung cấp cho nó các trạng thái được xác định trong a để nó có một nền khác khi nó được nhấn.

Có cách nào tốt hơn là tạo ImageButtonkích thước của toàn bộ Bố cục và định vị tuyệt đối không?


Trong trường hợp ai đó đang tìm kiếm một cách để làm nổi bật một TableRow (được thừa hưởng từ một LinearLayout) trên báo chí (như một nút), xem stackoverflow.com/a/8204768/427545
Lekensteyn

1
nếu ai đó muốn có được giải pháp đầy đủ, kiểm tra kho lưu trữ này: github.com/shamanland/AndroidLayoutSelector có tùy chỉnh có thể click / checkable LinearLayoutnhư mộtToggleButton
Oleksii K.

Câu trả lời:


154

Tôi đã gặp phải vấn đề này ngay bây giờ. Bạn sẽ phải đặt LinearLayout thành có thể nhấp được. Bạn có thể làm điều này trong XML với

android:clickable="true"

Hoặc trong mã với

yourLinearLayout.setClickable(true);

Chúc mừng!


2
Câu trả lời dưới đây là tốt hơn nhiều!
Zach Sperske

2
Ngoài ra, nếu bạn có một phần tử "có thể nhấp" là con của nó, đừng quên thêm android:clickable="false"vào phần tử đó để ngăn nó chặn các sự kiện nhấp chuột.
TheKalpit

không cần thiết, thêm một trình nghe nhấp chuột là đủ đối với tôi và nếu bạn không muốn có trình nghe nhấp chuột tại sao bạn lại muốn thứ gì đó có thể nhấp được?
hmac

158

Nếu bạn muốn thêm hành vi nền mặc định của Android để thực hiện Layouthành vi giống như "có thể leo" View, hãy đặt trên mục tiêu được nhắm mục tiêu Layout:

API 11+ (Android thuần túy):

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

API 7+ (Thư viện hỗ trợ Android + AppCompat):

android:background="?attr/selectableItemBackground"

Bất kỳ API nào:

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

Các câu trả lời ở trên vẫn đúng nhưng không giúp tôi chỉ thêm trạng thái giao diện người dùng được nhấn và phát hành mặc định ( ListViewchẳng hạn như ví dụ).


+1 cho bạn, điều này thật tuyệt nếu bạn muốn phản hồi chạm vào giao diện người dùng nhưng muốn tự xử lý logic nhấp chuột (và không bị buộc phải chỉ định phương thức onClickX, phương thức android: clickable yêu cầu)
Rick Barkhouse

2
Điều này cũng hoạt động với các gợn sóng thiết kế material design. Câu trả lời tốt nhất.
Miro Markaravanes

3
Tốt! Khi nhấn nó sẽ ra màu như cam / vàng như hiệu ứng nhấn. Tôi muốn đổi màu thành xanh lục. Làm thế nào để làm nó?
Han Whiteking

@HanWhiteking bạn đã tìm ra chưa?
Jacob Sánchez

16

Tôi đã sử dụng câu trả lời đầu tiên và thứ hai. Nhưng tuyến tính của tôi có hình ảnh và văn bản với màu nền, vì vậy tôi đã phải thay đổi "nền" thành "nền trước"

tuyến tính

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

9

Trước tiên, bạn sẽ cần một bộ chọn để xác định các trạng thái khác nhau. Ví dụ, trong tệp 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>

Tôi chưa thử, nhưng bạn có thể đặt android: background của LinearLayout thành bộ chọn này và đặt android: clickable thành true và nó sẽ hoạt động.

Nếu không, bạn có thể chuyển sang sử dụng RelativeLayout và đặt phần tử đầu tiên thành một nút với bộ chọn này làm nền và fill_parent cho chiều rộng và chiều cao của bố cục. Trong trường hợp này, chỉ cần sử dụng Nút thông thường và đặt android: background thành bộ chọn của bạn. Bạn không cần phải đặt văn bản trên nút của mình.


Vâng, tôi bỏ phiếu cho việc sử dụng một thực tế Button. Bạn có thể ghi đè onDraw(Canvas)để làm bất kỳ điều gì đặc biệt mà bạn cần (ví dụ: vẽ hình ảnh hoặc văn bản trong nút).
Dave

1
Cảm ơn! Việc đặt nền của LinearLayout hoạt động và nó phản ứng với các sự kiện chạm, gần như– nếu tôi nhấn trực tiếp vào LinearLayout, trạng thái của nó sẽ được cập nhật. Nếu tôi nhấn TextView bên trong nó, sự kiện cảm ứng dường như không tạo thành LinearLayout. Bạn có ý tưởng nào về cách thực hiện thử nghiệm lần truy cập Bố cục không?
Jason Prado

Hãy thử android: clickable = "false" trên TextView. Tôi chưa thử điều này, nhưng tôi không gặp sự cố khi nhấp qua TextViews. Có thể đó là do TextView của bạn có nền.
Tenfour04

Điều này đã thực hiện thủ thuật, mặc dù nó không tạo ra tiếng nhấp chuột. Có cách nào để làm được điều đó không?
Steven

@Steven Chỉ nhìn thấy bình luận cũ của bạn, xin lỗi. Tôi nghĩ rằng âm thanh nhấp chuột gắn liền với việc chỉ định onClickListener. Tôi đã có một cái gì đó với onTouchListener và nó sẽ không nhấp cho đến khi tôi cũng thêm một onClickListener (với phương thức onClick trống).
Tenfour04

7

Trong ứng dụng tôi đang làm việc, tôi cần tạo một LinearLayout động. Trong trường hợp này, lệnh

ll.setClickable(true);

không hoạt động như phải làm. Mặc dù tôi có thể bỏ lỡ điều gì đó, nhưng tôi đã quản lý để khai thác setOnTouchListener để có được kết quả tương tự và tôi gửi mã trong trường hợp bất kỳ ai có nhu cầu giống nhau.

Đoạn mã sau tạo một LinearLayout với hai chế độ xem văn bản và các góc tròn, thay đổi màu sắc khi được nhấn.

Đầu tiên, tạo hai tệp xml trong thư mục có thể vẽ, một tệp ở trạng thái bình thường và một tệp cho trạng thái tuyến tính được nhấn.

Xml trạng thái bình thường (drawable / round_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>

Trạng thái được nén xml (drawable / round_edges_pressed.xml). Điểm khác biệt duy nhất là màu ...

<?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>

Sau đó, đoạn mã sau thực hiện công việc

Biến toàn cục:

public int layoutpressed = -1;

Trong 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

Chỉ cần đặt các thuộc tính này

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

5

Chỉ cần thêm background attr / selectableItemBackground vào bố cục tuyến tính và cũng có thể nhấp vào tuyến tính đó

thí dụ :

<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">

Điều đó làm cho tuyến tính hoạt động giống như nút khi nó được nhấn. :)


1

Điều này rất hữu ích nhưng nếu bạn muốn đặt màu nền và làm cho bố cục tuyến tính có thể nhấp được như mục danh sách. Đặt nền với màu ưa thích của bạn và đặt màu nền trước thành? Android: attr / selectableItemBackground, đặt focusable true và clickable true

mã mẫu

   <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

Phần trước là về cách đặt nền mặc định trong tệp xml. Đây là điều tương tự trong mã:

linearLayout1.setBackgroundResource(android.R.drawable.list_selector_background);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.