Jak stworzyć standardowe przyciski bez obramowania (jak we wspomnianych wytycznych projektowych)?


114

Właśnie sprawdzałem wytyczne projektowe i zastanawiałem się nad przyciskami bez obramowania. Wytrzeszczyłem oczy i próbowałem znaleźć w źródle, ale nie mogę sam tego zebrać. Czy to normalny widżet Przycisk, ale dodajesz niestandardowy (domyślny dla Androida) styl? Jak zrobić te przyciski bez obramowania (oczywiście możesz ustawić puste tło, ale wtedy nie mam separatora)?

Tutaj linki do wytycznych projektowych:

wprowadź opis obrazu tutaj


Odpowiedzi:


163

Aby usunąć zamieszanie:

Odbywa się to w 2 krokach: Ustawienie atrybutu tła przycisku na android: attr / selectableItemBackground tworzy przycisk z informacją zwrotną, ale bez tła.

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

Linia oddzielająca przycisk bez obramowania od reszty układu jest tworzona przez widok z tłem android: attr / dividerVertical

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

Dla lepszego zrozumienia jest tutaj układ kombinacji przycisków OK / Anuluj bez obramowania u dołu ekranu (jak na prawym obrazku powyżej).

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

25
Warto zwrócić uwagę: to rozwiązanie działa tylko dla poziomu API 11+.

9
Jeśli używasz HoloEverywhere , działa to na poziomie API 7+. Musisz zmienić ?android:attr/selectableItemBackgroundna ?attr/selectableItemBackgroundi ?android:attr/dividerVerticalna?attr/dividerVertical
Brais Gabin

1
?android:attr/dividerVerticalfora ?attr/dividerVerticaltakże działa na abs
oscarthecat


22

Późna odpowiedź, ale wiele opinii. Ponieważ API <11 jeszcze nie umarły, dla zainteresowanych jest to sztuczka.

Niech twój pojemnik uzyska pożądany kolor (może być przezroczysty). Następnie nadaj przyciskom selektor z domyślnym przezroczystym kolorem i pewnym kolorem po naciśnięciu. W ten sposób będziesz mieć przezroczysty przycisk, ale po naciśnięciu zmieni kolor (jak hologramy). Możesz także dodać animację (np. Hologramy). Selektor powinien wyglądać mniej więcej tak:

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>

A przycisk powinien mieć android:background="@drawable/selector_transparent_button"

PS: pozwól kontenerowi mieć separatory ( android:divider='@android:drawable/...dla API <11)

PS [Newbies]: powinieneś zdefiniować te kolory w values ​​/ colors.xml


To działało idealnie zarówno w przypadku, jak API Level 10i API Level > 10!
theblang

Jest to lepsze niż robienie tego programowo, mimo że oba będą działać.
Eran Goldin

1
Atrybut „exitFadeDuration” jest używany tylko na poziomie interfejsu API 11 i wyższych.
Bevor

tak @Bevor, niezłe. Czytelnicy uważają, że nieznane znaczniki xml są ignorowane, więc użyje zanikania dla api> = 11 i po prostu będzie działać dla <11
aacotroneo

18

Dla tych, którzy chcą przyciski bez obramowania, ale nadal są animowane po kliknięciu. Dodaj to w przycisku.

style="?android:attr/borderlessButtonStyle"

Jeśli chcesz, aby między nimi była dzielnica / linia. Dodaj to w układzie liniowym.

style="?android:buttonBarStyle"

Podsumowanie

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

plus dla buttonBarStyle. i to jest przy okazji odpowiedź.
mroźno cudowny

7

Aby uzyskać styl materiału, dodaj style="@style/Widget.AppCompat.Button.Borderless"podczas korzystania z biblioteki AppCompat.


5

Ze źródła aplikacji na iOS wymyśliłem tę ButtonBarklasę:

/**
 * 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;
}

Będzie to miejsce LinearLayout, do którego trafiają przyciski „OK” i „Anuluj” i zajmą się umieszczaniem ich w odpowiedniej kolejności. Następnie umieść to w układzie, w którym chcesz umieścić przyciski:

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

Daje to wygląd okna dialogowego z przyciskami bez obramowania. Możesz znaleźć te atrybuty w res we frameworku. buttonBarStylewykonuje pionowy separator i dopełnienie. buttonBarButtonStylejest ustawiony jak borderlessButtonStylemotyw Holo, ale uważam, że powinien to być najpewniejszy sposób wyświetlania go, ponieważ struktura chce go wyświetlić.


jak mogę umieścić to (? android: attr / buttonBarButtonStyle) w styles.xml jako element stylu?
lis

4

Spojrzenie na temat atrybutów buttonBarStyle, buttonBarButtonStyleoraz borderlessButtonStyle.


Jeśli używam buttonBarButtonStyle, otrzymuję wyjątek 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}Nie mam pojęcia dlaczego, ale używanie selectableItemBackgrounddziała cuda.
Someone Somewhere

4

Możesz również uczynić przyciski bez obramowania za pomocą kodu:

TypedValue value= new TypedValue();
getApplicationContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
 myButton.setBackgroundResource(value.resourceId);

Działa, dzięki. Ale android.R.attr.selectableItemBackgroundwymaga API 21. Jakieś pomysły, jak to zrobić we wcześniejszych wersjach?
arenaq

To nie działa. Próbuję ustawić zasób android.R.attr.buttonBarButtonStyle i mówi, że nie można znaleźć zasobu.
Kristy Welsh

użyj android.R.attr.selectableItemBackground
Isj

2

Dla tych, którzy chcą programowo utworzyć przycisk bez obramowania dla 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);

To jest lepsze, prostsze niż rozwiązanie lsj. Po prostu ustawBackgroundResource (0)
jk7

2

Innym rozwiązaniem, które powinno działać zarówno na starszej, jak i nowszej platformie Android, jest użycie

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

atrybut dla widoku przycisku. Ale po dodaniu powyższej linii przycisk nie zapewni reakcji na dotyk.

Aby zapewnić reakcję dotykową, dodaj następujący kod do klasy Activity

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;
    }
});

Dla mnie działa dobrze.


Dodałbym również case MotionEvent.ACTION_CANCEL: poniżej case MotionEvent.ACTION_UP: .
Medo

2

Dla każdego, kto wciąż szuka:

odziedzicz własny styl pasków przycisków Holo:

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

lub Holo Light:

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

a dla przycisków Holo bez obramowania:

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

lub Holo Light:

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

2

W ten sposób programistycznie tworzysz przycisk bez obramowania (płaski) bez użycia 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);

Używałem: ContextThemeWrapper myContext = new ContextThemeWrapper(this.getActivity(), R.style.Widget_AppCompat_Button_Borderless_Colored); Button myButton = new Button(myContext); i to nie zadziała. Po dodaniu drugiego i trzeciego parametru działa!
lewibostian

1

Użyj poniższego kodu w pliku xml. Użyj android: background = "# 00000000", aby uzyskać przezroczysty kolor.

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

1

Możesz użyć biblioteki obsługi AppCompat dla przycisku bez obramowania.

Możesz utworzyć przycisk bez obramowania w następujący sposób:

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

Możesz utworzyć kolorowy przycisk bez obramowania w następujący sposób:

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

0

Z jakiegoś powodu style="Widget.Holo.Button.Borderless"ani android:background="?android:attr/selectableItemBackground"dla mnie, ani dla mnie nie działały. Mówiąc dokładniej, Widget.Holo.Button.Borderlesswykonałem zadanie na Androidzie 4.0, ale nie działało na Androidzie 2.3.3. Jaki był dla mnie trick w obu wersjach android:background="@drawable/transparent"i ten XML w res / drawable / transparent.xml:

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

Prosta głowa przez podejście do ściany.


2
Ustawienie tła na @android: color / transparent działało jak dla mnie, bez potrzeby dodatkowego pliku XML.
Nicolai Buch-Andersen

Nie obejmuje to, jak uzyskać rozdzielacz.
Navarr

3
@Navarr, zgodnie z odpowiedzią Blundella, dzielnik nie jest częścią „przycisku bez obramowania”. Nie powinno też tak być, ponieważ przyciski i inne klasy widoku nie powinny być informowane o otaczających elementach GUI. To odpowiedzialność kontenera. W komentarzach do posta Blundella znajduje się łącze do czegoś, co wygląda na układ elementu szczegółów kontaktu ICS. Istnieje dodatkowy widok (z id vertical_divider) do wyświetlania separatora. Brak gotowego rozwiązania dla automatycznych rozdzielaczy, chociaż jest zgrabna android:background="?android:attr/dividerVertical"sztuczka.
Emperor Orionii

Pytanie OP dotyczyło Android UX „Borderless Buttons” i we wszystkich przykładach mają one separator - który najwyraźniej jest częścią buttonBarStyle. Mimo że przekazałeś mi kilka bardzo pomocnych informacji, dziękuję.
Navarr

0

Świetny pokaz slajdów pokazujący, jak osiągnąć pożądany efekt od Googles Nick Butcher (zacznij od slajdu 20). Używa standardowego Androida @attrdo stylizacji przycisku i rozdzielacza.


Zwróć uwagę, że odradza się udzielanie odpowiedzi zawierających tylko łącze , odpowiedzi SO powinny być końcowym punktem poszukiwania rozwiązania (w porównaniu z kolejnym zatrzymaniem odniesień, które z czasem stają się nieaktualne). Proszę rozważyć dodanie tutaj samodzielnego streszczenia, zachowując link jako odniesienie.
kleopatra

0

Dodając do pierwszej odpowiedzi, możesz także użyć widoków z ciemnoszarym tłem w układzie liniowym, takim jak ten.

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

Jeśli twoja linia jest pozioma, będziesz chciał ustawić wysokość na 1dip i szerokość tak, aby pasowała do rodzica i odwrotnie, jeśli twoja linia jest pionowa.


0

Jeśli chcesz osiągnąć to samo programowo:

(to jest C #, ale łatwo można przetłumaczyć na Javę)

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

Mecz

    <Button
       style="@style/Widget.AppCompat.Button.Borderless.Colored"
    .../>

0

Wypróbuj ten kod, aby programowo usunąć tło do rysowania (@ drawable / bg), po prostu musimy podać wartość null jako parametr.

Button btn= new Button(this);
btn.setText("HI");
btn.setBackground(null);

1
Dziękujemy za ten fragment kodu, który może zapewnić ograniczoną, natychmiastową pomoc. Właściwe wyjaśnienie byłoby znacznie poprawić swoją długoterminową wartość pokazując dlaczego jest to dobre rozwiązanie problemu i byłoby bardziej użyteczne dla czytelników przyszłości z innymi, podobnymi pytaniami. Proszę edytować swoją odpowiedź dodać kilka wyjaśnień, w tym założeń już wykonanych.
NIE,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.