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.