Membuat LinearLayout bertindak seperti Tombol

100

Saya memiliki gaya LinearLayoutyang saya buat agar terlihat seperti a button, dan itu berisi beberapa elemen teks / ImageView. Saya ingin membuat keseluruhan LinearLayouttindakan seperti a button, khususnya untuk memberikan status yang ditentukan dalam a sehingga memiliki latar belakang yang berbeda saat ditekan.

Apakah ada cara yang lebih baik daripada membuat ImageButtonukuran seluruh Tata Letak dan pemosisian secara mutlak?

Jason Prado
sumber
Jika seseorang mencari cara untuk menyorot TableRow (yang diwarisi dari LinearLayout) saat ditekan (seperti Tombol), lihat stackoverflow.com/a/8204768/427545
Lekensteyn
1
jika seseorang ingin mendapatkan solusi lengkap, periksa repositori ini: github.com/shamanland/AndroidLayoutSelector ada yang dapat diklik / dicentang khusus LinearLayoutsepertiToggleButton
Oleksii K.

Jawaban:

154

Saya mengalami masalah ini sekarang. Anda harus menyetel LinearLayout menjadi dapat diklik. Anda bisa melakukan ini dalam XML dengan

android:clickable="true"

Atau di kode dengan

yourLinearLayout.setClickable(true);

Bersulang!

Rockmaninoff
sumber
2
Jawaban di bawah ini jauh lebih baik!
Zach Sperske
2
Selain itu, jika Anda memiliki elemen "yang dapat diklik" sebagai anaknya, jangan lupa untuk menambahkannya android:clickable="false"untuk mencegahnya memblokir peristiwa klik.
TheKalpit
tidak perlu, menambahkan pendengar klik sudah cukup bagi saya dan jika Anda tidak ingin pendengar klik, mengapa Anda ingin sesuatu dapat diklik?
hmac
158

Jika Anda ingin menambahkan perilaku latar belakang default Android untuk membuat Layouttindakan seperti "dapat diklik" View, setel yang ditargetkan Layout:

API 11+ (Android Murni):

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

API 7+ (Pustaka Dukungan Android + AppCompat):

android:background="?attr/selectableItemBackground"

API apa pun:

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

Jawaban di atas masih benar tetapi tidak membantu saya untuk hanya menambahkan status UI yang ditekan dan dilepaskan default (seperti ListViewmisalnya).

FabiF
sumber
+1 untuk Anda, ini bagus jika Anda menginginkan umpan balik sentuhan UI, tetapi ingin menangani logika klik sendiri (dan tidak dipaksa untuk menentukan metode onClickX, yang dibutuhkan android: dapat diklik)
Rick Barkhouse
2
Ini juga bekerja dengan riak desain material. Jawaban Terbaik.
Miro Markaravanes
3
Baik! Saat ditekan ternyata warna seperti jingga / kuning seperti efek ditekan. Saya ingin mengubah warna menjadi hijau. Bagaimana cara melakukannya?
Han Whiteking
@HanWhiteking, apakah Anda tahu?
Jacob Sánchez
16

Saya menggunakan jawaban pertama dan kedua. Tetapi linearlayout saya memiliki gambar dan teks dengan warna background, jadi saya harus mengubah "background" menjadi "foreground"

linearlayout

android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
Roma
sumber
9

Pertama, Anda akan menginginkan pemilih untuk menentukan status yang berbeda. Misalnya, dalam file 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>

Saya belum mencobanya, tetapi Anda mungkin dapat menyetel latar belakang android: LinearLayout ke pemilih ini, dan menyetel android: dapat diklik menjadi true dan ini akan berhasil.

Jika tidak, Anda dapat beralih menggunakan RelativeLayout, dan membuat elemen pertama menjadi tombol dengan selektor ini sebagai latar belakang dan fill_parent untuk lebar dan tinggi tata letaknya. Dalam kasus ini, cukup gunakan Tombol biasa dan setel android: background ke pemilih Anda. Anda tidak perlu meletakkan teks di tombol Anda.

Tenfour04
sumber
Ya, saya memilih untuk menggunakan aktual Button. Anda dapat mengganti onDraw(Canvas)untuk melakukan hal khusus apa pun yang Anda butuhkan (yaitu, menggambar gambar atau teks di dalam tombol).
Dave
1
Terima kasih! Menyetel latar belakang LinearLayout berfungsi dan merespons peristiwa sentuh, hampir– jika saya menekan LinearLayout secara langsung, statusnya diperbarui. Jika saya menekan TextView di dalamnya, acara sentuh tampaknya tidak sesuai dengan LinearLayout. Ada ide tentang cara membuat uji coba Layout?
Jason Prado
Coba android: clickable = "false" di TextView. Belum mencoba ini, tetapi saya tidak mengalami masalah dengan mengklik melalui TextView. Mungkin karena TextView Anda memiliki latar belakang.
Tenfour04
Ini berhasil, meskipun tidak membuat bunyi klik. Apakah ada cara untuk melakukannya?
Steven
@Steven Baru saja melihat komentar lama Anda, maaf. Saya pikir suara klik terkait dengan memiliki onClickListener yang ditetapkan. Saya memiliki sesuatu dengan onTouchListener dan tidak akan diklik sampai saya juga menambahkan onClickListener (dengan metode onClick kosong).
Tenfour04
7

Dalam aplikasi yang sedang saya kerjakan, saya perlu membuat LinearLayout secara dinamis. Dalam hal ini perintahnya

ll.setClickable(true);

tidak berfungsi sebagaimana mestinya. Meskipun saya mungkin melewatkan sesuatu, saya berhasil mengeksploitasi setOnTouchListener untuk mendapatkan hasil yang sama dan saya mengirimkan kode jika ada yang memiliki kebutuhan yang sama.

Kode berikut membuat LinearLayout dengan dua tampilan teks dan sudut bundar, berubah warna saat ditekan.

Pertama, buat dua file xml dalam folder drawable, satu untuk normal dan satu lagi untuk keadaan linearlayout yang ditekan.

Status normal xml (drawable / rounded_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>

Status ditekan xml (drawable / rounded_edges_pressed.xml). Satu-satunya perbedaan adalah warnanya ...

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

Kemudian kode berikut melakukan pekerjaannya

Variabel global:

public int layoutpressed = -1;

Masuk 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;
                }
  });           
Epaminondas
sumber
6

Atur saja atribut ini

<LinearLayout 
    ...
    android:background="@android:drawable/btn_default" 
    android:clickable="true"
    android:focusable="true"
    android:onClick="onClick"
    >
...
</LinearLayout>
Daniel De León
sumber
5

Cukup tambahkan background attr / selectableItemBackground ke linear layout dan juga buat linearlayout itu bisa diklik

contoh:

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

Itu membuat linearlayout bertindak seperti tombol saat ditekan. :)

Exel Staderlin
sumber
1

Ini membantu tetapi jika Anda ingin memberi warna latar belakang dan membuat tata letak linier dapat diklik seperti item daftar. Setel latar belakang dengan warna pilihan Anda dan setel warna latar depan ke? Android: attr / selectableItemBackground, setel true focusable, dan true clickable

Kode sampel

   <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"
        />
Jeb Eb
sumber
0

Jawaban sebelumnya adalah tentang bagaimana mengatur latar belakang default di file xml. Di sini hal yang sama dalam kode:

linearLayout1.setBackgroundResource(android.R.drawable.list_selector_background);
yuliskov
sumber