Android에서 버튼 클릭 효과를 설정하는 방법은 무엇입니까?


105

Android에서 배경 이미지를 Button으로 설정하면 버튼에 아무런 영향을주지 않습니다.

사용자가 버튼이 클릭되었음을 알 수 있도록 버튼에 약간의 효과가 필요합니다.

버튼을 클릭했을 때 몇 초 동안 어두워 야하는데 어떻게해야합니까?

감사.



다음 메서드를 사용하면 단일 스타일 클래스를 사용하여 텍스트에 관계없이 모든 버튼을 스키닝 할 수 있습니다. stackoverflow.com/questions/5327553/…
Zack Marrapese

아니 이미지 버튼을 사용하고 있지 않습니다. 일반 버튼을 사용하고 있습니까?
Jignesh Ansodariya

3
그것의 아주 좋은 튜토리얼 : dibbus.com/2011/02/gradient-buttons-for-android
Pratik Butani

답변:


154

버튼 상태 목록이 포함 된 드로어 블 xml 파일을 생성하면됩니다. 예를 들어 다음 코드를 사용하여 "button.xml"이라는 새 xml 파일을 만드는 경우 :

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/YOURIMAGE" />
    <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/gradient" />
    <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/gradient" />
    <item android:drawable="@drawable/YOURIMAGE" />
</selector>

누를 때 어둡게 표시된 배경 이미지를 유지하려면 두 번째 xml 파일을 만들고 다음 코드를 사용하여 gradient.xml이라고합니다.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <bitmap android:src="@drawable/YOURIMAGE"/>
    </item>
    <item>
        <shape xmlns:android="http://schemas.android.com/apk/res/android">
            <gradient android:angle="90" android:startColor="#880f0f10" android:centerColor="#880d0d0f" android:endColor="#885d5d5e"/>
        </shape>
    </item>
</layer-list>

버튼의 xml에서 배경을 버튼 xml로 설정하십시오.

android:background="@drawable/button"

도움이 되었기를 바랍니다!

편집 : 위의 코드가 블록 색상이 아닌 버튼에 이미지 (YOURIMAGE)를 표시하도록 변경했습니다.


그럼 난 세트 이미지로, 버튼 배경 이미지를 설정할 수는 필수입니다
Jignesh Ansodariya

1
상태 XML과 함께 배경 이미지를 사용하는 방법을 보여주기 위해 편집되었습니다. YOURIMAGE를 드로어 블 디렉터리의 이미지 리소스로 바꿉니다.
Ljdawson

버튼의 src가 직사각형 인 경우에만 작동합니다. src 드로어 블이 그것과 다른 모양을 가지고 있다면, 그래디언트도 배경에 적용될 것이고 이것은 슬프다.
Renato Lochetti 2013 년

별로 항상 레이어 목록에서 다른 모양 사용할 수 있습니다
Ljdawson

2
내가 이미지를 사용하는 동안 그것은 나를 위해 작동합니다 ..하지만 내가 Xml 배경을 사용할 때. 작동하지 않습니다 ...
DKV

88

이미지 버튼이 많고 모든 버튼에 대해 xml-s를 작성하고 싶지 않을 때 더 간단합니다.

Kotlin 버전 :

fun buttonEffect(button: View) {
    button.setOnTouchListener { v, event ->
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                v.background.setColorFilter(-0x1f0b8adf, PorterDuff.Mode.SRC_ATOP)
                v.invalidate()
            }
            MotionEvent.ACTION_UP -> {
                v.background.clearColorFilter()
                v.invalidate()
            }
        }
        false
    }
}

자바 버전 :

public static void buttonEffect(View button){
    button.setOnTouchListener(new OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    v.getBackground().setColorFilter(0xe0f47521,PorterDuff.Mode.SRC_ATOP);
                    v.invalidate();
                    break;
                }
                case MotionEvent.ACTION_UP: {
                    v.getBackground().clearColorFilter();
                    v.invalidate();
                    break;
                }
            }
            return false;
        }
    });
}

2
나는 이것을 내 코드에서 사용하고 지금까지 주목 한 유일한 문제는 버튼이 ScrollView에 배치되었을 때 이상하게 작동한다는 것입니다.
Finnboy11 2013 년

정말 훌륭한 해결책이 올바른 해답이 될 수 있어야
Biraj Zalavadia

이것이 어떻게 더 낫습니까? 디자인은 코드 외부에서 유지되어야합니다. 그렇지 않습니까?
버그 발생

이 문제에 대한 간단한 해결책입니다. 버튼이 많고 모든 버튼에 대해 xml을 만들고 싶지 않을 때 도움이 될 수 있습니다.
András

세상에! 프래그먼트에 5 개의 버튼이 있다고 상상해보세요 ...이 보일러 플레이트 코드 전체를 갖게 될 것입니다 ... 그러면 어떻게 리팩토링할까요? 모든 활동의 모든 버튼에 대한 색상 필터를 변경 하시겠습니까? 그것은 다음 개발자가 그렇게 행복하지 않을 것입니다 이럴 ..
레오 Droidcoder

84

당신의 생성 AlphaAnimation얼마나 많은 버튼의 페이딩 효과가있을 것입니다 결정 개체, 다음이에서 시작하자 onClickListener당신의 버튼

예 :

private AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.8F);

// some code

public void onClick(View v) {
    v.startAnimation(buttonClick);
}

물론 이것은 가장 선호하는 방법이 아닌 방법 일뿐입니다.


5
이 솔루션에 대해 제가 좋아하는 점은 각각 고유 한 사용자 지정 이미지가있는 많은 버튼이있을 때 많은 선택기를 만들 필요가 없다는 것입니다.
Pete

2
이렇게하면 터치 다운시 버튼이 페이드되지 않으며, 클릭이 감지되고 사용자의 손가락이 이미 들어간 후 몇 초 동안 만 페이드됩니다.
Doug Voss 2017

1
니스와 간단한

@Doug Voss이, 당신은 더 이상 그것을 만들기 위해 애니메이션의 지속 시간을 설정할 수 있습니다
아메드 아델 이스마일에게

onLongClick과 'circularReveal'은 어떻습니까?
Acauã Pitta 2019

44

클릭 가능한 효과를 얻기 위해 단순히 전경사용할 수 있습니다 View.

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


어두운 테마와 함께 사용하기 위해도 추가 테마layout(클릭 효과를 명확하게) :

android:theme="@android:style/ThemeOverlay.Material.Dark"

5
구현하는 가장 쉬운 방법입니다. 참고로, android : foreground 속성은 23보다 낮은 API 레벨에 영향을주지 않습니다.
dolgom

1
가장 간단한 솔루션.
Jerry Chong

2
이것은 훨씬 더 간단하고 멋진 잔물결 애니메이션 효과를 추가합니다.
Tyler

1
@dolgom API 레벨 <23 인 경우 "background"속성에서 사용합니다. 따라서 : android : background = "? android : attr / selectableItemBackground"
Z3R0

24

항목이 시스템 룩앤필과 일치하도록하려면 android:attr/selectableItemBackground원하는보기의 배경 또는 전경 태그에서 시스템 속성 을 참조하십시오 .

<ImageView
    ...
    android:background="?android:attr/selectableItemBackground"      
    android:foreground="?android:attr/selectableItemBackground"
    ...
/>

두 속성을 모두 사용하여 각각 API 레벨 23 전후에 원하는 효과를 얻으십시오.

https://stackoverflow.com/a/11513474/4683601


2
지금까지 가장 간단한 솔루션입니다. 감사!
tykom

9

또는 하나의 배경 이미지 만 사용하여 클릭 효과를 얻을 수 있습니다. setOnTouchListener

두 가지 방법

((Button)findViewById(R.id.testBth)).setOnTouchListener(new OnTouchListener() {

      @Override
        public boolean onTouch(View v, MotionEvent event) {
          switch (event.getAction()) {
              case MotionEvent.ACTION_DOWN: {
                  Button view = (Button) v;
                  view.getBackground().setColorFilter(0x77000000, PorterDuff.Mode.SRC_ATOP);
                  v.invalidate();
                  break;
              }
              case MotionEvent.ACTION_UP:
                  // Your action here on button click
              case MotionEvent.ACTION_CANCEL: {
                  Button view = (Button) v;
                  view.getBackground().clearColorFilter();
                  view.invalidate();
                  break;
              }
          }
          return true;
        }
});

여기에 이미지 설명 입력

을 사용하지 않으려는 경우 setOnTouchLister이를 달성하는 또 다른 방법은

    myButton.getBackground().setColorFilter(.setColorFilter(0xF00, Mode.MULTIPLY);

    StateListDrawable listDrawable = new StateListDrawable();
    listDrawable.addState(new int[] {android.R.attr.state_pressed}, drawablePressed);
    listDrawable.addState(new int[] {android.R.attr.defaultValue}, myButton);

    myButton.setBackgroundDrawable(listDrawable);

두 번째 방법으로 코드에 오류가 있습니다. getCurrent () 함수는 무엇입니까? 또한 myButton은 Drawable이 아니므로 상태로 추가 할 수 없습니다.
Ehtesham Hasan 2016 년

오류를 지적 해 주셔서 감사합니다. 나는 그것을 수정했고 myButton은 setBackgroundDrawable 메소드를 제공하는 Button 클래스의 인스턴스이며 Drawable 인스턴스를 취하므로 작동합니다.
Vinayak Bevinakatti 2016 년

두 번째 접근 방식을 기반으로 한 내 대답을 확인하십시오. stackoverflow.com/a/39430738/5229515
Ehtesham Hasan 2016 년

이벤트를 사용하지 않고 추가 onClickListeners를 호출 할 수 있도록 끝에 "return false"가 있어야합니다.
Doug Voss 2017

3

이 작업을 수행하는 또 다른 쉬운 방법을 추가하고 싶습니다 : ImageButton이 배경을 유지하고 null로 설정하지 않으면 일반 버튼처럼 작동하고 다른 버튼과 똑같이 클릭하는 동안 클릭 애니메이션이 표시됩니다. 아직 거기에있는 동안 배경 :

<ImageButton
    android:id="@+id/imageButton2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingBottom="1dp"
    android:paddingLeft="1dp"
    android:paddingRight="1dp"
    android:paddingTop="1dp"
    android:src="@drawable/squareicon" />

패딩은 배경이 보이지 않게하고 버튼이 다른 버튼처럼 작동하도록합니다.


1
원형 인 경우 이미지 주위에 사각형 버튼 테두리가 유지됩니다.
MSaudi

3

이것은 @Vinayak의 답변에서 힌트를 얻은 최고의 솔루션입니다. 다른 모든 솔루션에는 다른 단점이 있습니다.

우선 이와 같은 함수를 만듭니다.

void addClickEffect(View view)
{
    Drawable drawableNormal = view.getBackground();

    Drawable drawablePressed = view.getBackground().getConstantState().newDrawable();
    drawablePressed.mutate();
    drawablePressed.setColorFilter(Color.argb(50, 0, 0, 0), PorterDuff.Mode.SRC_ATOP);

    StateListDrawable listDrawable = new StateListDrawable();
    listDrawable.addState(new int[] {android.R.attr.state_pressed}, drawablePressed);
    listDrawable.addState(new int[] {}, drawableNormal);
    view.setBackground(listDrawable);
}

설명:

getConstantState (). newDrawable ()은 기존 Drawable을 복제하는 데 사용됩니다. 그렇지 않으면 동일한 드로어 블이 사용됩니다. 여기에서 더 읽기 : Android : 필터를 사용하여 StateListDrawable을 만들기 위해 드로어 블 복제

mutate ()는 Drawable 복제본이 다른 Drawable 인스턴스와 상태를 공유하지 않도록 만드는 데 사용됩니다. 여기에서 자세히 알아보세요 : https://developer.android.com/reference/android/graphics/drawable/Drawable.html#mutate ()

용법:

모든 유형의보기 (버튼, 이미지 버튼,보기 등)를 매개 변수로 함수에 전달할 수 있으며 클릭 효과가 적용됩니다.

addClickEffect(myButton);
addClickEffect(myImageButton);

2
Step: set a button in XML with onClick Action:

 <Button
android:id="@+id/btnEditUserInfo"
style="?android:borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/txt_height"
android:layout_gravity="center"
android:background="@drawable/round_btn"
android:contentDescription="@string/image_view"
android:onClick="edit_user_info"
android:text="Edit"
android:textColor="#000"
android:textSize="@dimen/login_textSize" />

Step: on button clicked show animation point
//pgrm mark ---- ---- ----- ---- ---- ----- ---- ---- -----  ---- ---- -----

    public void edit_user_info(View view) {

        // show click effect on button pressed
        final AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.8F);
        view.startAnimation(buttonClick);

        Intent intent = new Intent(getApplicationContext(),  EditUserInfo.class);
        startActivity(intent);

    }// end edit_user_info

2

Material Design 상태 누름 / 클릭 효과에 RippleDrawable을 사용합니다.

이를 위해 / drawable 폴더 아래에 .xml로 잔물결 항목을 생성하고 모든 뷰에 대해 android : background에서 사용합니다.

  • 누르거나 클릭 한 아이콘에 대한 효과, 원형 물결 효과를 사용합니다. 예 :

    <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@android:color/darker_gray" />

  • 직사각형 경계로 클릭 한 뷰에 대한 효과, 다음과 같이 기존 드로어 블 위에 리플을 추가 할 수 있습니다.

    <?xml version="1.0" encoding="utf-8"?> <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="#000000"> <item android:drawable="@drawable/your_background_drawable"/> </ripple>


2

모든보기를 위해

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

그러나 고도 사용이있는 카드 뷰의 경우

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

툴바와 같은 원형 클릭 효과

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

또한 설정해야합니다

 android:clickable="true"
 android:focusable="true"

0

Andràs 답변에 약간의 추가 작업 :

당신이 사용할 수있는 postDelayed더 눈에 띄는 할 시간의 작은 기간 동안 컬러 필터 마지막을 만들기 위해 :

        @Override
        public boolean onTouch(final View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    v.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
                    v.invalidate();
                    break;
                }
                case MotionEvent.ACTION_UP: {
                    v.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            v.getBackground().clearColorFilter();
                            v.invalidate();
                        }
                    }, 100L);
                    break;
                }
            }
            return false;
        }

필요에 맞게 지연 100L 값을 변경할 수 있습니다.


0

IMG 대신 xml 배경을 사용하는 경우 다음을 제거하십시오.

<item>
    <bitmap android:src="@drawable/YOURIMAGE"/>
</item>

@Ljdawson이 우리에게 준 첫 번째 답변에서.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.