Wie kann ich einen Bildansicht-Klickeffekt wie eine Schaltfläche auf Android geben?

83

Ich habe eine Bildansicht in meiner Android-App, die ich wie eine Schaltfläche mit dem angegebenen onClick-Ereignis verwende, aber wie Sie vielleicht vermuten, gibt sie der Bildansicht beim Klicken keinen anklickbaren Effekt. Wie kann ich das erreichen?

Burak Dede
quelle

Antworten:

53

Sie können verschiedene Bilder für angeklickte / nicht angeklickte Zustände entwerfen und diese im onTouchListener wie folgt festlegen

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;
            }
        });

Die bessere Wahl ist, dass Sie einen Selektor wie folgt definieren

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

und wählen Sie das Bild im Ereignis aus:

v.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View arg0, MotionEvent arg1) {
                v.setSelected(arg1.getAction()==MotionEvent.ACTION_DOWN);
                return true;
            }
        });
Martin Booka Weser
quelle
1
Können Sie erklären, was res.getDrawable res macht?
VenushkaT
v.setSelected wird nur einmal == true sein und aufgrund von MotionEvent.ACTION_MOVE sofort auf false verschoben. Sobald der Finger losgelassen wird, tritt MotionEvent.ACTION_UP auf. Wenn Sie die Auswahlmethode verwenden, verwenden Sie eine separate Logik für setSelected oder setPressed. if (arg1.getAction () == MotionEvent.ACTION_DOWN) {v.setPressed (true); } else if (arg1.getAction () == MotionEvent.ACTION_UP) {v.setPressed (false); }
Adam Denoon
Es ist besser MotionEvent.ACTION_DOWN || MotionEvent.ACTION_MOVE, das Bild so lange anzuzeigen, wie wir drücken.
Alaa M.
Das musst du nicht setOnTouchListener(.... Sie können einfach das erstellen <selector ...>und dann das ImageView in XML anklickbar machen wie<ImageView ... android:clickable="true" android:focusable="true" android:src="@drawable/my_selector" />
Pierre
76

Sie können dies mit einem einzelnen Bild tun, indem Sie Folgendes verwenden:

     //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;
        }
    });

Ich werde dies wahrscheinlich zu einer Unterklasse von ImageView (oder ImageButton, da es auch eine Unterklasse von ImageView ist) machen, um die Wiederverwendbarkeit zu vereinfachen, aber dies sollte es Ihnen ermöglichen, ein "ausgewähltes" Aussehen auf eine Bildansicht anzuwenden.

Herr Zorn
quelle
2
Ich habe auch einen Fall für ACTION_CANCEL hinzugefügt, es funktioniert großartig, danke!
Alan
Guter Anruf - ich hatte das selbst in meinen eigenen Code eingefügt, werde ihn aber auch hier aktualisieren.
Herr Zorn
1
Dies mag eine andere Frage sein, aber wie würde ich nach ACTION_UP abbrechen? Insbesondere ... Benutzer trifft Bild. Der Benutzer zieht den Finger vom Bild, um den Vorgang abzubrechen. Aber Aktion wird nicht mit diesem Code abgebrochen
Sudocoder
Ich werde auch MotionEvent.ACTION_OUTSIDE hinzufügen;)
bonnyz
3
Vielleicht möchten Sie zurückkehren false, sonst wird das eigentliche onClick()Ereignis der Ansicht nicht ausgelöst
Nimrod Dayan
44

Mit der ColorFilter-Methode ist es möglich, mit nur einer Bilddatei zu arbeiten. ColorFilter erwartet jedoch, dass es mit ImageViews und nicht mit Schaltflächen funktioniert. Daher müssen Sie Ihre Schaltflächen in ImageViews umwandeln. Dies ist ohnehin kein Problem, wenn Sie Bilder als Schaltflächen verwenden, aber es ist ärgerlicher, wenn Sie Text hatten ... Angenommen, Sie finden einen Weg, um das Problem mit Text zu umgehen, ist hier der folgende Code:

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

Dadurch wird eine rote Überlagerung auf die Schaltfläche angewendet (der Farbcode ist der Hex-Code für vollständig undurchsichtiges Rot - die ersten beiden Ziffern sind Transparenz, dann RR GG BB.).

AZ_
quelle
3
Könnten Sie bitte erklären, was nach der Ausführung dieses Codes passieren wird und wo er aufgerufen werden soll? Ich habe versucht, diese beiden Zeilen bei der ImageView-Initialisierung aufzurufen. Mein Bild wird rot angezeigt, und dann passiert nichts, weder beim Klicken noch beim Berühren. Das gleiche gilt für Anrufe bei Berührung.
Wertschätzung
44

BEARBEITEN : Obwohl die ursprüngliche Antwort unten funktioniert und einfach einzurichten ist, lesen Sie diesen Beitrag eines Android Developer Advocate bei Google, wenn Sie eine effizientere Implementierung wünschen / benötigen. Beachten Sie außerdem, dass das android:foregroundAttribut in Android M standardmäßig für alle Ansichten , einschließlich ImageView, verfügbar ist.


Das Problem bei der Verwendung eines Selektors für eine ImageView besteht darin, dass Sie ihn nur als Hintergrund für die Ansicht festlegen können. Solange Ihr Bild undurchsichtig ist, wird der Effekt des Selektors dahinter nicht angezeigt.

Der Trick besteht darin, Ihre ImageView in ein FrameLayout mit dem Attribut zu verpacken, mit dem android:foregroundwir eine Überlagerung für den Inhalt definieren können. Wenn wir android:foregroundeinen Selektor ?android:attr/selectableItemBackgroundfestlegen (z. B. für API-Level 11+) und OnClickListenerdiesen anstelle der ImageView an das FrameLayout anhängen, wird das Bild mit dem Drawable unseres Selektors überlagert - dem gewünschten Klickeffekt!

Erblicken:

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

(Beachten Sie, dass dies in Ihrem übergeordneten Layout platziert werden sollte.)

final View imageButton = findViewById(R.id.imageButton);
imageButton.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View view) {
        // do whatever we wish!
    }
});
justasm
quelle
2
Toll ! Dies ist eine sehr gute Lösung. Dieselbe Lösung, die in der Kontaktanwendung für SMS- oder Anrufaktionen verwendet wird.
Jerry
Funktioniert nicht in API <11.? Android: attr / selectableItemBackground erfordert API-Level 11 (derzeit
mindestens
Das selectableItemBackgroundAttribut wurde nur in API-Ebene 11 hinzugefügt. Sie müssen daher einen anderen Selektor verwenden, wenn Sie diese Lösung für ältere API-Ebenen verwenden möchten. Für eine meiner Anwendungen, die API Level 7 unterstützt, verwende ich beispielsweise die @drawable/list_selector_holo_lightRessource, die mit dem Android Holo Colors Generator-Tool generiert wurde .
Justasm
Sie können das gleiche Verhalten mit nur 1 <ImageButton>mit selectableItemBackground erreichen!
Yohan Dahmani
28

Verwenden Sie style = "? Android: borderlessButtonStyle" in der XML-Datei. Es wird der Standard-Klickeffekt für Android angezeigt.

<ImageView
    android:id="@+id/imageView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_launcher" 
    style="?android:borderlessButtonStyle"
/>
Anjula
quelle
1
Dies ist eigentlich die beste Antwort,
viel
1
Dadurch wird die Auffüllung festgelegt. Selbst wenn Sie die Auffüllung auf 0 setzen und das von Ihnen angegebene Bild die gesamte Bildansicht einnimmt, werden beim Klicken keine Auswirkungen angezeigt.
Android-Entwickler
2
@androiddeveloper android:adjustViewBounds="true"zum Deaktivieren der Polsterung.
Hafez Divandari
1
Es wird empfohlen, style="?android:attr/borderlessButtonStyle"
Folgendes
21

Verwenden Sie einfach einen ImageButton .

Kevin Coppock
quelle
3
Ich persönlich kann es nicht wie ImageView aussehen lassen. Kein Rand, strecken Sie das Bild auf die Größe von ImageButton usw. Wenn Sie dieses Problem mit Rand und Dehnung angeben und Ihren Beitrag aktualisieren können.
Meiner
15

Hier ist mein einfacher Weg, um das zu lösen:

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);
    });

In Datei 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>
Oscar Josue Alvrez
quelle
Tolle Lösung - danke! Ich habe diesen Beitrag durchgeblättert und alle prägnanten ausprobiert - und keinen Erfolg. Endlich bin ich hier und es hat bei mir funktioniert. Eine Beobachtung: Wenn Sie 2+ Schaltflächen haben, auf die Sie die Animation anwenden möchten. Für meinen Code musste ich für jede Schaltfläche, für die ich den Effekt anwenden wollte, eine eindeutige Instanz des Animationsobjekts erstellen. Durch die Wiederverwendung derselben Instanz flackerten alle Schaltflächen, wenn auf 1 geklickt wurde.
Gene Bo
9

Stellen Sie den auswählbaren Hintergrund auf ImageView ein und fügen Sie einige Auffüllungen hinzu. Dann befestigen Sie die 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"/>
Oliver Kranz
quelle
Gibt es eine Möglichkeit, es zu verwenden, ohne das Auffüllen festzulegen, und die gesamte ImageView den Effekt und nicht nur den leeren Bereich zu erzielen?
Android-Entwickler
Dies wird eine Welligkeit in Kubik zeigen, wir brauchen eine mittlere Welligkeit
Kishan Solanki
8

Zum Definieren der auswählbaren Auswahl des Selektors

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

Ich muss android: state_pressed anstelle von android: state_selected verwenden

<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>
worawee.s
quelle
5

Sie können versuchen android:background="@android:drawable/list_selector_background" , den gleichen Effekt wie "Alarm hinzufügen" im Standard "Wecker" (jetzt Schreibtischuhr) zu erzielen.

Marco Bettiol
quelle
4

Das hat bei mir funktioniert:

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: Wie Gunhan sagte, wird es ein Abwärtskompatibilitätsproblem mit der setImageAlpha-Methode geben. Ich habe diese Methode verwendet:

public static void setImageAlpha(ImageView img, int alpha)
    {
        if(Build.VERSION.SDK_INT > 15)
        {
            img.setImageAlpha(alpha);
        }
        else
        {
            img.setAlpha(alpha);
        }
    }
Altosh
quelle
1
setImageAlpha erfordert API-Level 16. Daher ist es für abwärtskompatible Apps nicht möglich, es zu verwenden
Gunhan
1
@Gunhan tatsächlich können Sie die Bibliothek "nineOldAndroids" verwenden, mit der Alpha auch auf älteren APIs verwendet werden kann. Verwenden Sie einfach: ViewHelper.setAlpha (view, alpha);
Android-Entwickler
4

Ich mache einige ähnliche Dinge. Passend für dich oder nicht

Presseeffekt-Helfer anzeigen:

  • Verwendung: Machen Sie einen einfachen Press-Effekt wie iOS

    Einfache Verwendung:

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

  • ViewPressEffectHelper.attach (img)

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

Ah Lam
quelle
4

In Kombination mit allen obigen Antworten wollte ich, dass die ImageView gedrückt und der Status geändert wird. Wenn sich der Benutzer jedoch bewegt, wird "Abbrechen" ausgeführt und kein onClickListener ausgeführt.

Am Ende habe ich ein Point-Objekt innerhalb der Klasse erstellt und seine Koordinaten entsprechend dem Zeitpunkt festgelegt, zu dem der Benutzer die ImageView gedrückt hat. Auf dem MotionEvent.ACTION_UP zeichne ich einen neuen Punkt auf und vergleiche die Punkte.

Ich kann es nur so gut erklären, aber hier ist, was ich getan habe.

// 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;
    }
});

Ich habe einen onClickListener in der imageView festgelegt, aber dies kann eine Methode sein.

samschwartz96
quelle
Durch Hinzufügen von Groß- und Kleinschreibung MotionEvent.ACTION_CANCELmit der gleichen Funktionalität wie MotionEvent.ACTION_UPdamals ist es möglich, die Ansicht zu "löschen", wenn der Benutzer ein "Ziehen" ausführt, das keine Klickaktion ist.
Madlymad
4

Sie können setPresseddie ImageView überschreiben und dort die Farbfilterung durchführen, anstatt onTouchEvent-Listener zu erstellen:

@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();
    }
}
Oh nein
quelle
4

Basierend auf der Antwort von Herrn Zorn verwende ich in meiner abstrakten Utility-Klasse eine statische Methode:

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

    ...
}

Dann benutze ich es mit 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)

Es ist sehr einfach, wenn Sie viele Bilder haben und einen einfachen onTouch-Effekt wünschen, ohne dass XML gezeichnet werden kann und nur ein Bild.

neoteknic
quelle
4

Wenn Sie beim Antippen eine Welligkeit wünschen, kann dies durch den folgenden Code angegeben werden:

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

Ebenso können Sie den Klickeffekt für TextView implementieren

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

Ich erstelle hier ein Beispiel , ändere einfach ImageView in ClickableImageView aus deinem Layout. Hoffe es hilft.

Geben Sie hier die Bildbeschreibung ein

thanhbinh84
quelle
3

Ich denke, ImageButton ist eine bessere Lösung

<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" />
Dan Alboteanu
quelle
2

Ich habe eine schönere Lösung, wenn Sie Hintergrundbilder verwenden :)

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;
        }
    });
}
András
quelle
2

ODER:

Sie können dieses Formular mit der Bildschaltfläche verwenden.

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

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

Ihr Bild ändert sich mit einem Klick und Sie können es mit einem linearen Layout anpassen:

<?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>
Alex Zaraos
quelle
2

Hier ist meine Lösung, die mit der Bibliothek " NineOldAndroids " auch alte APIs unterstützt:

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;
    }
});

Es wird davon ausgegangen, dass die RootView die Zelle selbst (das Layout) ist und dass es eine einzelne ImageView gibt, die von der Farbe beeinflusst werden soll, die Sie auf die gesamte Zelle anwenden möchten.


BEARBEITEN: Wenn Sie möchten, können Sie ImageView auch erweitern, um den Vordergrund zu verarbeiten, und es auf "? Android: attr / selectableItemBackground" setzen. Es gibt eine Bibliothek für das hier und eine Anleitung, wie man es für jede Ansicht tun Sie es wünschen, hier .

Android-Entwickler
quelle
@madlymad, danke, dass Sie die Code-Formatierung korrigiert haben, obwohl ich denke, dass beim Einrücken etwas schief gelaufen ist. Wie auch immer, es ist gut genug, um es lesen zu können ...
Android-Entwickler
1

Danke für die Hilfe zu diesem Thread. Sie haben jedoch eines verpasst ... Sie müssen auch mit ACTION_CANCEL umgehen. Wenn Sie dies nicht tun, können Sie den Alpha-Wert der ImageView möglicherweise nicht ordnungsgemäß wiederherstellen, falls eine übergeordnete Ansicht in der Ansichtshierarchie ein Berührungsereignis abfängt (denken Sie an eine ScrollView, die Ihre ImageView umschließt).

Hier ist eine vollständige Klasse, die auf der obigen Klasse basiert, sich aber auch um ACTION_CANCEL kümmert. Es verwendet eine ImageViewCompat-Hilfsklasse, um die Unterschiede in der JellyBean-API vor und nach dem Eingriff zu abstrahieren.

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();
    }
}
Matt Accola
quelle
1

Hier ist mein Code. Die Idee ist, dass ImageView einen Farbfilter erhält, wenn der Benutzer ihn berührt, und der Farbfilter entfernt wird, wenn der Benutzer ihn nicht mehr berührt.

Martin Booka Weser, András, Ah Lam, altosh, Lösung funktioniert nicht, wenn ImageView auch onClickEvent hat. Für die Lösung von worawee.s und kcoppock (mit ImageButton) ist Hintergrund erforderlich, was keinen Sinn macht, wenn ImageView nicht transparent ist.

Dies ist eine Erweiterung der AZ_- Idee zum Farbfilter.

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

Verwendung:

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

Ich habe versucht mit:

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

und das hat funktioniert. Bitte beachten Sie in der Zeile:style="?android:borderlessButtonStyle"

aviit
quelle
Dies funktioniert bei 0-Auffüllung nicht und das Bild nimmt den gesamten Bereich der Ansicht ein.
Android-Entwickler
1

Ich denke, der einfachste Weg ist das Erstellen einer neuen XML-Datei. In diesem Fall nennen wir es "example.xml" im Zeichenordner und geben den folgenden Code ein:

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

</selector>

Zuvor müssen Sie jedoch die Farben in der Datei colours.xml im Ordner values ​​wie folgt festlegen:

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

Dazu haben Sie einfach den Button / ImageButton so eingestellt, dass das neue Layout wie folgt verwendet wird:

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

Wenn Sie dann auf dieses Bild klicken, ändert es sich in die eingestellte Farbe

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

Geben Sie das Feedback, das Sie wollen ...

Lima Neto
quelle
1

Dies ist die beste Lösung, die ich je gesehen habe. Es ist allgemeiner.

<?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>
Nilesh
quelle
2
An welcher Stelle und in welcher Datei soll es injiziert werden?
Entwickler
0

Ich habe folgt wie in XML - mit 0 Polsterung um das Bild und Welligkeit ontop des Bildes:

<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" />
Irgendwer irgendwo
quelle
-1

Im Moment sollten wir die Materialdesignpraxis entwickeln . In diesem Fall können Sie einer ImageView einen Ripple-Effekt hinzufügen.

festgefahrener Überlauf
quelle
-1

Fügen Sie einfach das XML-Attribut android hinzu: clickable = "true" ...

Sandipkumar Savani
quelle