Sürükle ve bırak özelliğini etkinleştir

Android sürükle ve bırak çerçevesi, uygulamanıza etkileşimli sürükle ve bırak özellikleri eklemenize olanak tanır. Kullanıcılar, sürükle ve bırak özelliğiyle bir uygulama içinde bir Viewdan diğerine veya çoklu pencere modundaki uygulamalar arasında bir URI ile temsil edilebilen metin, resim, nesne ve diğer içerikleri kopyalayıp taşıyabilir.

Bir uygulama içinde sürüklenip bırakılan metin dizesi ve resim. Bölünmüş ekran modunda uygulamalar arasında sürüklenip bırakılan metin dizesi ve resim.
Şekil 1. Bir uygulama içinde sürükleyip bırakın.
Şekil 2. Uygulamalar arasında sürükleyip bırakın.

Çerçeve bir drag etkinliği sınıfı, sürükleme işleyicileri ve yardımcı sınıflar ile yöntemler içerir. Temel olarak veri aktarımını sağlamak için tasarlanmış olsa da bu çerçeveyi diğer kullanıcı arayüzü işlemleri için de kullanabilirsiniz. Örneğin, kullanıcı bir renk simgesini başka bir simgenin üzerine sürüklediğinde renkleri karıştıran bir uygulama oluşturabilirsiniz. Ancak belgenin geri kalanında, veri aktarımı bağlamında sürükle ve bırak çerçevesi açıklanmaktadır.

Genel bakış

Kullanıcı, uygulamanızın verileri sürüklemeye başlama sinyali olarak tanıdığı bir kullanıcı arayüzü hareketi yaptığında sürükle ve bırak işlemi başlar. Bunun karşılığında uygulama, bir sürükle ve bırak işleminin başladığını sisteme bildirir. Sistem, sürükleme gölgesi adı verilen, sürüklenen verilerin bir temsilini almak için uygulamanızı geri çağırır.

Kullanıcı, sürükleme gölgesini uygulama düzeninin üzerinde hareket ettirdikçe sistem, sürükleme etkinliklerini, düzendeki View nesneleriyle ilişkili sürükleme etkinliği işleyicilere ve geri çağırma yöntemlerini gönderir. Kullanıcı, verileri kabul edebilen bir görünümün üzerinde sürükleme gölgesini serbest bırakırsa (bırakma hedefi) sistem, verileri hedefe gönderir. Sürükleme ve bırakma işlemi, kullanıcı sürükleme gölgesini serbest bıraktığında sona erer (sürükleme gölgesinin bir bırakma hedefinin üzerinde olup olmamasına bakılmaksızın).

View.OnDragListener uygulayarak bir sürükleme etkinliği işleyicisi oluşturun. View nesnesinin setOnDragListener() yöntemini kullanarak bir bırakma hedefi için işleyiciyi ayarlayın. Düzendeki her görünümün bir onDragEvent() geri çağırma yöntemi de vardır.

Uygulamanız, sisteme sürükleme etkinlikleri göndermesini söyleyen startDragAndDrop() yöntemini çağırarak sistemi sürükle ve bırak işlemi başlatması için bilgilendirir. Bu yöntem, sisteme kullanıcının sürüklediği verileri ve verileri açıklayan meta verileri de sağlar. Geçerli düzendeki herhangi bir View cihazında startDragAndDrop() öğesini çağırabilirsiniz. Sistem, View nesnesini yalnızca düzendeki genel ayarlara erişmek için kullanır.

Sürükle ve bırak işlemi sırasında sistem, düzendeki View nesnelerinin geri çağırma yöntemlerine veya sürükleme etkinliği işleyicilerine sürükleme etkinliklerini gönderir. İşleyiciler veya geri çağırma yöntemleri, verileri bırakıldıktan sonra kabul etmek isteyip istemediklerine karar vermek için meta verileri kullanır. Kullanıcı verileri bir bırakma hedefine (verileri kabul eden bir View) bırakırsa sistem, bırakma hedefinin sürükleme etkinliği işleyicisine veya geri çağırma yöntemine verileri içeren bir sürükleme etkinliği nesnesi gönderir.

Etkinlik işleyicileri ve geri çağırma yöntemlerini sürükleme

View, View.OnDragListener uygulayan bir sürükleme etkinliği işleyicisi veya görünümün onDragEvent() geri çağırma yöntemini kullanarak sürükleme etkinliklerini alır. Sistem, yöntemi veya dinleyiciyi çağırdığında bir DragEvent bağımsız değişkeni sağlar.

Çoğu durumda, geri çağırma yönteminin kullanılması yerine bir işleyicinin kullanılması tercih edilir. Kullanıcı arayüzleri tasarlarken genellikle View sınıfını alt sınıflara ayırmazsınız. Ancak geri çağırma yöntemini kullanmak, sizi yöntemi geçersiz kılmak için alt sınıflar oluşturmaya zorlar. Buna karşılık, bir dinleyici sınıfı uygulayabilir ve ardından bu sınıfı birden fazla farklı View nesnesiyle kullanabilirsiniz. Bunu anonim bir satır içi sınıf veya lambda ifadesi olarak da uygulayabilirsiniz. Bir View nesnesinin işleyicisini ayarlamak için setOnDragListener() çağrısı yapın.

Alternatif olarak, yöntemi geçersiz kılmadan varsayılan onDragEvent() uygulamasını değiştirebilirsiniz. Bir görünümde OnReceiveContentListener ayarlama. Ayrıntılı bilgi için setOnReceiveContentListener() sayfasını inceleyin. Daha sonra onDragEvent() yöntemi, varsayılan olarak aşağıdakileri yapar:

  • startDragAndDrop() çağrısına yanıt olarak true değerini döndürür.
  • Sürükle ve bırak verileri görünüme düşerse performReceiveContent() çağrılar. Veriler yönteme ContentInfo nesnesi olarak aktarılır. Yöntem OnReceiveContentListener yöntemini çağırır.

  • Sürükleyip bırakma verileri görünümde kalırsa ve OnReceiveContentListener herhangi bir içeriği tüketirse true değerini döndürür.

Verileri özel olarak uygulamanıza göre işlemek için OnReceiveContentListener tanımlayın. API düzeyi 24'e kadar geriye dönük uyumluluk için OnReceiveContentListener Jetpack sürümünü kullanın.

Sistem önce işleyiciyi çağıran View nesnesi için bir sürükleme etkinliği işleyicisi ve geri çağırma yönteminiz olabilir. İşleyici false değerini döndürmediği sürece sistem geri çağırma yöntemini çağırmaz.

onDragEvent() yöntemi ile View.OnDragListener kombinasyonu, dokunma etkinlikleriyle kullanılan onTouchEvent() ve View.OnTouchListener kombinasyonlarının kombinasyonuna benzer.

Sürükleyip bırakma işlemi

Sürükle ve bırak işleminde dört adım veya durum vardır: başlatıldı, devam ediyor, atlandı ve sona erdi.

Başlatıldı

Kullanıcının sürükleme hareketine karşılık olarak uygulamanız, sisteme bir sürükle ve bırak işlemi başlatması için startDragAndDrop() komutunu çağırır. Yöntemin bağımsız değişkenleri şunları sağlar:

  • Sürüklenecek veriler.
  • Sürükleme gölgesini çizmek için bir geri çağırma
  • Sürüklenen verileri açıklayan meta veri : Sistem, sürükleme gölgesi almak için uygulamanızı geri çağırarak yanıt verir. Ardından sistem, cihazda sürükleme gölgesini gösterir. : Daha sonra sistem, geçerli düzendeki tüm View nesnelerinin sürükleme etkinliği işleyicisine ACTION_DRAG_STARTED işlem türünde bir drag etkinliği gönderir. Olası bir bırakma etkinliği dahil sürükleme etkinliklerini almaya devam etmek için sürükleme etkinliği işleyicinin true değerini döndürmesi gerekir. Bu, dinleyiciyi sisteme kaydeder. Yalnızca kayıtlı işleyiciler sürükleme etkinliklerini almaya devam eder. Bu noktada dinleyiciler, görünümün bir bırakma etkinliğini kabul edebileceğini göstermek için bırakma hedefi View nesnelerinin görünümünü de değiştirebilir. : Sürükleme etkinliği işleyici false değerini döndürürse sistem ACTION_DRAG_ENDED işlem türüne sahip bir sürükleme etkinliği gönderene kadar geçerli işlem için sürükleme etkinliklerini almaz. İşleyici, false değerini döndürerek sisteme sürükle ve bırak işlemiyle ilgilenmediğini ve sürüklenen verileri kabul etmek istemediğini bildirir.
Devam ediyor
Kullanıcı sürükleme işlemine devam eder. Sürükleme gölgesi, bir bırakma hedefinin sınırlayıcı kutusuyla kesiştiğinde sistem hedefin sürükleme etkinliği işleyicisine bir veya daha fazla sürükleme etkinliği gönderir. İşleyici, etkinliğe yanıt olarak View düşüş hedefinin görünümünü değiştirebilir. Örneğin, etkinlik, sürükleme gölgesinin bırakma hedefinin sınırlayıcı kutusuna (işlem türü ACTION_DRAG_ENTERED) girdiğini belirtiyorsa dinleyici View işaretini vurgulayarak tepki verebilir.
Atıldı
Kullanıcı, bırakma hedefinin sınırlayıcı kutusu içinde sürükleme gölgesini serbest bırakır. Sistem, bırakma hedefinin işleyicisine ACTION_DROP işlem türüne sahip bir sürükleme etkinliği gönderir. Sürükleme etkinliği nesnesi, işlemi başlatan startDragAndDrop() çağrısında sisteme iletilen verileri içerir. İşleyici, bırakılan verileri başarılı bir şekilde işlerse dinleyicinin sisteme true boole'sini döndürmesi beklenir. : Bu adım yalnızca kullanıcı, işleyicisi sürükleme etkinlikleri (düşme hedefi) almak üzere kayıtlı View öğesinin sınırlayıcı kutusu içinde sürükleme gölgesini bırakırsa gerçekleşir. Kullanıcı başka bir durumda sürükleme gölgesini serbest bırakırsa ACTION_DROP sürükleme etkinliği gönderilmez.
Sona erdi

Kullanıcı sürükleme gölgesini serbest bıraktıktan ve sistem tarafından

ACTION_DROP işlem türüne sahip bir sürükleme etkinliği oluşturmak için gerekirse sistem, sürükle ve bırak işleminin bittiğini belirtmek için ACTION_DRAG_ENDED işlem türüne sahip bir sürükleme etkinliği gönderir. Bu işlem, kullanıcının sürükleme gölgesini nerede serbest bıraktığından bağımsız olarak gerçekleştirilir. Etkinlik, işleyici ACTION_DROP etkinliğini de alsa bile, sürükleme etkinliklerini almak için kayıtlı her işleyiciye gönderilir.

Bu adımların her biri, Sürükle ve bırak işlemi adlı bölümde daha ayrıntılı olarak açıklanmıştır.

Sürükleme etkinlikleri

Sistem, DragEvent nesnesi biçiminde bir sürükleme etkinliği gönderir. Bu nesne, sürükle ve bırak işleminde neler olduğunu açıklayan bir işlem türü içerir. İşlem türüne bağlı olarak nesne başka veriler de içerebilir.

Sürükleme etkinliği işleyiciler DragEvent nesnesini alır. İşlem türünü öğrenmek için dinleyiciler DragEvent.getAction() ifadesini arar. DragEvent sınıfında sabit değerlerle tanımlanan altı olası değer vardır ve bunlar tablo 1'de açıklanmıştır:

Tablo 1. DragEvent işlem türleri

İşlem türü Anlamı
ACTION_DRAG_STARTED Uygulama startDragAndDrop() işlevini çağırır ve bir sürükleme gölgesi elde eder. İşleyici, bu işlem için sürükleme etkinliklerini almaya devam etmek isterse sisteme true boole değerini döndürmelidir.
ACTION_DRAG_ENTERED Sürükleme gölgesi, sürükleme etkinliği işleyicisinin View sınırlayıcı kutusuna girer. Bu, sürükleme gölgesi sınırlayıcı kutuya girdiğinde işleyicinin aldığı ilk etkinlik işlemi türüdür.
ACTION_DRAG_LOCATION Bir ACTION_DRAG_ENTERED etkinliğinden sonra sürükleme gölgesi hâlâ sürükleme etkinliği işleyicisinin View sınırlayıcı kutusunun içindedir.
ACTION_DRAG_EXITED Bir ACTION_DRAG_ENTERED ve en az bir ACTION_DRAG_LOCATION etkinliğinin ardından sürükleme gölgesi, sürükleme etkinliği işleyicisinin View sınırlama kutusunun dışına hareket eder.
ACTION_DROP Sürükleme gölgesi, sürükleme etkinliği işleyicinin View öğesinin üzerinde serbest bırakılır. Bu işlem türü, yalnızca işleyici ACTION_DRAG_STARTED sürükleme etkinliğine yanıt olarak true Boole değeri döndürdüğünde View nesnesinin işleyicisine gönderilir. Kullanıcı, işleyicisi kayıtlı olmayan bir View öğesinin üzerine sürükleme gölgesini serbest bırakırsa veya sürükleme gölgesini geçerli düzenin parçası olmayan bir öğenin üzerine getirirse bu işlem türü gönderilmez.

İşleyici, düşüşü başarıyla işlerse true boole değerini döndürür. Aksi takdirde false değerini döndürmelidir.

ACTION_DRAG_ENDED Sistem, sürükle ve bırak işlemini sonlandırıyor. Bu işlem türünün öncesinde bir ACTION_DROP etkinliği olması şart değildir. Sistem bir ACTION_DROP gönderirse ACTION_DRAG_ENDED işlem türünün alınması, düşüşün başarılı olduğu anlamına gelmez. İşleyici, ACTION_DROP yanıtı olarak döndürülen değeri almak için tablo 2'de gösterildiği gibi getResult() yöntemini çağırmalıdır. Bir ACTION_DROP etkinliği gönderilmezse getResult(), false değerini döndürür.

DragEvent nesnesi ayrıca, uygulamanızın startDragAndDrop() çağrısında sisteme sağladığı verileri ve meta verileri de içerir. Bazı veriler, yalnızca 2. tabloda özetlenen belirli işlem türleri için geçerlidir. Etkinlikler ve ilişkili verileri hakkında daha fazla bilgi için Sürükle ve bırak işlemi adlı bölüme bakın.

Tablo 2. İşlem türüne göre geçerli DragEvent verileri

getAction()
değer
getClipDescription()
değer
getLocalState()
değer
getX()
değer
getY()
değer
getClipData()
değer
getResult()
değer
ACTION_DRAG_STARTED ✓ ✓ ✓ ✓    
ACTION_DRAG_ENTERED ✓ ✓        
ACTION_DRAG_LOCATION ✓ ✓ ✓ ✓    
ACTION_DRAG_EXITED ✓ ✓        
ACTION_DROP ✓ ✓ ✓ ✓ ✓  
ACTION_DRAG_ENDED   ✓       ✓

DragEvent yöntemleri getAction(), describeContents(), writeToParcel() ve toString() her zaman geçerli veriler döndürür.

Bir yöntem, belirli bir işlem türü için geçerli veriler içermiyorsa sonuç türüne bağlı olarak null veya 0 değerini döndürür.

Sürükleme gölgesi

Sürükle ve bırak işlemi sırasında sistem, kullanıcının sürüklediği bir resim görüntüler. Veri taşıma için bu resim, sürüklenen verileri temsil etmektedir. Diğer işlemlerde resim, sürükleme işleminin bir kısmını temsil eder.

Resme sürükleme gölgesi denir. Bunu, View.DragShadowBuilder nesnesi için tanımladığınız yöntemlerle oluşturursunuz. startDragAndDrop() kullanarak bir sürükle ve bırak işlemi başlattığınızda oluşturucuyu sisteme geçirirsiniz. Sistem, startDragAndDrop() özelliğine verdiği yanıtın bir parçası olarak sürükleme gölgesi elde etmek için View.DragShadowBuilder içinde tanımladığınız geri çağırma yöntemlerini çağırır.

View.DragShadowBuilder sınıfının iki kurucusu vardır:

View.DragShadowBuilder(View)

Bu oluşturucu, uygulamanızın View nesnelerinden herhangi birini kabul eder. Oluşturucu, View nesnesini View.DragShadowBuilder nesnesinde depolar. Böylece geri çağırmalar, sürükleme gölgesini oluşturmak için nesneye erişebilir. Görünümün, kullanıcının sürükleme işlemini başlatmak için seçtiği bir View olması gerekmez.

Bu oluşturucuyu kullanırsanız View.DragShadowBuilder öğesini genişletmeniz veya yöntemlerini geçersiz kılmanız gerekmez. Varsayılan olarak, bağımsız değişken olarak ilettiğiniz View ile aynı görünüme sahip, kullanıcının ekrana dokunduğu konumun altında ortalanmış bir sürükleme gölgesi elde edersiniz.

View.DragShadowBuilder()

Bu oluşturucuyu kullanırsanız View.DragShadowBuilder nesnesinde View nesnesi bulunmaz. Alan null olarak ayarlandı. View.DragShadowBuilder öğesini genişletmeniz ve yöntemlerini geçersiz kılmanız gerekir. Aksi takdirde, görünmez bir sürükleme gölgesi elde edersiniz. Sistem hata vermiyor.

View.DragShadowBuilder sınıfında, birlikte sürükleme gölgesi oluşturan iki yöntem bulunur:

onProvideShadowMetrics()

startDragAndDrop() çağrıldıktan hemen sonra sistem bu yöntemi çağırır. Sürükleme gölgesinin boyutlarını ve temas noktasını sisteme göndermek için bu yöntemi kullanın. Yöntemin iki parametresi vardır:

outShadowSize: Bir Point nesnesi. Sürükleme gölgesi genişliği x ve yüksekliği y içinde olur.

outShadowTouchPoint: Bir Point nesnesi. Temas noktası, sürükleme sırasında kullanıcının parmağının altında olması gereken sürükleme gölgesi içindeki konumdur. X konumu x, Y konumu y olur.

onDrawShadow()

onProvideShadowMetrics() çağrısından hemen sonra sistem, sürükleme gölgesini oluşturmak için onDrawShadow() yöntemini çağırır. Yöntemde tek bir bağımsız değişken (sistemin onProvideShadowMetrics() içinde sağladığınız parametrelerden oluşturduğu bir Canvas nesnesi) bulunur. Yöntem, sağlanan Canvas üzerinde sürükleme gölgesini çizer.

Performansı artırmak için sürükleme gölgesinin boyutunu küçük tutun. Tek bir öğe için bir simge kullanabilirsiniz. Birden fazla öğeden oluşan bir seçim için ekrana yayılmış tam resimler yerine simgeleri bir grup hâlinde kullanabilirsiniz.

Sürükle ve bırak işlemi

Bu bölümde, bir sürüklemenin nasıl başlatılacağı, sürükleme sırasında etkinliklere nasıl yanıt verileceği, bir bırakma etkinliğine nasıl yanıt verileceği ve sürükle ve bırak işleminin nasıl sonlandırılacağı adım adım gösterilmektedir.

Sürükleme başlatın

Kullanıcı, bir View nesnesine sürükleme hareketiyle (genellikle dokunup basılı tutarak) sürükleme başlatır. Buna karşılık olarak uygulamanız şunları yapmalıdır:

  1. Taşınan veriler için bir ClipData ve ClipData.Item nesnesi oluşturun. ClipData öğesinin bir parçası olarak, ClipData içindeki bir ClipDescription nesnesinde depolanan meta verileri sağlayın. Veri hareketini temsil etmeyen bir sürükle ve bırak işlemi için gerçek bir nesne yerine null işlevini kullanmak isteyebilirsiniz.

    Örneğin bu kod snippet'i, ImageView üzerinde yapılan dokunma ve basılı tutma hareketine, ImageView etiketini (veya etiketini) içeren bir ClipData nesnesi oluşturarak nasıl yanıt verileceğini gösterir:

    Kotlin

    // Create a string for the ImageView label.
    val IMAGEVIEW_TAG = "icon bitmap"
    ...
    val imageView = ImageView(context).apply {
    // Set the bitmap for the ImageView from an icon bitmap defined elsewhere.
    setImageBitmap(iconBitmap)
    tag = IMAGEVIEW_TAG
    setOnLongClickListener { v ->
            // Create a new ClipData. This is done in two steps to provide
            // clarity. The convenience method ClipData.newPlainText() can
            // create a plain text ClipData in one step.
    
            // Create a new ClipData.Item from the ImageView object's tag.
            val item = ClipData.Item(v.tag as? CharSequence)
    
            // Create a new ClipData using the tag as a label, the plain text
            // MIME type, and the already-created item. This creates a new
            // ClipDescription object within the ClipData and sets its MIME type
            // to "text/plain".
            val dragData = ClipData(
                v.tag as? CharSequence,
                arrayOf(ClipDescription.MIMETYPE_TEXT_PLAIN),
                item)
    
            // Instantiate the drag shadow builder.
            val myShadow = MyDragShadowBuilder(view: this)
    
            // Start the drag.
            v.startDragAndDrop(dragData,  // The data to be dragged.
                               myShadow,  // The drag shadow builder.
                               null,      // No need to use local data.
                               0          // Flags. Not currently used, set to 0.
            )
    
           // Indicate that the long-click is handled.
           true
    }
    }
    

    Java

    // Create a string for the ImageView label.
    private static final String IMAGEVIEW_TAG = "icon bitmap";
    ...
    // Create a new ImageView.
    ImageView imageView = new ImageView(context);
    
    // Set the bitmap for the ImageView from an icon bitmap defined elsewhere.
    imageView.setImageBitmap(iconBitmap);
    
    // Set the tag.
    imageView.setTag(IMAGEVIEW_TAG);
    
    // Set a long-click listener for the ImageView using an anonymous listener
    // object that implements the OnLongClickListener interface.
    imageView.setOnLongClickListener( v -> {
    
    // Create a new ClipData. This is done in two steps to provide clarity. The
    // convenience method ClipData.newPlainText() can create a plain text
    // ClipData in one step.
    
    // Create a new ClipData.Item from the ImageView object's tag.
    ClipData.Item item = new ClipData.Item((CharSequence) v.getTag());
    
    // Create a new ClipData using the tag as a label, the plain text MIME type,
    // and the already-created item. This creates a new ClipDescription object
    // within the ClipData and sets its MIME type to "text/plain".
    ClipData dragData = new ClipData(
            (CharSequence) v.getTag(),
            new String[] { ClipDescription.MIMETYPE_TEXT_PLAIN },
            item);
    
    // Instantiate the drag shadow builder.
    View.DragShadowBuilder myShadow = new MyDragShadowBuilder(imageView);
    
    // Start the drag.
    v.startDragAndDrop(dragData,  // The data to be dragged.
                           myShadow,  // The drag shadow builder.
                           null,      // No need to use local data.
                           0          // Flags. Not currently used, set to 0.
    );
    
    // Indicate that the long-click is handled.
    return true;
    });
    
  2. View.DragShadowBuilder içindeki yöntemleri geçersiz kılarak myDragShadowBuilder öğesini tanımlayın. Aşağıdaki kod snippet'i, TextView için küçük, dikdörtgen ve gri bir sürükleme gölgesi oluşturur:

    Kotlin

    private class MyDragShadowBuilder(view: View) : View.DragShadowBuilder(view) {
    
    private val shadow = ColorDrawable(Color.LTGRAY)
    
    // Define a callback that sends the drag shadow dimensions and touch point
    // back to the system.
    override fun onProvideShadowMetrics(size: Point, touch: Point) {
    
            // Set the width of the shadow to half the width of the original
            // View.
            val width: Int = view.width / 2
    
            // Set the height of the shadow to half the height of the original
            // View.
            val height: Int = view.height / 2
    
            // The drag shadow is a ColorDrawable. Set its dimensions to
            // be the same as the Canvas that the system provides. As a result,
            // the drag shadow fills the Canvas.
            shadow.setBounds(0, 0, width, height)
    
            // Set the size parameter's width and height values. These get back
            // to the system through the size parameter.
            size.set(width, height)
    
            // Set the touch point's position to be in the middle of the drag
            // shadow.
            touch.set(width / 2, height / 2)
    }
    
    // Define a callback that draws the drag shadow in a Canvas that the system
    // constructs from the dimensions passed to onProvideShadowMetrics().
    override fun onDrawShadow(canvas: Canvas) {
    
            // Draw the ColorDrawable on the Canvas passed in from the system.
            shadow.draw(canvas)
    }
    }
    

    Java

    private static class MyDragShadowBuilder extends View.DragShadowBuilder {
    
    // The drag shadow image, defined as a drawable object.
    private static Drawable shadow;
    
    // Constructor.
    public MyDragShadowBuilder(View view) {
    
            // Store the View parameter.
            super(view);
    
            // Create a draggable image that fills the Canvas provided by the
            // system.
            shadow = new ColorDrawable(Color.LTGRAY);
    }
    
    // Define a callback that sends the drag shadow dimensions and touch point
    // back to the system.
    @Override
    public void onProvideShadowMetrics (Point size, Point touch) {
    
            // Define local variables.
            int width, height;
    
            // Set the width of the shadow to half the width of the original
            // View.
            width = getView().getWidth() / 2;
    
            // Set the height of the shadow to half the height of the original
            // View.
            height = getView().getHeight() / 2;
    
            // The drag shadow is a ColorDrawable. Set its dimensions to
            // be the same as the Canvas that the system provides. As a result,
            // the drag shadow fills the Canvas.
            shadow.setBounds(0, 0, width, height);
    
            // Set the size parameter's width and height values. These get back
            // to the system through the size parameter.
            size.set(width, height);
    
            // Set the touch point's position to be in the middle of the drag
            // shadow.
            touch.set(width / 2, height / 2);
    }
    
    // Define a callback that draws the drag shadow in a Canvas that the system
    // constructs from the dimensions passed to onProvideShadowMetrics().
    @Override
    public void onDrawShadow(Canvas canvas) {
    
            // Draw the ColorDrawable on the Canvas passed in from the system.
            shadow.draw(canvas);
    }
    }
    

Sürükleme başlangıcına yanıt verme

Sürükleme işlemi sırasında sistem, sürükleme etkinliklerini geçerli düzendeki View nesnelerinin sürükleme etkinliği dinleyicilerine gönderir. Dinleyiciler, işlem türünü öğrenmek için DragEvent.getAction() yöntemini çağırarak tepki verir. Bir sürüklemenin başlangıcında bu yöntem ACTION_DRAG_STARTED değerini döndürür.

ACTION_DRAG_STARTED işlem türündeki bir etkinliğe yanıt olarak, bir sürükleme etkinliği işleyicinin aşağıdakileri yapması gerekir:

  1. İşleyicinin sürüklenen verileri kabul edip edemeyeceğini görmek için DragEvent.getClipDescription() yöntemini çağırın ve döndürülen ClipDescription öğesindeki MIME türü yöntemlerini kullanın.

    Sürükleyip bırakma işlemi veri taşımayı temsil etmiyorsa bu gerekli olmayabilir.

  2. Sürükleme etkinliği işleyicisi bir bırakma işlemini kabul edebiliyorsa sisteme, işleyiciye sürükleme etkinlikleri göndermeye devam etmesini bildirmek için true değerini döndürmesi gerekir. İşleyici bir bırakma işlemini kabul edemezse false değerini döndürmesi gerekir. Bu durumda sistem, sürükle ve bırak işlemini sonlandırmak için ACTION_DRAG_ENDED gönderene kadar sistem tarafından işleyiciye sürükleme etkinlikleri göndermeyi durdurur.

Bir ACTION_DRAG_STARTED etkinliği için şu DragEvent yöntemleri geçerli değildir: getClipData(), getX(), getY() ve getResult().

Sürükleme sırasında etkinlikleri işleme

Sürükleme işlemi sırasında, ACTION_DRAG_STARTED sürükleme etkinliğine yanıt olarak true sonucunu döndüren sürükleme etkinliği işleyicileri sürükleme etkinlikleri almaya devam eder. Bir işleyicinin sürükleme sırasında aldığı sürükleme etkinliklerinin türleri, sürükleme gölgesinin konumuna ve işleyicinin View görünürlüğüne bağlıdır. İşleyiciler, View görünümünü değiştirmeleri gerekip gerekmediğine karar vermek için öncelikle sürükleme etkinliklerini kullanır.

Sürükleme işlemi sırasında DragEvent.getAction(), şu üç değerden birini döndürür:

  • ACTION_DRAG_ENTERED: Dokunmatik nokta (ekranda kullanıcının parmağının veya faresinin altındaki nokta) işleyicinin View sınırlayıcı kutusuna girdiğinde işleyici, bu etkinlik işlemi türünü alır.
  • ACTION_DRAG_LOCATION: İşleyici bir ACTION_DRAG_ENTERED etkinliği aldığında, temas noktası bir ACTION_DRAG_EXITED etkinliği alana kadar her hareket ettiğinde yeni bir ACTION_DRAG_LOCATION etkinliği alır. getX() ve getY() yöntemleri, temas noktasının X ve Y koordinatlarını döndürür.
  • ACTION_DRAG_EXITED: Bu etkinlik işlemi türü, daha önce ACTION_DRAG_ENTERED alan dinleyiciye gönderilir. Sürükleme gölgesi temas noktası, işleyicinin View sınırlayıcı kutusundan sınırlayıcı kutunun dışına hareket ettiğinde etkinlik gönderilir.

Sürükleme etkinliği işleyicinin bu işlem türlerinin hiçbirine tepki vermesi gerekmez. İşleyici sisteme bir değer döndürürse bu değer yoksayılır.

Aşağıda, bu işlem türlerinin her birine yanıt vermeyle ilgili bazı yönergeler verilmiştir:

  • İşleyici, ACTION_DRAG_ENTERED veya ACTION_DRAG_LOCATION özelliğine yanıt olarak, görüntülemenin olası bir düşüş hedefi olduğunu belirtmek için View görünümünü değiştirebilir.
  • ACTION_DRAG_LOCATION işlem türüne sahip bir etkinlik, temas noktasının konumuna karşılık gelen getX() ve getY() için geçerli veriler içerir. İşleyici, temas noktasındaki View görünümünü değiştirmek veya kullanıcının sürükleme gölgesini bırakabileceği tam konumu, yani verileri bırakmak için bu bilgileri kullanabilir.
  • İşleyici, ACTION_DRAG_EXITED özelliğine yanıt olarak ACTION_DRAG_ENTERED veya ACTION_DRAG_LOCATION için uyguladığı görünüm değişikliklerini sıfırlamalıdır. Bu durum, kullanıcıya View öğesinin artık yaklaşan bir düşüş hedefi olmadığını belirtir.

Düşüşe yanıt verme

Kullanıcı bir View üzerinde sürükleme gölgesini serbest bıraktığında ve View daha önce sürüklenmekte olan içeriği kabul edebildiğini bildirdiğinde sistem, ACTION_DROP işlem türüne sahip View öğesine bir sürükleme etkinliği gönderir.

Sürükleme etkinliği işleyici şunları yapmalıdır:

  1. startDragAndDrop() çağrısında orijinal olarak sağlanan ClipData nesnesini almak ve verileri işlemek için getClipData() yöntemini çağırın. Sürükleyip bırakma işlemi veri taşımayı temsil etmiyorsa bu gerekli değildir.

  2. Düşüşün başarıyla işlendiğini belirtmek için true boole değerini veya işlenmiyorsa false boole'sini döndürün. Döndürülen değer, nihai ACTION_DRAG_ENDED etkinliği için getResult() tarafından döndürülen değer haline gelir. Sistem bir ACTION_DROP etkinliği göndermezse bir ACTION_DRAG_ENDED etkinliği için getResult() tarafından döndürülen değer false olur.

Bir ACTION_DROP etkinliğinde getX() ve getY(), düşüşü alan View koordinat sistemini kullanarak düşüş anındaki temas noktasının X ve Y konumunu döndürür.

Sistem, kullanıcının sürükleme etkinliği işleyicisi olmayan bir View üzerinde sürükleme gölgesini bırakmasını sağlar. Ayrıca, kullanıcının uygulama arayüzündeki boş alanlara veya uygulamanızın dışındaki alanlara sürükleme gölgesini bırakmasını sağlar. Tüm bu durumlarda sistem bir ACTION_DRAG_ENDED etkinliği gönderse de sistem ACTION_DROP işlem türüne sahip bir etkinlik göndermez.

Sürükleme işlemine yanıt verme

Kullanıcı sürükleme gölgesini serbest bıraktıktan hemen sonra, sistem uygulamanızdaki tüm sürükleme etkinliği işleyicilerine ACTION_DRAG_ENDED işlem türünde bir sürükleme etkinliği gönderir. Bu, sürükle ve bırak işleminin sona erdiğini gösterir.

Her sürükleme etkinliği işleyici aşağıdakileri yapmalıdır:

  1. İşleyici, işlem sırasında View nesnesinin görünümünü değiştirirse işleyici View öğesini varsayılan görünümüne sıfırlamalıdır. Bu, kullanıcıya işlemin bittiğini belirten görsel bir işarettir.
  2. Dinleyici, işlem hakkında daha fazla bilgi edinmek için isteğe bağlı olarak getResult() komutunu çağırabilir. Bir işleyici, ACTION_DROP işlem türündeki bir etkinliğe yanıt olarak true değerini döndürürse getResult(), boole true değerini döndürür. Diğer tüm durumlarda getResult(), sistemin ACTION_DROP etkinliği göndermediği durumlar da dahil olmak üzere false boole değerini döndürür.
  3. Sürükle ve bırak işleminin başarılı bir şekilde tamamlandığını belirtmek için işleyici, sisteme boole true değerini döndürmelidir.

Sürükleme etkinliklerine yanıt verme: Örnek

Tüm sürükleme etkinlikleri, sürükleme etkinliği yönteminiz veya işleyiciniz tarafından alınır. Aşağıdaki kod snippet'i, sürükleme etkinliklerine yanıt vermeye ilişkin basit bir örnektir:

Kotlin

val imageView = ImageView(this)

// Set the drag event listener for the View.
imageView.setOnDragListener { v, e ->

    // Handle each of the expected events.
    when (e.action) {
        DragEvent.ACTION_DRAG_STARTED -> {
            // Determine whether this View can accept the dragged data.
            if (e.clipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
                // As an example, apply a blue color tint to the View to
                // indicate that it can accept data.
                (v as? ImageView)?.setColorFilter(Color.BLUE)

                // Invalidate the view to force a redraw in the new tint.
                v.invalidate()

                // Return true to indicate that the View can accept the dragged
                // data.
                true
            } else {
                // Return false to indicate that, during the current drag and
                // drop operation, this View doesn't receive events again until
                // ACTION_DRAG_ENDED is sent.
                false
            }
        }
        DragEvent.ACTION_DRAG_ENTERED -> {
            // Apply a green tint to the View.
            (v as? ImageView)?.setColorFilter(Color.GREEN)

            // Invalidate the view to force a redraw in the new tint.
            v.invalidate()

            // Return true. The value is ignored.
            true
        }

        DragEvent.ACTION_DRAG_LOCATION ->
            // Ignore the event.
            true
        DragEvent.ACTION_DRAG_EXITED -> {
            // Reset the color tint to blue.
            (v as? ImageView)?.setColorFilter(Color.BLUE)

            // Invalidate the view to force a redraw in the new tint.
            v.invalidate()

            // Return true. The value is ignored.
            true
        }
        DragEvent.ACTION_DROP -> {
            // Get the item containing the dragged data.
            val item: ClipData.Item = e.clipData.getItemAt(0)

            // Get the text data from the item.
            val dragData = item.text

            // Display a message containing the dragged data.
            Toast.makeText(this, "Dragged data is $dragData", Toast.LENGTH_LONG).show()

            // Turn off color tints.
            (v as? ImageView)?.clearColorFilter()

            // Invalidate the view to force a redraw.
            v.invalidate()

            // Return true. DragEvent.getResult() returns true.
            true
        }

        DragEvent.ACTION_DRAG_ENDED -> {
            // Turn off color tinting.
            (v as? ImageView)?.clearColorFilter()

            // Invalidate the view to force a redraw.
            v.invalidate()

            // Do a getResult() and display what happens.
            when(e.result) {
                true ->
                    Toast.makeText(this, "The drop was handled.", Toast.LENGTH_LONG)
                else ->
                    Toast.makeText(this, "The drop didn't work.", Toast.LENGTH_LONG)
            }.show()

            // Return true. The value is ignored.
            true
        }
        else -> {
            // An unknown action type is received.
            Log.e("DragDrop Example", "Unknown action type received by View.OnDragListener.")
            false
        }
    }
}

Java

View imageView = new ImageView(this);

// Set the drag event listener for the View.
imageView.setOnDragListener( (v, e) -> {

    // Handle each of the expected events.
    switch(e.getAction()) {

        case DragEvent.ACTION_DRAG_STARTED:

            // Determine whether this View can accept the dragged data.
            if (e.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {

                // As an example, apply a blue color tint to the View to
                // indicate that it can accept data.
                ((ImageView)v).setColorFilter(Color.BLUE);

                // Invalidate the view to force a redraw in the new tint.
                v.invalidate();

                // Return true to indicate that the View can accept the dragged
                // data.
                return true;

            }

            // Return false to indicate that, during the current drag and drop
            // operation, this View doesn't receive events again until
            // ACTION_DRAG_ENDED is sent.
            return false;

        case DragEvent.ACTION_DRAG_ENTERED:

            // Apply a green tint to the View.
            ((ImageView)v).setColorFilter(Color.GREEN);

            // Invalidate the view to force a redraw in the new tint.
            v.invalidate();

            // Return true. The value is ignored.
            return true;

        case DragEvent.ACTION_DRAG_LOCATION:

            // Ignore the event.
            return true;

        case DragEvent.ACTION_DRAG_EXITED:

            // Reset the color tint to blue.
            ((ImageView)v).setColorFilter(Color.BLUE);

            // Invalidate the view to force a redraw in the new tint.
            v.invalidate();

            // Return true. The value is ignored.
            return true;

        case DragEvent.ACTION_DROP:

            // Get the item containing the dragged data.
            ClipData.Item item = e.getClipData().getItemAt(0);

            // Get the text data from the item.
            CharSequence dragData = item.getText();

            // Display a message containing the dragged data.
            Toast.makeText(this, "Dragged data is " + dragData, Toast.LENGTH_LONG).show();

            // Turn off color tints.
            ((ImageView)v).clearColorFilter();

            // Invalidate the view to force a redraw.
            v.invalidate();

            // Return true. DragEvent.getResult() returns true.
            return true;

        case DragEvent.ACTION_DRAG_ENDED:

            // Turn off color tinting.
            ((ImageView)v).clearColorFilter();

            // Invalidate the view to force a redraw.
            v.invalidate();

            // Do a getResult() and displays what happens.
            if (e.getResult()) {
                Toast.makeText(this, "The drop was handled.", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(this, "The drop didn't work.", Toast.LENGTH_LONG).show();
            }

            // Return true. The value is ignored.
            return true;

        // An unknown action type is received.
        default:
            Log.e("DragDrop Example","Unknown action type received by View.OnDragListener.");
            break;
    }

    return false;

});

Çoklu pencere modunda sürükleyip bırakma

Android 7.0 (API düzeyi 24) veya sonraki sürümleri çalıştıran cihazlar, kullanıcıların sürükle ve bırak işlemiyle verileri bir uygulamadan diğerine taşımasına olanak tanıyan çoklu pencere modunu destekler. Daha fazla bilgi için Çoklu pencere desteği bölümünü inceleyin.

Verileri, sürükle ve bırak işleminin başladığı kaynak uygulama sağlar. Verileri, sürükle ve bırak işleminin sona erdiği hedef uygulama alır.

Sürükle ve bırak işlemi başlatılırken kaynak uygulama, kullanıcının başka bir uygulamaya veri sürükleyebileceğinizi belirtmek için DRAG_FLAG_GLOBAL işaretini ayarlamalıdır.

Veriler uygulama sınırları arasında hareket ettiğinden, uygulamalar verilere erişimi bir içerik URI'si kullanarak paylaşır. Bunun için aşağıdakiler gereklidir:

  • Kaynak uygulama, kaynak uygulamanın hedef uygulamaya vermek istediği verilere okuma veya yazma erişimine bağlı olarak DRAG_FLAG_GLOBAL_URI_READ ve DRAG_FLAG_GLOBAL_URI_WRITE işaretlerinden birini ya da ikisini birden ayarlamalıdır.
  • Hedef uygulama, kullanıcının uygulamaya sürüklediği verileri işlemeden önce hemen requestDragAndDropPermissions() yöntemini çağırmalıdır. Hedef uygulamanın artık sürükle ve bırak verilerine erişmesi gerekmiyorsa uygulama, requestDragAndDropPermissions() kaynağından döndürülen nesnede release() çağrısı yapabilir. Aksi takdirde, kapsayıcı etkinlik silindiğinde izinler serbest bırakılır. Uygulamanız, bırakılan URI'ların işlenmesi için yeni bir Etkinlik başlatmayı içeriyorsa yeni Etkinliğe aynı izinleri vermeniz gerekir. Klip verilerini ve bir bayrağı ayarlamanız gerekir:

    Kotlin

    intent.setClipData(clipData)
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    

    Java

    intent.setClipData(clipData);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    

Aşağıdaki kod snippet'leri, sürükle ve bırak işlemi gerçekleştikten hemen sonra verileri sürükleyip bırakmak için nasıl salt okuma erişiminin verildiğini göstermektedir. Daha eksiksiz bir örnek için GitHub'daki DragAndDrop örneğine göz atın.

Kaynak sürükle ve bırak etkinliği

Kotlin

// Drag a file stored in an images/ directory in internal storage.
val internalImagesDir = File(context.filesDir, "images")
val imageFile = File(internalImagesDir, imageFilename)
val uri = FileProvider.getUriForFile(context, contentAuthority, imageFile)

val listener = OnDragStartListener@{ view: View, _: DragStartHelper ->
    val clipData = ClipData(ClipDescription("Image Description",
                                            arrayOf("image/*")),
                            ClipData.Item(uri))
    // Must include DRAG_FLAG_GLOBAL to permit dragging data between apps.
    // This example provides read-only access to the data.
    val flags = View.DRAG_FLAG_GLOBAL or View.DRAG_FLAG_GLOBAL_URI_READ
    return@OnDragStartListener view.startDragAndDrop(clipData,
                                                     View.DragShadowBuilder(view),
                                                     null,
                                                     flags)
}

// Container where the image originally appears in the source app.
val srcImageView = findViewById<ImageView>(R.id.imageView)

// Detect and start the drag event.
DragStartHelper(srcImageView, listener).apply {
    attach()
}

Java

// Drag a file stored in an images/ directory in internal storage.
File internalImagesDir = new File(context.getFilesDir(), "images");
File imageFile = new File(internalImagesDir, imageFilename);
final Uri uri = FileProvider.getUriForFile(context, contentAuthority, imageFile);

// Container where the image originally appears in the source app.
ImageView srcImageView = findViewById(R.id.imageView);

// Enable the view to detect and start the drag event.
new DragStartHelper(srcImageView, (view, helper) -> {
    ClipData clipData = new ClipData(new ClipDescription("Image Description",
                                                          new String[] {"image/*"}),
                                     new ClipData.Item(uri));
    // Must include DRAG_FLAG_GLOBAL to permit dragging data between apps.
    // This example provides read-only access to the data.
    int flags = View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ;
    return view.startDragAndDrop(clipData,
                                 new View.DragShadowBuilder(view),
                                 null,
                                 flags);
}).attach();

Hedef sürükle ve bırak etkinliği

Kotlin

// Container where the image is to be dropped in the target app.
val targetImageView = findViewById<ImageView>(R.id.imageView)

targetImageView.setOnDragListener { view, event ->

    when (event.action) {

        ACTION_DROP -> {
            val imageItem: ClipData.Item = event.clipData.getItemAt(0)
            val uri = imageItem.uri

            // Request permission to access the image data being dragged into
            // the target activity's ImageView element.
            val dropPermissions = requestDragAndDropPermissions(event)
            (view as ImageView).setImageURI(uri)

            // Release the permission immediately afterward because it's no
            // longer needed.
            dropPermissions.release()
            return@setOnDragListener true
        }

        // Implement logic for other DragEvent cases here.

        // An unknown action type is received.
        else -> {
            Log.e("DragDrop Example", "Unknown action type received by View.OnDragListener.")
            return@setOnDragListener false
        }

    }
}

Java

// Container where the image is to be dropped in the target app.
ImageView targetImageView = findViewById(R.id.imageView);

targetImageView.setOnDragListener( (view, event) -> {

    switch (event.getAction()) {

        case ACTION_DROP:
            ClipData.Item imageItem = event.getClipData().getItemAt(0);
            Uri uri = imageItem.getUri();

            // Request permission to access the image data being dragged into
            // the target activity's ImageView element.
            DragAndDropPermissions dropPermissions =
                requestDragAndDropPermissions(event);

            ((ImageView)view).setImageURI(uri);

            // Release the permission immediately afterward because it's no
            // longer needed.
            dropPermissions.release();

            return true;

        // Implement logic for other DragEvent cases here.

        // An unknown action type was received.
        default:
            Log.e("DragDrop Example","Unknown action type received by View.OnDragListener.");
            break;
    }

    return false;
});

Basitleştirilmiş sürükle ve bırak için DropHelper

DropHelper sınıfı, sürükle ve bırak işlevlerinin uygulanmasını kolaylaştırır. Jetpack DragAndDrop kitaplığının bir üyesi olan DropHelper, API düzeyi 24'e kadar geriye dönük uyumluluk sunar.

Bırakma hedefleri belirtmek, bırakma hedefinin vurgulamasını özelleştirmek ve bırakılan verilerin nasıl işleneceğini tanımlamak için DropHelper öğesini kullanın.

Düşme hedefleri belirtme

DropHelper.configureView(), bırakma hedeflerini belirtmenize olanak tanıyan statik ve aşırı yüklenmiş bir yöntemdir. Bu parametrenin parametreleri şunlardır:

Örneğin, resimleri kabul eden bir bırakma hedefi oluşturmak için aşağıdaki yöntem çağrılarından birini kullanın:

Kotlin

configureView(
    myActivity,
    targetView,
    arrayOf("image/*"),
    options,
    onReceiveContentListener)

// or

configureView(
    myActivity,
    targetView,
    arrayOf("image/*"),
    onReceiveContentListener)

Java

DropHelper.configureView(
    myActivity,
    targetView,
    new String[] {"image/*"},
    options,
    onReceiveContentlistener);

// or

DropHelper.configureView(
    myActivity,
    targetView,
    new String[] {"image/*"},
    onReceiveContentlistener);

İkinci çağrı, bırakma hedefi yapılandırma seçeneklerini atlar. Bu durumda, bırakma hedefi vurgu rengi temanın ikincil (veya vurgu) rengine, vurgu köşe yarıçapı 16 dp olarak ayarlanır ve EditText bileşenleri listesi boş bırakılır. Ayrıntılar için aşağıdaki bölüme bakın.

Düşüş hedeflerini yapılandırın

DropHelper.Options iç sınıfı, bırakma hedeflerini yapılandırmanıza olanak tanır. DropHelper.configureView(Activity, View, String[], Options, OnReceiveContentListener) yöntemine sınıfın bir örneğini sağlayın. Daha fazla bilgi için önceki bölüme bakın.

Bırakma hedefi vurgulamayı özelleştirin

DropHelper, kullanıcılar içeriği hedeflerin üzerine sürükledikçe bir vurgu görüntülemek için bırakma hedeflerini yapılandırır. DropHelper, varsayılan stil özellikleri sunar. Ayrıca DropHelper.Options, vurgu rengini ayarlamanıza ve vurgunun dikdörtgeninin köşe yarıçapını belirtmenize olanak tanır.

DropHelper.Options örneği oluşturmak ve yapılandırma seçeneklerini ayarlamak için aşağıdaki örnekte gösterildiği gibi DropHelper.Options.Builder sınıfını kullanın:

Kotlin

val options: DropHelper.Options = DropHelper.Options.Builder()
                                      .setHighlightColor(getColor(R.color.purple_300))
                                      .setHighlightCornerRadiusPx(resources.getDimensionPixelSize(R.dimen.drop_target_corner_radius))
                                      .build()

Java

DropHelper.Options options = new DropHelper.Options.Builder()
                                     .setHighlightColor(getColor(R.color.purple_300))
                                     .setHighlightCornerRadiusPx(getResources().getDimensionPixelSize(R.dimen.drop_target_corner_radius))
                                     .build();

Bırakma hedeflerindeki EditText bileşenlerini işleyin

DropHelper, hedef düzenlenebilir metin alanları içerdiğinde bırakma hedefi içindeki odağı da kontrol eder.

Bırakma hedefleri, tek bir görünüm veya görünüm hiyerarşisi olabilir. Açılır hedef görünümü hiyerarşisi bir veya daha fazla EditText bileşeni içeriyorsa açılır hedef vurgulamanın ve metin verilerini işlemenin doğru çalıştığından emin olmak için DropHelper.Options.Builder.addInnerEditTexts(EditText...) bileşenlerinin bir listesini sağlayın.

DropHelper, bırakma hedefi görünümü hiyerarşisindeki EditText bileşenlerinin sürükleme etkileşimleri sırasında odağı içeren görünümden çalmasını engeller.

Ayrıca, sürükle ve bırak özelliği ClipData metin ve URI verilerini içeriyorsa DropHelper, metin verilerini işlemek için bırakma hedefindeki EditText bileşenlerinden birini seçer. Seçim, aşağıdaki öncelik sırasına göre yapılır:

  1. ClipData öğesinin atlandığı EditText.
  2. Metin imlecini (düzeltme işareti) içeren EditText.
  3. DropHelper.Options.Builder.addInnerEditTexts(EditText...), yapılan çağrıya sağlanan ilk EditText.

EditText değerini varsayılan metin veri işleyicisi olarak ayarlamak için EditText özelliğini, DropHelper.Options.Builder.addInnerEditTexts(EditText...) çağrısının ilk bağımsız değişkeni olarak iletin. Örneğin, bırakma hedefiniz resimleri işlemesine rağmen T1, T2 ve T3 düzenlenebilir metin alanları içeriyorsa T2 öğesini aşağıdaki gibi varsayılan yapın:

Kotlin

val options: DropHelper.Options = DropHelper.Options.Builder()
                                      .addInnerEditTexts(T2, T1, T3)
                                      .build()

Java

DropHelper.Options options = new DropHelper.Options.Builder()
                                     .addInnerEditTexts(T2, T1, T3)
                                     .build();

Bırakma hedeflerindeki verileri işleme

DropHelper.configureView() yöntemi, ClipData sürükle ve bırak işlemini işlemek için oluşturduğunuz bir OnReceiveContentListener öğesini kabul eder. Sürükleyip bırakma verileri, işleyiciye bir ContentInfoCompat nesnesinde sağlanır. Nesnede metin verileri var. Medya (resimler gibi) URI'ler ile temsil edilir.

Aşağıdaki görünüm türlerini yapılandırmak için DropHelper.configureView() kullanıldığında OnReceiveContentListener, sürükleyip bırakma dışındaki kullanıcı etkileşimleri (ör. kopyalama ve yapıştırma gibi) dışındaki kullanıcı etkileşimleri tarafından sağlanan verileri de işler:

  • Kullanıcı, Android 12 veya sonraki bir sürümü çalıştırıyorsa tüm görüntülemeler.
  • AppCompatEditText: Kullanıcı, Android 7.0'a kadarki bir Android sürümünü çalıştırıyorsa.

MIME türleri, izinler ve içerik doğrulama

DropHelper tarafından MIME türü kontrolü, sürükle ve bırak verilerini sağlayan uygulama tarafından oluşturulan sürükle ve bırak yöntemine ClipDescription dayanır. MIME türlerinin doğru şekilde ayarlandığından emin olmak için ClipDescription öğesini doğrulayın.

DropHelper, ClipData sürükle ve bırak işlemindeki içerik URI'leri için tüm erişim izinlerini ister. Daha fazla bilgi için DragAndDropPermissions bölümünü inceleyin. İzinler, sürükle ve bırak verilerini işlerken içerik URI'lerini çözümlemenizi sağlar.

DropHelper, bırakılan verilerdeki URI'leri çözerken içerik sağlayıcılar tarafından döndürülen verileri doğrulamaz. Boş olup olmadığını kontrol edin ve çözümlenmiş tüm verilerin doğruluğunu onaylayın.