使LinearLayout像按钮一样


100

我有一个LinearLayout样式类似于的样式button,其中包含一些text / ImageView元素。我想使整个LinearLayout动作像a一样button,特别是要赋予它在a中定义的状态,以便在按下时具有不同的背景。

有没有比ImageButton确定整个Layout的大小和绝对定位更好的方法?


如果有人正在寻找一种突出显示按下时(如Button)突出显示TableRow(继承自LinearLayout的方法)的方法,请参见stackoverflow.com/a/8204768/427545
Lekensteyn,2012年

1
如果有人想获得完整的解决方案,请检查此存储库:github.com/shamanland/AndroidLayoutSelector,其中有一个自定义的clickable / checkableLinearLayout例如ToggleButton
OleksiiK。13年

Answers:


154

我刚才遇到了这个问题。您必须将LinearLayout设置为clickable。您可以在XML中使用

android:clickable="true"

或在代码中

yourLinearLayout.setClickable(true);

干杯!


2
下面的答案要好得多!
Zach Sperske 2015年

2
另外,如果您将“ clickable”元素作为其子元素,请不要忘记添加该元素android:clickable="false"以防止其阻止点击事件。
TheKalpit'3

没必要,添加点击侦听器对我来说就足够了,如果您不希望点击侦听器,为什么要让某些内容可点击?
hmac

158

如果要添加Android默认背景行为以使Layout行为类似“ clikable” View,请针对Layout

API 11+(纯Android):

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

API 7+(Android + AppCompat支持库):

android:background="?attr/selectableItemBackground"

任何API:

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

上面的答案仍然是正确的,但仅添加默认的按下和释放的UI状态(例如在a ListView中)并没有帮助我。


为您+1,如果您需要UI触摸反馈,但又想自己处理click-logic(而不是被迫指定onClickX方法,这是android:clickable的要求)
那就太好了

2
这也适用于材料设计波动。最佳答案。
米罗·马克拉瓦内斯

3
好!按下时,效果像橙色/黄色一样。我想将颜色更改为绿色。怎么做?
韩怀特金

@HanWhiteking你知道了吗?
JacobSánchez19年

16

我使用了第一个和第二个答案。但是我的linearlayout具有带有背景颜色的图像和文本,因此我不得不将“背景”更改为“前景”

线性布局

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

9

首先,您需要一个选择器来定义不同的状态。例如,在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>

我没有尝试过,但是您可以将LinearLayout的android:background设置为此选择器,并将android:clickable设置为true即可使用。

如果不是,则可以切换为使用RelativeLayout,并使第一个元素成为一个按钮,以该选择器为背景,并以fill_parent作为其布局的宽度和高度。在这种情况下,只需使用常规Button并将android:background设置为选择器即可。您不必在按钮上输入文字。


是的,我赞成使用实际的Button。您可以重写onDraw(Canvas)以执行所需的任何特殊操作(即在按钮内绘制图像或文本)。
戴夫

1
谢谢!设置LinearLayout的背景是可行的,并且它会响应触摸事件,几乎–如果我直接按下LinearLayout,其状态就会更新。如果我按一下其中的TextView,触摸事件似乎并不能弥补LinearLayout的不足。知道如何使Layout命中测试吗?
詹森·普拉多

在TextView上尝试android:clickable =“ false”。还没有尝试过,但是单击TextViews并没有问题。可能是因为您的TextView具有背景。
2011年

尽管没有发出咔嗒声,但这确实可以解决问题。有没有办法做到这一点?
史蒂文·

@Steven刚刚看到您的旧评论,对不起。我认为点击声音与分配onClickListener有关。我在onTouchListener上放置了一些东西,直到我还添加了onClickListener(带有空的onClick方法)后,它才会单击。
Tenfour04 2014年

7

在应用程序中,我需要动态创建LinearLayout。在这种情况下,命令

ll.setClickable(true);

无法正常工作。尽管我可能会错过一些东西,但是我设法利用setOnTouchListener来获得相同的结果,并在有人有相同需求的情况下提交了代码。

下面的代码创建一个带有两个textview和圆角的LinearLayout,按下时会更改颜色。

首先,在drawable文件夹中创建两个xml文件,一个用于普通文件,另一个用于按线性布局状态。

正常状态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>

按下状态xml(drawable / rounded_edges_pressed.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="#add8e6" />
            <corners android:radius="7dp" />
        </shape>
    </item>
</layer-list>

然后下面的代码完成工作

全局变量:

public int layoutpressed = -1;

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

只需设置这些属性

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

5

只需将背景attr / selectableItemBackground添加到线性布局,并使该linearlayout可点击

例如:

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

这使得linearlayout在按下时就像按钮一样。:)


1

这很有用,但是如果您要设置背景色并使线性布局像列表项一样可单击。将背景设置为您喜欢的颜色,并将前景色设置为?android:attr / selectableItemBackground,设置focusable true和clickable true

样例代码

   <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

先前的询问者是关于如何在xml文件中设置默认背景的。代码中的相同内容:

linearLayout1.setBackgroundResource(android.R.drawable.list_selector_background);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.