Ein LinearLayout wirkt wie eine Schaltfläche

100

Ich habe eine LinearLayout, die ich so gestaltet habe, dass sie wie eine aussieht button, und sie enthält einige Text- / ImageView-Elemente. Ich möchte das Ganze LinearLayoutwie ein Akt machen button, insbesondere um ihm Zustände zu geben, die in a definiert sind, damit es beim Drücken einen anderen Hintergrund hat.

Gibt es einen besseren Weg, als ImageButtondie Größe des gesamten Layouts zu bestimmen und absolut zu positionieren?

Jason Prado
quelle
Falls jemand nach einer Möglichkeit sucht, eine TableRow (die von einem LinearLayout geerbt wird) beim Drücken (wie eine Schaltfläche) hervorzuheben, siehe stackoverflow.com/a/8204768/427545
Lekensteyn,
1
Wenn jemand eine vollständige Lösung erhalten möchte, überprüfen Sie dieses Repository: github.com/shamanland/AndroidLayoutSelector gibt es benutzerdefinierte klickbar / überprüfbar LinearLayoutwie aToggleButton
Oleksii K.

Antworten:

154

Ich bin gerade auf dieses Problem gestoßen. Sie müssen das LinearLayout auf anklickbar setzen. Sie können dies entweder im XML mit tun

android:clickable="true"

Oder im Code mit

yourLinearLayout.setClickable(true);

Prost!

Rockmaninoff
quelle
2
Die Antwort unten ist viel besser!
Zach Sperske
2
Wenn Sie als untergeordnetes Element ein "anklickbares" Element haben, vergessen Sie nicht, es hinzuzufügen, android:clickable="false"um zu verhindern, dass es Klickereignisse blockiert.
TheKalpit
nicht notwendig, das Hinzufügen eines Klick-Listeners war genug für mich und wenn Sie keinen Klick-Listener möchten, warum möchten Sie, dass etwas anklickbar ist?
Hmac
158

Wenn Sie das Standard-Hintergrundverhalten von Android hinzufügen möchten, um eine LayoutAktion wie "anklickbar" zu erstellen View, legen Sie Folgendes fest Layout:

API 11+ (reines Android):

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

API 7+ (Android + AppCompat Support Library):

android:background="?attr/selectableItemBackground"

Beliebige API:

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

Die obigen Antworten sind immer noch wahr, haben mir aber nicht geholfen, nur den standardmäßig gedrückten und freigegebenen UI-Status hinzuzufügen (wie ListViewzum Beispiel in einem ).

FabiF
quelle
+1 für Sie, dies ist großartig, wenn Sie das Feedback der Benutzeroberfläche berühren möchten, aber die Klicklogik selbst handhaben möchten (und nicht gezwungen sein müssen, eine onClickX-Methode anzugeben, was android: clickable erfordert)
Rick Barkhouse
2
Dies funktioniert auch bei Welligkeiten des Materialdesigns. Beste Antwort.
Miro Markaravanes
3
Gut! Beim Drücken wird die Farbe Orange / Gelb als Druckeffekt angezeigt. Ich möchte die Farbe in Grün ändern. Wie es geht?
Han Whiteking
@ HanWhiteking hast du herausgefunden?
Jacob Sánchez
16

Ich habe die erste und zweite Antwort verwendet. Aber mein lineares Layout enthält Bilder und Text mit Hintergrundfarbe, daher musste ich "Hintergrund" in "Vordergrund" ändern.

lineares Layout

android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
römisch
quelle
9

Zuerst möchten Sie, dass ein Selektor die verschiedenen Zustände definiert. Zum Beispiel in einer XML-Datei:

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

Ich habe es nicht ausprobiert, aber Sie können möglicherweise den android: background des LinearLayout auf diesen Selektor setzen und android: clickable auf true setzen, und es wird funktionieren.

Wenn dies nicht der Fall ist, können Sie zur Verwendung eines RelativeLayout wechseln und das erste Element zu einer Schaltfläche mit diesem Selektor als Hintergrund und fill_parent für seine Layoutbreite und -höhe machen. In diesem Fall verwenden Sie einfach einen normalen Button und setzen android: background auf Ihren Selektor. Sie müssen keinen Text auf Ihre Schaltfläche setzen.

Tenfour04
quelle
Ja, ich stimme für die Verwendung eines tatsächlichen Button. Sie können überschreiben onDraw(Canvas), um alle speziellen Dinge zu tun, die Sie benötigen (z. B. Bilder oder Text innerhalb der Schaltfläche zeichnen).
Dave
1
Vielen Dank! Das Einstellen des Hintergrunds des LinearLayout funktioniert und es reagiert fast auf Berührungsereignisse - wenn ich das LinearLayout direkt drücke, wird sein Status aktualisiert. Wenn ich die Textansicht drin drücke, scheint das Berührungsereignis das LinearLayout nicht zu erreichen. Irgendeine Idee, wie man den Layout-Hit-Test macht?
Jason Prado
Versuchen Sie android: clickable = "false" in der Textansicht. Ich habe es nicht versucht, aber ich hatte kein Problem mit dem Klicken durch TextViews. Vielleicht liegt es daran, dass Ihre Textansicht einen Hintergrund hat.
Tenfour04
Dies hat den Trick gemacht, obwohl es das Klickgeräusch nicht erzeugt. Gibt es eine Möglichkeit, dies zu erreichen?
Steven
@Steven Hab gerade deinen alten Kommentar gesehen, sorry. Ich denke, der Klick-Sound ist an die Zuweisung eines onClickListener gebunden. Ich hatte etwas mit einem onTouchListener und es würde nicht klicken, bis ich auch einen onClickListener hinzugefügt habe (mit einer leeren onClick-Methode).
Tenfour04
7

In der Anwendung, an der ich arbeite, muss ich dynamisch ein LinearLayout erstellen. In diesem Fall der Befehl

ll.setClickable(true);

funktioniert nicht wie vorgesehen. Obwohl ich möglicherweise etwas vermisse, habe ich es geschafft, setOnTouchListener zu nutzen, um das gleiche Ergebnis zu erzielen, und ich sende den Code, falls jemand die gleichen Bedürfnisse hat.

Der folgende Code erstellt ein LinearLayout mit zwei Textansichten und runden Ecken, dessen Farbe sich beim Drücken ändert.

Erstellen Sie zunächst zwei XML-Dateien in einem zeichnbaren Ordner, eine für den normalen und eine für den gedrückten linearen Layoutstatus.

Normalzustand xml (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>

Gedrückter Status xml (drawable / round_edges_pressed.xml). Der einzige Unterschied ist in der Farbe ...

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

Dann erledigt der folgende Code den Job

Globale Variable:

public int layoutpressed = -1;

In 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
quelle
6

Stellen Sie einfach diese Attribute ein

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

Fügen Sie dem linearen Layout einfach den Hintergrund attr / selectableItemBackground hinzu und machen Sie das lineare Layout anklickbar

Beispiel:

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

Dadurch verhält sich das lineare Layout beim Drücken wie eine Taste. :) :)

Exel Staderlin
quelle
1

Dies war hilfreich, aber wenn Sie eine Hintergrundfarbe einfügen und das lineare Layout wie das Listenelement anklickbar machen möchten. Stellen Sie den Hintergrund mit Ihrer bevorzugten Farbe ein und setzen Sie die Vordergrundfarbe auf? Android: attr / selectableItemBackground, setzen Sie focusable true und clickable true

Beispielcode

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

In früheren Antworten ging es darum, wie der Standardhintergrund in einer XML-Datei festgelegt wird. Hier dasselbe im Code:

linearLayout1.setBackgroundResource(android.R.drawable.list_selector_background);
Yuliskov
quelle