Bagaimana cara membuat tombol tanpa bingkai standar (seperti dalam pedoman desain yang disebutkan)?

113

Saya baru saja memeriksa pedoman desain dan bertanya-tanya tentang tombol tanpa bingkai. Saya melotot dan mencoba menemukan sumbernya tetapi tidak dapat menyatukannya sendiri. Apakah ini widget Tombol normal tetapi Anda menambahkan gaya kustom (default Android)? Bagaimana cara membuat tombol tanpa batas ini (tentu saja Anda dapat mengatur latar belakang menjadi kosong, tetapi saya tidak memiliki pembatas)?

Berikut tautan ke pedoman desain:

masukkan deskripsi gambar di sini

KarlKarlsom
sumber

Jawaban:

163

Untuk menghilangkan kebingungan:

Ini dilakukan dalam 2 langkah: Menyetel atribut latar belakang tombol ke android: attr / selectableItemBackground membuat Anda tombol dengan umpan balik tetapi tanpa latar belakang.

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

Garis untuk membagi tombol tanpa bingkai dari tata letak Anda yang lain dilakukan oleh tampilan dengan latar belakang android: attr / dividerVertical

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

Untuk pemahaman yang lebih baik di sini adalah tata letak untuk kombinasi tombol OK / Batal tanpa batas di bagian bawah layar Anda (seperti pada gambar kanan di atas).

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:layout_alignParentBottom="true">
        <View
            android:layout_width="match_parent"
            android:layout_height="1dip"
            android:layout_marginLeft="4dip"
            android:layout_marginRight="4dip"
            android:background="?android:attr/dividerVertical"
            android:layout_alignParentTop="true"/>
        <View
            android:id="@+id/ViewColorPickerHelper"
            android:layout_width="1dip"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="4dip"
            android:layout_marginTop="4dip"
            android:background="?android:attr/dividerVertical" 
            android:layout_centerHorizontal="true"/>
        <Button
            android:id="@+id/BtnColorPickerCancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_toLeftOf="@id/ViewColorPickerHelper"
            android:background="?android:attr/selectableItemBackground"
            android:text="@android:string/cancel" 
            android:layout_alignParentBottom="true"/>
        <Button
            android:id="@+id/BtnColorPickerOk"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:background="?android:attr/selectableItemBackground"
            android:text="@android:string/ok" 
            android:layout_alignParentBottom="true" 
            android:layout_toRightOf="@id/ViewColorPickerHelper"/>
    </RelativeLayout>
KarlKarlsom
sumber
25
Patut diperhatikan: solusi ini hanya berfungsi untuk API level 11+.
9
Jika Anda menggunakan HoloEverywhere, ini berfungsi untuk API level 7+. Anda harus berganti ?android:attr/selectableItemBackgrounduntuk ?attr/selectableItemBackgrounddan ?android:attr/dividerVerticaluntuk?attr/dividerVertical
Brais Gabin
1
?android:attr/dividerVerticalfordan ?attr/dividerVerticaljuga bekerja untuk abs
oscarthecat
22

Jawaban telat, tapi banyak dilihat. Karena API <11 belum mati, bagi mereka yang tertarik, ini adalah trik.

Biarkan wadah Anda memiliki warna yang diinginkan (mungkin transparan). Kemudian berikan tombol Anda selektor dengan warna transparan default, dan beberapa warna saat ditekan. Dengan begitu Anda akan memiliki tombol transparan, tetapi akan berubah warna saat ditekan (seperti holo). Anda juga dapat menambahkan beberapa animasi (seperti holo). Selektornya harus seperti ini:

res/drawable/selector_transparent_button.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" 
          android:exitFadeDuration="@android:integer/config_shortAnimTime">
     <item android:state_pressed="true"
         android:drawable="@color/blue" />

   <item android:drawable="@color/transparent" />
</selector>

Dan tombolnya harus ada android:background="@drawable/selector_transparent_button"

PS: biarkan wadah Anda memiliki pemisah ( android:divider='@android:drawable/...untuk API <11)

PS [Pemula]: Anda harus menentukan warna-warna itu di values ​​/ colors.xml

aacotroneo
sumber
Ini bekerja dengan sempurna untuk keduanya API Level 10dan API Level > 10!
theblang
Ini lebih baik daripada melakukannya secara terprogram meskipun keduanya akan berhasil.
Eran Goldin
1
Atribut "exitFadeDuration" hanya digunakan di API level 11 dan yang lebih tinggi.
Bevor
ya @Bevor, bagus. Pembaca menganggap bahwa tag xml yang tidak dikenal diabaikan sehingga akan menggunakan fading untuk api> = 11, dan hanya berfungsi untuk <11
aacotroneo
18

Untuk yang ingin tombol tanpa bingkai tapi tetap animasi saat diklik. Tambahkan ini di tombol.

style="?android:attr/borderlessButtonStyle"

Jika Anda menginginkan pemisah / garis di antara mereka. Tambahkan ini di layout linier.

style="?android:buttonBarStyle"

Ringkasan

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:orientation="horizontal"
   style="?android:buttonBarStyle">

    <Button
        android:id="@+id/add"
        android:layout_weight="1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/add_dialog" 
        style="?android:attr/borderlessButtonStyle"
        />

    <Button
        android:id="@+id/cancel"
        android:layout_weight="1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/cancel_dialog" 
        style="?android:attr/borderlessButtonStyle"
        />

</LinearLayout>
aLIEz
sumber
plus untuk buttonBarStyle. dan inilah jawabannya btw.
frostymarvelous
7

Untuk menambahkan gaya material style="@style/Widget.AppCompat.Button.Borderless"saat menggunakan pustaka AppCompat.

Roel
sumber
5

Dari sumber aplikasi iosched saya mendapatkan ButtonBarkelas ini :

/**
 * An extremely simple {@link LinearLayout} descendant that simply reverses the 
 * order of its child views on Android 4.0+. The reason for this is that on 
 * Android 4.0+, negative buttons should be shown to the left of positive buttons.
 */
public class ButtonBar extends LinearLayout {

    public ButtonBar(Context context) {
        super(context);
    }

    public ButtonBar(Context context, AttributeSet attributes) {
        super(context, attributes);
    }

    public ButtonBar(Context context, AttributeSet attributes, int def_style) {
        super(context, attributes, def_style);
    }

    @Override
    public View getChildAt(int index) {
        if (_has_ics)
            // Flip the buttons so that "OK | Cancel" becomes "Cancel | OK" on ICS
            return super.getChildAt(getChildCount() - 1 - index);

        return super.getChildAt(index);
    }

    private final static boolean _has_ics = Build.VERSION.SDK_INT >= 
                                        Build.VERSION_CODES.ICE_CREAM_SANDWICH;
}

Ini akan menjadi tombol LinearLayout"OK" dan "Batal" masuk, dan akan menangani menempatkan mereka dalam urutan yang sesuai. Kemudian letakkan ini di tata letak yang Anda inginkan untuk tombol:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:divider="?android:attr/dividerHorizontal"
          android:orientation="vertical"
          android:showDividers="middle">
    <!--- A view, this approach only works with a single view here -->
    <your.package.ButtonBar style="?android:attr/buttonBarStyle"
        android:id="@+id/buttons"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="1.0">
        <Button style="?android:attr/buttonBarButtonStyle"
            android:id="@+id/ok_button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="@string/ok_button" />
        <Button style="?android:attr/buttonBarButtonStyle"
            android:id="@+id/cancel_button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="@string/cancel_button" />
    </your.package.ButtonBar>
</LinearLayout>

Ini memberi Anda tampilan dialog dengan tombol tanpa bingkai. Anda dapat menemukan atribut ini di res dalam kerangka kerja. buttonBarStylemelakukan pembatas dan bantalan vertikal. buttonBarButtonStyledisetel borderlessButtonStyleuntuk tema Holo, tapi saya yakin ini harus menjadi cara paling kuat untuk menampilkannya karena kerangka kerja ingin menampilkannya.

Dandre Allison
sumber
bagaimana saya bisa meletakkan ini (? android: attr / buttonBarButtonStyle) di styles.xml sebagai item gaya?
lis
4

Lihat ke tema atribut buttonBarStyle, buttonBarButtonStyledan borderlessButtonStyle.

Josh Lee
sumber
Jika saya menggunakan buttonBarButtonStylesaya mendapatkan pengecualian E/AndroidRuntime(17134): Caused by: java.lang.reflect.InvocationTargetException E/AndroidRuntime(17134): Caused by: android.content.res.Resources$NotFoundException: Resource is not a Drawable (color or path): TypedValue{t=0x1/d=0x1030281 a=2 r=0x1030281}Tidak tahu mengapa, tetapi menggunakan selectableItemBackgroundkeajaiban.
Seseorang di suatu tempat
4

Anda juga dapat membuat tombol tanpa bingkai melalui kode:

TypedValue value= new TypedValue();
getApplicationContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
 myButton.setBackgroundResource(value.resourceId);
Isj
sumber
Berhasil, terima kasih. Tetapi android.R.attr.selectableItemBackgroundmembutuhkan API 21. Ada ide bagaimana melakukan ini pada versi sebelumnya?
arenaq
Ini tidak bekerja. Saya mencoba menyetel sumber daya android.R.attr.buttonBarButtonStyle dan dikatakan bahwa sumber daya tidak dapat ditemukan.
Kristy Welsh
gunakan android.R.attr.selectableItemBackground
Isj
2

Bagi mereka yang ingin membuat tombol tanpa batas lewat program untuk API> = 8

ImageButton smsImgBtn = new ImageButton(this);
//Sets a drawable as the content of this button
smsImgBtn.setImageResource(R.drawable.message_icon);    
//Set to 0 to remove the background or for bordeless button
smsImgBtn.setBackgroundResource(0);
Sohail
sumber
Ini lebih baik, lebih sederhana daripada solusi lsj. Cukup setBackgroundResource (0)
jk7
2

Solusi lain yang seharusnya berfungsi pada platform Android yang lebih lama dan yang lebih baru adalah dengan menggunakan

android:background="@android:color/transparent"

atribut untuk tampilan Tombol. Tetapi setelah menambahkan tombol baris di atas tidak akan memberikan umpan balik sentuhan.

Untuk memberikan masukan sentuh, tambahkan kode berikut ke kelas Aktivitas

button.setOnTouchListener(new View.OnTouchListener() {          
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        switch (event.getAction())
        {
            case MotionEvent.ACTION_DOWN:    
                ((Button)view).setBackgroundColor(Color.LTGRAY);
                break;
            case MotionEvent.ACTION_UP:
                ((Button)view).setBackgroundColor(Color.TRANSPARENT);
        }
        return false;
    }
});

Ini bekerja dengan baik untuk saya.

prodev
sumber
Saya akan menambahkan di case MotionEvent.ACTION_CANCEL: bawah ini case MotionEvent.ACTION_UP: juga.
Medo
2

Untuk siapa saja yang masih mencari:

mewarisi gaya Anda sendiri untuk bilah tombol Holo:

<style name="yourStyle" parent="@android:style/Holo.ButtonBar">
  ...
</style>

atau Cahaya Holo:

<style name="yourStyle" parent="@android:style/Holo.Light.ButtonBar">
  ...
</style>

dan untuk tombol Holo tanpa bingkai:

<style name="yourStyle" parent="@android:style/Widget.Holo.Button.Borderless.Small">
  ...
</style>

atau Cahaya Holo:

<style name="yourStyle" parent="@android:style/Widget.Holo.Light.Button.Borderless.Small">
  ...
</style>
silversmurf
sumber
2

Ini adalah cara Anda membuat tombol tanpa bingkai (datar) secara terprogram tanpa menggunakan XML

ContextThemeWrapper myContext = new ContextThemeWrapper(this.getActivity(), 
   R.style.Widget_AppCompat_Button_Borderless_Colored);

Button myButton = new Button(myContext, null, 
   R.style.Widget_AppCompat_Button_Borderless_Colored);
Manuel
sumber
Saya menggunakan: ContextThemeWrapper myContext = new ContextThemeWrapper(this.getActivity(), R.style.Widget_AppCompat_Button_Borderless_Colored); Button myButton = new Button(myContext); dan itu tidak akan berhasil. Setelah menambahkan parameter ke-2 dan ke-3, itu berfungsi!
levibostian
1

Gunakan kode di bawah ini di file xml Anda. Gunakan android: background = "# 00000000" untuk memiliki warna transparan.

<Button
   android:id="@+id/btnLocation"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="#00000000"
   android:text="@string/menu_location"
   android:paddingRight="7dp"
/>
Kayuri Ravrani
sumber
1

Anda dapat menggunakan Pustaka Dukungan AppCompat untuk Tombol Tanpa Batas.

Anda dapat membuat Tombol Tanpa Tepi seperti ini:

<Button
    style="@style/Widget.AppCompat.Button.Borderless"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="16dp" 
    android:text="@string/borderless_button"/>

Anda dapat membuat Tombol Berwarna Tanpa Tepi seperti ini:

<Button
    style="@style/Widget.AppCompat.Button.Borderless.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="16dp" 
    android:text="@string/borderless_colored_button"/>
Rajesh
sumber
0

Untuk beberapa alasan tidak style="Widget.Holo.Button.Borderless"dan tidak android:background="?android:attr/selectableItemBackground"berhasil untuk saya. Lebih tepatnya Widget.Holo.Button.Borderlessmelakukan pekerjaan di Android 4.0 tetapi tidak berfungsi di Android 2.3.3. Apa trik untuk saya pada kedua versi itu android:background="@drawable/transparent"dan XML ini di res / drawable / transparent.xml:

<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle" >
</shape>

Kepala polos melalui pendekatan dinding.

Kaisar Orionii
sumber
2
Menyetel latar belakang ke @android: color / transparent berhasil untuk saya, tanpa perlu file XML tambahan.
Nicolai Buch-Andersen
Ini gagal untuk memasukkan bagaimana mendapatkan sekat.
Navarr
3
@Navarr menurut jawaban Blundell, pembatas bukanlah bagian dari "tombol tanpa bingkai". Juga tidak seharusnya karena tombol dan kelas tampilan lainnya tidak boleh diinformasikan tentang komponen GUI di sekitarnya. Itu tanggung jawab penampung. Di komentar untuk posting Blundell ada tautan ke apa yang tampak seperti tata letak item detail kontak ICS. Ada tampilan ekstra (dengan id vertical_divider) untuk menampilkan pembagi. Tidak ada solusi out of the box untuk pembagi otomatis meskipun ada android:background="?android:attr/dividerVertical"trik yang rapi .
Kaisar Orionii
Pertanyaan OP mengacu pada Android UX "Borderless Buttons", dan dalam semua contoh mereka memiliki pembagi - yang tampaknya merupakan bagian dari buttonBarStyle. Meskipun Anda telah memberi saya beberapa informasi yang sangat membantu, terima kasih.
Navarr
0

Pertunjukan slide yang bagus tentang cara mendapatkan efek yang diinginkan dari Google Nick Butcher (mulai dari slide 20). Dia menggunakan android standar @attruntuk mengatur gaya tombol dan pembatas.

Moritz
sumber
Perhatikan bahwa jawaban link-only tidak disarankan, jawaban SO harus menjadi titik akhir dari pencarian solusi (vs. referensi lain yang berhenti, yang cenderung menjadi basi seiring waktu). Harap pertimbangkan untuk menambahkan sinopsis yang berdiri sendiri di sini, dengan menyimpan tautan sebagai referensi.
kleopatra
0

Menambahkan ke jawaban teratas Anda juga dapat menggunakan tampilan dengan warna latar belakang abu-abu gelap dalam Tata Letak Linear seperti itu.

<View
    android:layout_width="match_parent"
    android:layout_height="1dip"
    android:layout_marginBottom="4dip"
    android:layout_marginLeft="4dip"
    android:layout_marginRight="4dip"
    android:layout_marginTop="4dip"
    android:background="@android:color/darker_gray"/>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="4dip"
    android:orientation="horizontal"
    android:weightSum="1">

    <Button
        android:id="@+id/button_decline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_weight="0.50"
        android:background="?android:attr/selectableItemBackground"
        android:padding="10dip"
        android:text="@string/decline"/>

    <View
        android:layout_width="1dip"
        android:layout_height="match_parent"
        android:layout_marginLeft="4dip"
        android:layout_marginRight="4dip"
        android:background="@android:color/darker_gray"/>

    <Button
        android:id="@+id/button_accept"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:layout_weight="0.50"
        android:background="?android:attr/selectableItemBackground"
        android:padding="10dip"
        android:text="@string/accept"/>
</LinearLayout>

Jika garis Anda horizontal, Anda ingin mengatur tinggi ke 1dip dan lebarnya agar sesuai dengan induk dan sebaliknya jika garis Anda vertikal.

Munaz
sumber
0

Jika Anda ingin mencapai hal yang sama secara terprogram:

(ini adalah C # tetapi mudah diterjemahkan ke Java)

Button button = new Button(new ContextThemeWrapper(Context, Resource.Style.Widget_AppCompat_Button_Borderless_Colored), null, Resource.Style.Widget_AppCompat_Button_Borderless_Colored);

Pertandingan

    <Button
       style="@style/Widget.AppCompat.Button.Borderless.Colored"
    .../>
Yohan Dahmani
sumber
0

Coba kode ini, untuk menghapus drawable latar belakang (@ drawable / bg) secara terprogram, kita hanya perlu memberikan null sebagai parameter.

Button btn= new Button(this);
btn.setText("HI");
btn.setBackground(null);
Ramesh kumar
sumber
1
Terima kasih atas cuplikan kode ini, yang mungkin memberikan bantuan terbatas dan langsung. SEBUAH penjelasan yang tepat akan sangat meningkatkan nilai jangka panjang dengan menunjukkan mengapa ini adalah solusi yang baik untuk masalah ini dan akan membuatnya lebih bermanfaat untuk pembaca masa depan dengan lainnya, pertanyaan-pertanyaan serupa. Harap edit jawaban Anda untuk menambahkan penjelasan, termasuk asumsi yang Anda buat.
NOhs