Android'de düğme gibi bir görüntü görüntüleme tıklama efekti nasıl verebilirim?


84

Android uygulamamda, verilen onClick etkinliğiyle bir düğme gibi kullandığım görüntü görünümü var, ancak tahmin edebileceğiniz gibi, tıklandığında görüntü görünümüne tıklanabilir bir etki sağlamıyor. Bunu nasıl başarabilirim?

Yanıtlar:


53

Tıklanan / tıklanmayan durumlar için farklı görüntüler tasarlayabilir ve bunları aşağıdaki gibi onTouchListener'da ayarlayabilirsiniz.

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

Daha iyi seçim, bir seçiciyi aşağıdaki gibi tanımlamanızdır

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

ve olaydaki resmi seçin:

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

1
res.getDrawable'ın ne yaptığını açıklayabilir misiniz?
VenushkaT

v.setSelected yalnızca == bir kez doğru olur ve MotionEvent.ACTION_MOVE nedeniyle hemen yanlışa geçer. Parmak serbest bırakıldığında, MotionEvent.ACTION_UP oluşur. Seçici yöntemi kullanılıyorsa, setSelected veya setPressed için ayrı mantık kullanın. eğer (arg1.getAction () == MotionEvent.ACTION_DOWN) {v.setPressed (true); } else if (arg1.getAction () == MotionEvent.ACTION_UP) {v.setPressed (false); }
Adam Denoon

Bastığımız MotionEvent.ACTION_DOWN || MotionEvent.ACTION_MOVEsürece görüntüyü göstermeye devam etsek iyi olur.
Alaa M.

Gerek yok setOnTouchListener(.... Basitçe oluşturabilir <selector ...>ve ardından ImageView tıklanabilirini XML'de olduğu gibi ayarlayabilirsiniz<ImageView ... android:clickable="true" android:focusable="true" android:src="@drawable/my_selector" />
Pierre

76

Bunu, aşağıdaki gibi bir şey kullanarak tek bir resimle yapabilirsiniz:

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

Muhtemelen bunu daha kolay yeniden kullanılabilirlik için ImageView alt sınıfı (veya ImageView alt sınıfı olduğu için ImageButton) yapacağım, ancak bu, bir görüntü görünümüne "seçilmiş" bir görünüm uygulamanıza izin vermelidir.


2
Ayrıca ACTION_CANCEL için bir vaka ekledim, harika çalışıyor, teşekkürler!
Alan

İyi çağrı - bunu kendi koduma kendim ekledim ama burada da güncelleyeceğim.
Bay Zorn

1
Bu başka bir soru olabilir, ancak ACTION_UP'tan sonra nasıl iptal ederim? Özellikle ... Kullanıcı resme çarpıyor. Kullanıcı iptal etmek için parmağını resmin dışına sürükler. Ancak bu kodla eylem iptal edilmez
sudocoder

Ayrıca MotionEvent.ACTION_OUTSIDE;)
bonnyz

3
geri dönmek isteyebilirsiniz false, aksi takdirde manzaranın asıl onClick()etkinliği kovulmayacaktır
Nimrod Dayan

45

ColorFilter yöntemini kullanarak tek bir görüntü dosyasıyla yapmak mümkündür . Ancak ColorFilter, Düğmelerle değil, Görüntü Görünümleriyle çalışmayı bekler, bu nedenle düğmelerinizi Görüntü Görünümlerine dönüştürmeniz gerekir. Yine de düğmeleriniz olarak görseller kullanıyorsanız bu bir sorun değildir, ancak metniniz olması daha can sıkıcı ... Her neyse, metinle ilgili sorunu çözmenin bir yolunu bulduğunuzu varsayarsak, işte kullanılacak kod:

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

Bu, düğmeye kırmızı bir kaplama uygular (renk kodu, tamamen opak kırmızı için onaltılık koddur - ilk iki hane şeffaftır, ardından RR GG BB'dir.).


3
Bu kod çalıştırıldıktan sonra ne olacağını ve nereden çağrılmasının amaçlandığını açıklar mısınız? İmageView başlatmada bu 2 satırı aramaya çalıştım - resmimi kırmızıya boyuyor ve sonra hiçbir şey olmuyor, ne tıklama ne de dokunma. Dokunarak arama yaparken de aynı.
esteewhy

45

DÜZENLEME : Aşağıdaki orijinal yanıt işe yarıyor ve kurulumu kolay olsa da, daha verimli bir uygulama istiyorsanız / buna ihtiyaç duyuyorsanız Google'daki bir Android Geliştirici Avukatı tarafından hazırlanan bu gönderiye bakın . Ayrıca, android:foregroundözniteliğin varsayılan olarak Android M'de ImageView dahil tüm Görünümlere geldiğini unutmayın .


Bir ImageView için bir seçici kullanmanın sorunu, onu yalnızca görünümün arka planı olarak ayarlayabilmenizdir - görüntünüz opak olduğu sürece, arkasındaki seçicinin etkisini görmeyeceksiniz.

İşin püf noktası, ImageView'unuzu , içeriği için android:foregroundbir kaplama tanımlamamıza izin veren öznitelikle bir FrameLayout'a sarmaktır . android:foregroundBir seçiciye (ör ?android:attr/selectableItemBackground. API seviyesi 11+ için) ayarlarsak veOnClickListener arzuladığımız tıklama etkisi - ImageView yerine FrameLayout için, görüntü bizim seçicinin çekilebilir ile Kaplanmış olacak!

Seyretmek:

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

(Bunun ebeveyn düzeninize yerleştirilmesi gerektiğini unutmayın.)

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

2
Harika ! Bu çok iyi bir çözüm. SMS veya Çağrı eylemleri için kişiler uygulamasında kullanılan aynı çözüm.
Jerry

API <11'de çalışmayacak? Android: attr / selectableItemBackground, API seviyesi 11'i gerektirir (şu anki dakika 8'dir)
MSaudi

selectableItemBackgroundEski API seviyeleri için bu çözümü kullanmak istiyorsanız başka bir seçici kullanmanız gerekir niteliği yalnızca, API düzeyinde 11'de eklendi. Örneğin, API seviye 7'yi destekleyen uygulamalarımdan biri @drawable/list_selector_holo_lightiçin Android Holo Colors Generator aracı kullanılarak oluşturulan kaynağı kullanıyorum .
justasm

Aynı davranışı <ImageButton>selectableItemBackground ile yalnızca 1 kullanarak elde edebilirsiniz !
Yohan Dahmani

28

XML dosyasında style = "? Android: borderlessButtonStyle" kullanın . Android varsayılan tıklama efektini gösterecektir.

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

1
Bu aslında en iyi cevap, ÇOK daha kolay
FrankMonza

1
Bu, dolguyu ayarlar ve dolguyu 0 olarak ayarlasanız bile, verdiğiniz görüntü tüm imageView'i alırsa, tıklamanın herhangi bir etkisini görmezsiniz.
android geliştiricisi

2
@androiddeveloper android:adjustViewBounds="true"doldurmayı kaldırmak için kullanın .
Hafez Divandari

1
Kullanılması önerilir style="?android:attr/borderlessButtonStyle": developer.android.com/guide/topics/ui/controls/…
Hafez Divandari

style="?android:actionButtonStyle"ActionBar veya ToolBar üzerinde tıklanabilir bir ImageView için kullanın .
palindrom

21

Sadece bir ImageButton kullanın .


3
Ben şahsen ImageView gibi görünmesini sağlayamıyorum. Kenarlık yok, resmi ImageButton vb. Boyutuna kadar uzatın. Bu kenarlık ve uzatma sorununu verebilirseniz yazınızı güncelleyin. Biraz itibar
kazanıyorsun

15

İşte bunu çözmenin basit yolu:

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

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

Harika çözüm - teşekkürler! Tüm özlü olanları denemek için bu yazıyı kaydırdım - ve başarı yok. Sonunda buraya geldim ve benim için çalıştı. Bir gözlem - animasyonu uygulamak istediğiniz 2+ düğmeniz varsa .. kodum için, efekti uygulamak istediğim her düğme için benzersiz bir Animasyon nesnesi örneği oluşturmam gerektiğini fark ettim. Aynı örneği yeniden kullanmak, 1 tıklandığında tüm düğmelerin titremesine neden oldu.
Gene Bo

9

Seçilebilir arka planı ImageView olarak ayarlayın ve biraz dolgu ekleyin. Ardından 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"/>

Dolguyu ayarlamadan kullanmanın bir yolu var mı ve tüm ImageView'ın sadece boş alana değil, etkiye sahip olmasını sağlamanın bir yolu var mı?
android geliştiricisi

Bu kübik dalgalanma gösterecek, merkez dalgalanmaya ihtiyacımız var
Kishan Solanki

8

Seçici çekilebilir seçimini tanımlamak için

<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 yerine android: state_pressed kullanmalıyım

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

6

Dokunulduğunda dalgalanma istiyorsanız, bu kodla verilebilir:

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

Benzer şekilde, TextView için tıklama efekti uygulayabilirsiniz.

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

5

android:background="@android:drawable/list_selector_background" Varsayılan "Çalar Saat" deki (şimdi Masa Saati) "Alarm ekle" ile aynı etkiyi elde etmeyi deneyebilirsiniz .


4

Bu benim için çalıştı:

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'ın dediği gibi setImageAlpha metodu ile geriye dönük uyumluluk sorunu yaşanacaktır. Bu yöntemi kullandım:

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

1
setImageAlpha, API seviyesi 16'yı gerektirir. Bu nedenle, geriye dönük uyumlu uygulamalar için onu kullanmak mümkün değildir
Gunhan

1
@Gunhan aslında eski API'lerde bile alpha kullanımına izin veren "nineOldAndroids" kitaplığını kullanabilirsiniz. sadece şunu kullanın: ViewHelper.setAlpha (view, alpha);
android geliştiricisi

4

Sana uygun görüp görmeme benzer şeyler yapıyorum

Basın Etkisi Yardımcısı'nı Görüntüle:

  • kullanım: iOS gibi bazı basit baskı efektleri yapın

    Basit Kullanım:

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

  • ViewPressEffectHelper.attach (img)

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


4

Yukarıdaki tüm cevaplarla birlikte, ImageView'a basılmasını ve durumunun değiştirilmesini istedim, ancak kullanıcı hareket ederse "iptal et" ve onClickListener yapmamasını istedim.

Sınıf içinde bir Point nesnesi oluşturdum ve koordinatlarını, kullanıcının ImageView'e ne zaman bastığına göre ayarladım. MotionEvent.ACTION_UP üzerinde yeni bir nokta kaydedip noktaları karşılaştırdım.

Sadece çok iyi açıklayabilirim, ama işte yaptığım şey.

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

İmageView üzerinde bir onClickListener ayarım var, ancak bu bir yöntem olabilir.


Kullanıcıların tıklama eylemi olmayan bir "sürükleme" gerçekleştirmesi durumunda MotionEvent.ACTION_CANCEL, aynı işlevselliğe sahip durum ekleyerek MotionEvent.ACTION_UPgörünümü "temizlemek" mümkündür.
madlymad

4

setPressedOnTouchEvent dinleyicileri oluşturmak yerine ImageView'da Geçersiz Kılabilir ve renk filtrelemesini orada yapabilirsiniz:

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

4

Bay Zorn'un cevabına dayanarak, soyut Utility sınıfımda statik bir yöntem kullanıyorum:

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

    ...
}

Sonra onTouchListener ile kullanıyorum:

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)

Çok fazla görüntünüz varsa ve herhangi bir XML çizilebilir ve tek bir görüntü olmadan basit bir onTouch efekti istiyorsanız bu çok basittir.




3

ImageButton'ın daha iyi bir çözüm olduğunu düşünüyorum

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

2

Arka plan resimleri kullanırsanız daha güzel bir çözümüm var :)

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

2

VEYA:

Bu formu Image Button ile kullanabilirsiniz.

Dosya oluştur 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>

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

Resminiz bir tıklama ile değişir ve doğrusal bir düzen ile ayarlayabilirsiniz:

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

2

İşte " nineOldAndroids " kitaplığını kullanan , eski API'leri de destekleyen çözümüm :

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

RootView'ın hücrenin kendisi (düzen) olduğunu ve tüm hücreye uygulamak istediğiniz renkten etkilenmesini istediğiniz tek bir imageView'e sahip olduğunu varsayar.


DÜZENLEME: isterseniz, ImageView'u ön planı işleyecek şekilde genişletebilir ve "? Android: attr / selectableItemBackground" olarak ayarlayabilirsiniz. Burada bunun için bir kitaplık var ve burada dilediğiniz herhangi bir görünüm için nasıl yapılacağına dair bir eğitim var .


@madlymad, kod biçimlendirmesini düzelttiğiniz için teşekkür ederim, yine de girintiyle ilgili bir sorun olduğunu düşünüyorum. Her neyse, okuyabilecek kadar iyi ...
android geliştiricisi

1

Bu konudaki yardım için teşekkürler. Ancak, bir şeyi kaçırdınız ... ACTION_CANCEL ile de ilgilenmeniz gerekiyor. Bunu yapmazsanız, görünüm hiyerarşisindeki bir üst görünümün bir dokunma olayını kesmesi durumunda ImageView'un alfa değerini düzgün şekilde geri yükleyemeyebilirsiniz (bir ScrollView sizi ImageView ile sarmaladığını düşünün).

İşte yukarıdaki sınıfa dayanan ancak ACTION_CANCEL ile de ilgilenen eksiksiz bir sınıf. Ön-sonrası JellyBean API'deki farklılıkları soyutlamak için bir ImageViewCompat yardımcı sınıfı kullanır.

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

1

İşte kodum. Buradaki fikir, ImageView'un kullanıcı dokunduğunda renk filtresi alması ve kullanıcı dokunmayı bıraktığında renk filtresinin kaldırılmasıdır.

Martin Booka Weser, András, Ah Lam, altosh, çözüm ImageView'da onClickEvent'e sahipken çalışmıyor. worawee.s ve kcoppock (ImageButton ile) çözümü, ImageView şeffaf olmadığında hiçbir anlamı olmayan arka plan gerektirir.

Bu, renk filtresi hakkındaki AZ_ fikrinin uzantısıdır .

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

kullanım:

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

1

İle denedim:

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

ve bu işe yaradı. Lütfen satıra dikkat edin:style="?android:borderlessButtonStyle"


Bu, 0 doldurma durumunda çalışmaz ve görüntü, görünümün tüm alanını kaplar.
android geliştiricisi

1

Bence en kolay yol yeni bir XML dosyası oluşturmak. Bu durumda, onu çekilebilir klasörde "example.xml" olarak adlandıralım ve aşağıdaki kodu yazalım:

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

</selector>

Ancak bundan önce, colours.xml dosyasındaki değerler klasöründeki renkleri şu şekilde ayarlamanız gerekir:

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

Böylece, Button / ImageButton öğesini yeni düzeni kullanacak şekilde ayarlamanız yeterlidir, örneğin:

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

Sonra bu resme tıkladığınızda, içindeki renk ayarına dönüşecektir.

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

istediğiniz geri bildirimi vermek ...


1

Bu şimdiye kadar gördüğüm en iyi çözüm. Daha genel.

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

2
Hangi yere ve dosyaya enjekte edilmelidir?
DmitryBoyko

0

XML'de aşağıdaki gibi yaptım - görüntünün etrafında 0 dolgusu ve görüntünün üstünde dalgalanma :

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


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.