Programing

Android에서 버튼과 같은 이미지보기 클릭 효과를 제공하려면 어떻게해야합니까?

lottogame 2020. 10. 11. 08:59
반응형

Android에서 버튼과 같은 이미지보기 클릭 효과를 제공하려면 어떻게해야합니까?


내 Android 앱에 onClick 이벤트가있는 버튼처럼 사용중인 imageview가 있지만, 클릭 할 때 imageview에 클릭 가능한 효과를주지 않는다고 짐작할 수 있습니다. 어떻게 할 수 있습니까?


클릭 / 클릭되지 않은 상태에 대해 서로 다른 이미지를 디자인하고 다음과 같이 onTouchListener에서 설정할 수 있습니다.

final ImageView v = (ImageView) findViewById(R.id.button0);
        v.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View arg0, MotionEvent arg1) {
                switch (arg1.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    v.setImageBitmap(res.getDrawable(R.drawable.img_down));
                    break;
                }
                case MotionEvent.ACTION_CANCEL:{
                    v.setImageBitmap(res.getDrawable(R.drawable.img_up));
                    break;
                }
                }
                return true;
            }
        });

더 나은 선택은 다음과 같이 선택자를 정의하는 것입니다.

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true"   
        android:drawable="@drawable/img_down" />
    <item android:state_selected="false"   
        android:drawable="@drawable/img_up" />
</selector>

이벤트에서 이미지를 선택하십시오.

v.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View arg0, MotionEvent arg1) {
                v.setSelected(arg1.getAction()==MotionEvent.ACTION_DOWN);
                return true;
            }
        });

다음과 같은 것을 사용하여 단일 이미지로이를 수행 할 수 있습니다.

     //get the image view
    ImageView imageView = (ImageView)findViewById(R.id.ImageView);

    //set the ontouch listener
    imageView.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    ImageView view = (ImageView) v;
                    //overlay is black with transparency of 0x77 (119)
                    view.getDrawable().setColorFilter(0x77000000,PorterDuff.Mode.SRC_ATOP);
                    view.invalidate();
                    break;
                }
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL: {
                    ImageView view = (ImageView) v;
                    //clear the overlay
                    view.getDrawable().clearColorFilter();
                    view.invalidate();
                    break;
                }
            }

            return false;
        }
    });

더 쉽게 재사용 할 수 있도록 ImageView의 하위 클래스 (또는 ImageView의 하위 클래스 인 ImageButton)로 만들 것입니다. 그러나 이렇게하면 "선택된"모양을 imageview에 적용 할 수 있습니다.


그것은 함께 할 수있어 하나의 이미지 파일 ColorFilter 방법을 사용. 그러나 ColorFilter는 Button이 아닌 ImageView와 함께 작동 할 것으로 예상하므로 버튼을 ImageView로 변환해야합니다. 어쨌든 이미지를 버튼으로 사용하는 경우 문제가되지 않지만 텍스트가 있으면 더 짜증이납니다 ... 어쨌든 텍스트 문제를 해결하는 방법을 찾은 경우 사용할 코드는 다음과 같습니다.

ImageView button = (ImageView) findViewById(R.id.button);
button.setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);

버튼에 빨간색 오버레이가 적용됩니다 (색상 코드는 완전히 불투명 한 빨간색의 16 진수 코드입니다. 처음 두 자리는 투명성이고 그다음은 RR GG BB입니다.)


편집 : 아래의 원래 답변이 작동하고 설정하기 쉽지만 더 효율적인 구현을 원하거나 필요로하는 경우 Google의 Android Developer Advocate 가이 게시물참조하십시오 . 또한 android:foreground속성은 Android M에서 기본적으로 ImageView를 포함한 모든보기 에 제공됩니다.


ImageView에 대한 선택기를 사용할 때의 문제는보기의 배경으로 만 설정할 수 있다는 것입니다. 이미지가 불투명 한 한 그 뒤에있는 선택기의 효과를 볼 수 없습니다.

트릭은 콘텐츠에 android:foreground대한 오버레이 를 정의 할 수 있는 속성 을 사용 하여 FrameLayout에 ImageView를 래핑하는 것입니다 . android:foreground선택기로 설정 하고 (예 : ?android:attr/selectableItemBackgroundAPI 레벨 11+ OnClickListener의 경우)를 ImageView 대신 FrameLayout에 연결 하면 이미지가 선택기의 드로어 블 (원하는 클릭 효과)로 오버레이됩니다!

보다:

<FrameLayout
    android:id="@+id/imageButton"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:foreground="?android:attr/selectableItemBackground" >

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/yourImageFile" />

</FrameLayout>

(이는 부모 레이아웃 내에 있어야합니다.)

final View imageButton = findViewById(R.id.imageButton);
imageButton.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View view) {
        // do whatever we wish!
    }
});

사용 스타일 = "안드로이드 : borderlessButtonStyle" XML 파일입니다. Android 기본 클릭 효과가 표시됩니다.

<ImageView
    android:id="@+id/imageView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_launcher" 
    style="?android:borderlessButtonStyle"
/>

ImageButton을 사용하기 만하면 됩니다.


이를 해결하는 간단한 방법은 다음과 같습니다.

ImageView iv = (ImageView) findViewById(R.id.imageView);

iv.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        //Agrega porcentajes de cada fraccion de grafica pastel

        Animation animFadein = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fade_in);

        iv.startAnimation(animFadein);
    });

파일 res/anim/fade_in.xml:

<?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:fillAfter="true" >

<alpha
    android:duration="100"
    android:fromAlpha="0.0"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toAlpha="1.0" />
 </set>

선택기 드로어 블 선택 정의

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true"   
        android:drawable="@drawable/img_down" />
    <item android:state_selected="false"   
        android:drawable="@drawable/img_up" />
</selector>

android : state_selected 대신 android : state_pressed를 사용해야합니다.

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

선택 가능한 배경을 ImageView로 설정하고 패딩을 추가합니다. 그런 다음 OnClickListener.

<ImageView
    android:id="@+id/your_image_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/your_image"
    android:padding="10dp"
    android:background="?android:attr/selectableItemBackground"/>

android:background="@android:drawable/list_selector_background"기본 "알람 시계"(현재 탁상 시계)의 "알람 추가"와 동일한 효과를 얻으 려고 시도 할 수 있습니다.


이것은 나를 위해 일했습니다.

img.setOnTouchListener(new OnTouchListener(){

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction())
                {
                    case MotionEvent.ACTION_DOWN:
                    {
                        ((ImageView)v).setImageAlpha(200);
                        break;
                    }
                    case MotionEvent.ACTION_MOVE:
                    {
                        // if inside bounds
                        if(event.getX() > 0 && event.getX() < v.getWidth() && event.getY() > 0 && event.getY() < v.getHeight())
                        {
                            ((ImageView)v).setImageAlpha(200);
                        }
                        else
                        {
                            ((ImageView)v).setImageAlpha(255);
                        }

                        break;
                    }
                    case MotionEvent.ACTION_UP:
                    {
                        ((ImageView)v).setImageAlpha(255);
                    }
                }
                return true;
            }

        });

@Edit : Gunhan이 말했듯이 setImageAlpha 메서드에는 하위 호환성 문제가있을 것입니다. 이 방법을 사용했습니다.

public static void setImageAlpha(ImageView img, int alpha)
    {
        if(Build.VERSION.SDK_INT > 15)
        {
            img.setImageAlpha(alpha);
        }
        else
        {
            img.setAlpha(alpha);
        }
    }

나는 비슷한 일을한다 당신에게 적합한 지 아닌지

프레스 효과 도우미보기 :

  • 사용법 : iOS와 같은 간단한 프레스 효과 수행

    간단한 사용법 :

  • ImageView img = (ImageView) findViewById (R.id.img);

  • ViewPressEffectHelper.attach (img)

https://gist.github.com/extralam/7489370


위의 모든 답변과 함께 ImageView를 누르고 상태를 변경하고 싶었지만 사용자가 이동하면 "취소"하고 onClickListener를 수행하지 않았습니다.

결국 클래스 내에서 Point 객체를 만들고 사용자가 ImageView를 누를 때 좌표를 설정했습니다. MotionEvent.ACTION_UP에서 새로운 포인트를 기록하고 포인트를 비교했습니다.

잘 설명 할 수밖에 없지만 여기에 제가 한 일이 있습니다.

// set the ontouch listener
weatherView.setOnTouchListener(new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // Determine what action with a switch statement
        switch (event.getAction()) {

        // User presses down on the ImageView, record the original point
        // and set the color filter
        case MotionEvent.ACTION_DOWN: {
            ImageView view = (ImageView) v;

            // overlay is black with transparency of 0x77 (119)
            view.getDrawable().setColorFilter(0x77000000,
                    PorterDuff.Mode.SRC_ATOP);
            view.invalidate();

            p = new Point((int) event.getX(), (int) event.getY());
            break;
        }

        // Once the user releases, record new point then compare the
        // difference, if within a certain range perform onCLick
        // and or otherwise clear the color filter
        case MotionEvent.ACTION_UP: {
            ImageView view = (ImageView) v;
            Point f = new Point((int) event.getX(), (int) event.getY());
            if ((Math.abs(f.x - p.x) < 15)
                    && ((Math.abs(f.x - p.x) < 15))) {
                view.performClick();
            }
            // clear the overlay
            view.getDrawable().clearColorFilter();
            view.invalidate();
            break;
        }
        }
        return true;
    }
});

imageView에 onClickListener가 설정되어 있지만 메서드가 될 수 있습니다.


setPressedonTouchEvent 리스너를 만드는 대신 ImageView에서 재정의 하고 여기에서 색상 필터링을 수행 할 수 있습니다 .

@Override
public void setPressed(boolean pressed) {
    super.setPressed(pressed);

    if(getDrawable() == null)
        return;

    if(pressed) {
        getDrawable().setColorFilter(0x44000000, PorterDuff.Mode.SRC_ATOP);
        invalidate();
    }
    else {
        getDrawable().clearColorFilter();
        invalidate();
    }
}

을 바탕으로 씨 죤의 대답 , 내 추상적 인 유틸리티 클래스의 정적 메서드를 사용합니다 :

public abstract class Utility {
...

    public static View.OnTouchListener imgPress(){
        return imgPress(0x77eeddff); //DEFAULT color
    }

    public static View.OnTouchListener imgPress(final int color){
        return new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch(event.getAction()) {

                    case MotionEvent.ACTION_DOWN: {
                        ImageView view = (ImageView) v;
                        view.getDrawable().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
                        view.invalidate();
                        break;
                    }

                    case MotionEvent.ACTION_UP:
                        v.performClick();

                    case MotionEvent.ACTION_CANCEL: {
                        ImageView view = (ImageView) v;

                        //Clear the overlay
                        view.getDrawable().clearColorFilter();
                        view.invalidate();
                        break;
                    }
                }

                return true;
            }
        };
    }

    ...
}

그런 다음 onTouchListener와 함께 사용합니다.

ImageView img=(ImageView) view.findViewById(R.id.image);
img.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) { /* Your click action */ }
});
img_zc.setOnTouchListener(Utility.imgPress()); //Or Utility.imgPress(int_color_with_alpha)

많은 이미지가 있고 XML 드로어 블없이 하나의 이미지 만있는 간단한 onTouch 효과를 원하는 경우 매우 간단합니다.


를 사용 android.widget.Button하고 background속성을 android.graphics.drawable.StateListDrawable. 이 모든 작업은 XML 또는 프로그래밍 방식으로 수행 할 수 있습니다. Form Stuff 자습서Custom Button 섹션을 참조하십시오 .


여기샘플을 만들고 레이아웃에서 ImageView를 ClickableImageView 로 변경 하십시오. 도움이 되었기를 바랍니다.

여기에 이미지 설명 입력


배경 이미지를 사용하면 더 많은 뷰티 솔루션이 있습니다. :)

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

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

또는:

이 양식을 이미지 버튼과 함께 사용할 수 있습니다.

파일 생성 res/drawable/btn_video.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/image"
        android:state_pressed="true" />
    <item android:drawable="@drawable/ico2"
        android:state_focused="true" />
    <item android:drawable="@drawable/ico2" />
</selector>

그리고 res/layout/activity_main.xml:

<ImageButton
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/imageButton"
    android:layout_gravity="center_horizontal"
    android:onClick="eventImageBtn"
    android:background="@drawable/btn_video"
    android:adjustViewBounds="true"
    android:scaleType="fitXY"
/>

클릭 한 번으로 이미지가 변경되고 선형 레이아웃으로 조정할 수 있습니다.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="@color/menu_item_background">

        <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"
                      android:paddingLeft="@dimen/main_screen_side_padding" android:paddingRight="@dimen/main_screen_side_padding" android:paddingTop="@dimen/main_screen_side_padding" android:paddingBottom="@dimen/main_screen_side_padding"
                      android:background="#ffb3ff13" android:weightSum="10.00">


            <LinearLayout android:layout_weight="2.50" android:background="#ff56cfcd" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" >

                <ImageButton
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:id="@+id/imageButton"
                    android:layout_gravity="center_horizontal"
                    android:onClick="eventImageBtn"
                    android:background="@drawable/btn_video"
                    android:adjustViewBounds="true"
                    android:scaleType="fitXY"
                />
            </LinearLayout>

            <LinearLayout android:layout_weight="0.50" android:layout_height="0dp" android:background="#ffffffff" android:orientation="vertical" android:layout_width="fill_parent" >
            </LinearLayout>

            <LinearLayout android:layout_weight="4.50" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" android:background="#ff8aa5ff">
            </LinearLayout>

            <LinearLayout android:layout_weight="0.50" android:layout_height="0dp" android:background="#ffffffff" android:orientation="vertical" android:layout_width="fill_parent" >
            </LinearLayout>

            <LinearLayout android:layout_weight="2.00" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" android:background="#ffff7d1a" >
            </LinearLayout>

        </LinearLayout>
    </LinearLayout>
</ScrollView>

탭했을 때 리플을 원하는 경우 다음 코드로 제공 할 수 있습니다.

<ImageView
    ...
    android:background="?attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    ...
</ImageView>

마찬가지로 TextView에 대한 클릭 효과를 구현할 수 있습니다.

<TextView
    ...
    android:background="?attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    ...
</TextView>

Thanks for the help on this thread. However, you missed one thing...you need to handle the ACTION_CANCEL as well. If you don't then you might not properly restore the alpha value of the ImageView in the event that a parent view in the view hierarchy intercepts a touch event (think a ScrollView wrapping you ImageView).

Here is a complete class that is based off the above class but takes care of the ACTION_CANCEL as well. It uses an ImageViewCompat helper class to abstract the differences in the pre-post JellyBean API.

public class ChangeAlphaOnPressedTouchListener implements OnTouchListener {

    private final float pressedAlpha;

    public ChangeAlphaOnPressedTouchListener(float pressedAlpha) {
        this.pressedAlpha = pressedAlpha;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        ImageView iv = (ImageView) v;
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            ImageViewCompat.setAlpha(iv, pressedAlpha);
            break;

        case MotionEvent.ACTION_MOVE:
            if (isInsideViewBounds(v, event)) {
                ImageViewCompat.setAlpha(iv, pressedAlpha);
            } else {
                ImageViewCompat.setAlpha(iv, 1f);
            }
            break;
        case MotionEvent.ACTION_UP:
            ImageViewCompat.setAlpha(iv, 1f);
            break;
        case MotionEvent.ACTION_CANCEL:
            ImageViewCompat.setAlpha(iv, 1f);
        }
        return false;
    }

    private static boolean isInsideViewBounds(View v, MotionEvent event) {
        return event.getX() > 0 && event.getX() < v.getWidth() && event.getY() > 0
                && event.getY() < v.getHeight();
    }
}

Here is my code. The idea is that ImageView gets color filter when user touches it, and color filter is removed when user stops touching it.

Martin Booka Weser, András, Ah Lam, altosh, solution doesn't work when ImageView has also onClickEvent. worawee.s and kcoppock (with ImageButton) solution requires background, which has no sense when ImageView is not transparent.

This one is extension of AZ_ idea about color filter.

class PressedEffectStateListDrawable extends StateListDrawable {

    private int selectionColor;

    public PressedEffectStateListDrawable(Drawable drawable, int selectionColor) {
        super();
        this.selectionColor = selectionColor;
        addState(new int[] { android.R.attr.state_pressed }, drawable);
        addState(new int[] {}, drawable);
    }

    @Override
    protected boolean onStateChange(int[] states) {
        boolean isStatePressedInArray = false;
        for (int state : states) {
            if (state == android.R.attr.state_pressed) {
                isStatePressedInArray = true;
            }
        }
        if (isStatePressedInArray) {
            super.setColorFilter(selectionColor, PorterDuff.Mode.MULTIPLY);
        } else {
            super.clearColorFilter();
        }
        return super.onStateChange(states);
    }

    @Override
    public boolean isStateful() {
        return true;
    }
}

usage:

Drawable drawable = new FastBitmapDrawable(bm);
imageView.setImageDrawable(new PressedEffectStateListDrawable(drawable, 0xFF33b5e5));

I tried with:

<ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="@string/get_started"
        android:src="@drawable/home_started"
        style="?android:borderlessButtonStyle"
        android:adjustViewBounds="true"
        android:clickable="true"
        android:elevation="5dp"
        android:longClickable="true" />

and this worked. Please note on the line: style="?android:borderlessButtonStyle"


I think the easiest way is creating a new XML file. In this case, let's call it "example.xml" in the drawable folder, and put in the follow code:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/blue"
          android:state_pressed="true" />

</selector>

But before that you have to set the colors in the colors.xml file, in the values folder, like this:

<resources>
    <color name="blue">#0000FF</color>
</resources>

That made, you just set the Button / ImageButton to use the new layout, like this:

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/example"
/>

Then when you click that image, it will change to the color set in

<item android:drawable="@color/blue"
      android:state_pressed="true" />

giving the feedback that you want...


.This is the best solution I ever seen. Its more generic

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:fillAfter="true" >

<alpha
    android:duration="100"
    android:fromAlpha="0.0"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toAlpha="1.0" />
 </set>

Here's my solution, which, using "nineOldAndroids" library, supports old APIs too:

rootView.setOnTouchListener(new OnTouchListener() {

    @Override
    public boolean onTouch(final View v, final MotionEvent event) {

        switch (event.getAction()) {

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                v.setBackgroundResource(R.drawable.listview_normal);
                ViewHelper.setAlpha(imageView, 1);
                break;

            case MotionEvent.ACTION_DOWN:
                v.setBackgroundResource(0);
                v.setBackgroundColor(getResources().getColor(R.color.listview_pressed));
                ViewHelper.setAlpha(imageView, 0.75f);
                break;
        }
        return false;
    }
});

It assumes the rootView is the cell itself (the layout), and that it has a single imageView that you wish to be affected by the color that you wish to apply to the whole cell.


EDIT: if you wish, you can also extend ImageView to handle foreground, and set it to "?android:attr/selectableItemBackground". There is a library for this here and a tutorial on how to do it for any view you wish, here.


I think ImageButton is a better solution

<ImageButton
    android:layout_width="96dp"
    android:layout_height="56dp"
    android:src="@mipmap/ic_launcher"
    android:adjustViewBounds="true"
    android:background="@android:color/transparent"
    android:foreground="@drawable/selector" />

I did as follows in XML - with 0 padding around the image and ripple ontop of the image:

<ImageView
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@drawable/my_image"
    android:clickable="true"
    android:focusable="true"
    android:src="?android:attr/selectableItemBackground" />

지금은 머티리얼 디자인 실습을 개발해야합니다 . 이 경우 ImageView에 파급 효과를 추가 할 수 있습니다.


XML 속성을 추가하기 만하면됩니다. android : clickable = "true"...

참고 URL : https://stackoverflow.com/questions/4617898/how-can-i-give-an-imageview-click-effect-like-a-button-on-android

반응형