Android'in kopyalama ve yapıştırma için pano tabanlı çerçevesi, aşağıdakiler de dahil olmak üzere basit ve karmaşık veri türlerini destekler:
- Metin dizeleri
- Karmaşık veri yapıları
- Metin ve ikili akış verileri
- Uygulama öğeleri
Basit metin verileri doğrudan panoda depolanır. Karmaşık veriler ise yapıştırma uygulamasının bir içerik sağlayıcıyla çözdüğü bir referans olarak depolanır.
Kopyalama ve yapıştırma, hem bir uygulama içinde hem de çerçeveyi uygulayan uygulamalar arasında çalışır.
Çerçevenin bir kısmı içerik sağlayıcıları kullandığından bu dokümanda, Android Content Provider API hakkında bilgi sahibi olduğunuz varsayılır.
Metinle çalışma
Bazı bileşenler, aşağıdaki tabloda gösterildiği gibi metin kopyalama ve yapıştırmayı destekler.
| Bileşen | Metin kopyalanıyor | Metin yapıştırma |
|---|---|---|
| BasicTextField | ✅ | ✅ |
| TextField | ✅ | ✅ |
| SelectionContainer | ✅ |
Örneğin, aşağıdaki snippet'te karttaki metni panoya kopyalayabilir ve kopyalanan metni TextField uygulamasına yapıştırabilirsiniz.
TextField simgesine dokunup basılı tutarak veya imleç tutma yerine dokunarak metni yapıştırma menüsünü görüntüleyebilirsiniz.
val textFieldState = rememberTextFieldState() Column { Card { SelectionContainer { Text("You can copy this text") } } BasicTextField(state = textFieldState) }
Metni şu klavye kısayoluyla yapıştırabilirsiniz: Ctrl+V . Klavye kısayolu da varsayılan olarak kullanılabilir. Ayrıntılar için Klavye işlemlerini yönetme başlıklı makaleyi inceleyin.
ClipboardManager ile kopyala
ClipboardManager ile metinleri panoya kopyalayabilirsiniz.
setText() yöntemi, iletilen AnnotatedString nesnesini panoya kopyalar.
Aşağıdaki snippet, kullanıcı düğmeyi tıkladığında "Merhaba, pano" ifadesini panoya kopyalar.
// Retrieve a ClipboardManager object val clipboardManager = LocalClipboardManager.current Button( onClick = { // Copy "Hello, clipboard" to the clipboard clipboardManager.setText(AnnotatedString("Hello, clipboard")) } ) { Text("Click to copy a text") }
Aşağıdaki snippet de aynı işlemi yapar ancak size daha ayrıntılı kontrol olanağı sunar.
Yaygın kullanım alanlarından biri, şifre gibi hassas içerikleri kopyalamaktır. ClipEntry, panodaki bir öğeyi açıklar.
Panodaki verileri açıklayan bir ClipData nesnesi içerir.
ClipData.newPlainText() yöntemi, bir String nesnesinden ClipData nesnesi oluşturmak için kullanılan kullanışlı bir yöntemdir.
ClipboardManager nesnesi üzerinden setClip() yöntemini çağırarak oluşturulan ClipEntry nesnesini panoya ayarlayabilirsiniz.
// Retrieve a ClipboardManager object val clipboardManager = LocalClipboardManager.current Button( onClick = { val clipData = ClipData.newPlainText("plain text", "Hello, clipboard") val clipEntry = ClipEntry(clipData) clipboardManager.setClip(clipEntry) } ) { Text("Click to copy a text") }
ClipboardManager ile yapıştırma
ClipboardManager üzerinden getText() yöntemini çağırarak panoya kopyalanan metne erişebilirsiniz.
getText() yöntemi, panoya bir metin kopyalandığında AnnotatedString nesnesi döndürür.
Aşağıdaki snippet, panodaki metni TextField içindeki metne ekler.
val textFieldState = rememberTextFieldState() Column { TextField(state = textFieldState) Button( onClick = { // The getText method returns an AnnotatedString object or null val annotatedString = clipboardManager.getText() if (annotatedString != null) { // The pasted text is placed on the tail of the TextField textFieldState.edit { append(annotatedString.text) } } } ) { Text("Click to paste the text in the clipboard") } }
Zengin içeriklerle çalışma
Kullanıcılar resimleri, videoları ve diğer etkileyici içerikleri sever.
Uygulamanız, kullanıcının ClipboardManager ve ClipEntry ile zengin içerikleri kopyalamasına olanak tanıyabilir.
contentReceiver değiştiricisi, zengin içerik yapıştırma özelliğini uygulamanıza yardımcı olur.
Zengin içeriği kopyalama
Uygulamanız, zengin içeriği doğrudan panoya kopyalayamaz.
Bunun yerine, uygulamanız panoya bir URI nesnesi iletir ve ContentProvider ile içeriğe erişim sağlar.
Aşağıdaki kod snippet'inde, JPEG resmin panoya nasıl kopyalanacağı gösterilmektedir.
Ayrıntılar için Veri akışlarını kopyalama bölümüne bakın.
// Get a reference to the context val context = LocalContext.current Button( onClick = { // URI of the copied JPEG data val uri = Uri.parse("content://your.app.authority/0.jpg") // Create a ClipData object from the URI value // A ContentResolver finds a proper ContentProvider so that ClipData.newUri can set appropriate MIME type to the given URI val clipData = ClipData.newUri(context.contentResolver, "Copied", uri) // Create a ClipEntry object from the clipData value val clipEntry = ClipEntry(clipData) // Copy the JPEG data to the clipboard clipboardManager.setClip(clipEntry) } ) { Text("Copy a JPEG data") }
Zengin içerik yapıştırma
contentReceiver değiştiricisiyle, değiştirilen bileşende zengin içeriğin BasicTextField öğesine yapıştırılmasını yönetebilirsiniz.
Aşağıdaki kod snippet'i, bir resim verisinin yapıştırılan URI'sini Uri nesneleri listesine ekler.
// A URI list of images val imageList = remember { mutableStateListOf<Uri>() } // Remember the ReceiveContentListener object as it is created inside a Composable scope val receiveContentListener = remember { ReceiveContentListener { transferableContent -> // Handle the pasted data if it is image data when { // Check if the pasted data is an image or not transferableContent.hasMediaType(MediaType.Image) -> { // Handle for each ClipData.Item object // The consume() method returns a new TransferableContent object containging ignored ClipData.Item objects transferableContent.consume { item -> val uri = item.uri if (uri != null) { imageList.add(uri) } // Mark the ClipData.Item object consumed when the retrieved URI is not null uri != null } } // Return the given transferableContent when the pasted data is not an image else -> transferableContent } } } val textFieldState = rememberTextFieldState() BasicTextField( state = textFieldState, modifier = Modifier .contentReceiver(receiveContentListener) .fillMaxWidth() .height(48.dp) )
contentReceiver değiştiricisi, bağımsız değişken olarak bir ReceiveContentListener nesnesi alır ve kullanıcı, değiştirilen bileşenin içindeki BasicTextField öğesine veri yapıştırdığında iletilen nesnenin onReceive yöntemini çağırır.
onReceive yöntemine bir TransferableContent nesnesi iletilir. Bu nesne, bu durumda yapıştırılarak uygulamalar arasında aktarılabilen verileri açıklar.
ClipEntry nesnesine clipEntry özelliğini kullanarak erişebilirsiniz.
Örneğin, kullanıcı birden fazla resim seçip bunları panoya kopyaladığında bir ClipEntry nesnesinde birden fazla ClipData.Item nesnesi olabilir.
Her ClipData.Item nesnesi için tüketildi veya yoksayıldı olarak işaretlemeniz ve yoksayılan ClipData.Item nesnelerini içeren bir TransferableContent döndürmeniz gerekir. Böylece en yakın üst öğe contentReceiver değiştiricisi bunu alabilir.
TransferableContent.hasMediaType() yöntemi, TransferableContent nesnesinin medya türüne sahip bir öğe sağlayıp sağlayamayacağını belirlemenize yardımcı olabilir.
Örneğin, TransferableContent nesnesi bir resim sağlayabiliyorsa aşağıdaki yöntem çağrısı true değerini döndürür.
transferableContent.hasMediaType(MediaType.Image)
Karmaşık verilerle çalışma
Karmaşık verileri, zengin içeriklerde olduğu gibi panoya kopyalayabilirsiniz. Ayrıntılar için Karmaşık verileri kopyalamak için içerik sağlayıcıları kullanma başlıklı makaleyi inceleyin.
Karmaşık verilerin yapıştırılmasını da zengin içerik için aynı şekilde işleyebilirsiniz.
Yapıştırılan verilerin URI'sini alabilirsiniz.
Gerçek veriler ContentProvider kaynağından alınabilir.
Daha fazla bilgi için Sağlayıcıdan veri alma bölümüne bakın.
İçerik kopyalamayla ilgili geri bildirim
Kullanıcılar, içeriği panoya kopyaladıklarında geri bildirim beklerler. Bu nedenle, kopyalama ve yapıştırma işlemlerini destekleyen çerçeveye ek olarak Android, Android 13 (API düzeyi 33) ve sonraki sürümlerde kopyalama işlemi yapan kullanıcılara varsayılan bir kullanıcı arayüzü gösterir. Bu özellik nedeniyle yinelenen bildirim riski vardır. Bu uç durum hakkında daha fazla bilgiyi Yinelenen bildirimleri önleme bölümünde bulabilirsiniz.
Android 12L (API düzeyi 32) ve önceki sürümlerde kopyalama yaparken kullanıcılara manuel olarak geri bildirim sağlayın. Öneriye göz atın.
Hassas içerik
Uygulamanızın, kullanıcının şifreler gibi hassas içerikleri panoya kopyalamasına izin vermesini tercih ederseniz uygulamanızın bunu sisteme bildirmesi gerekir. Böylece sistem, kopyalanan hassas içeriğin kullanıcı arayüzünde gösterilmesini engelleyebilir (Şekil 2).
ClipboardManager nesnesi üzerinden setClip() yöntemini çağırmadan önce ClipData içinde ClipDescription'e bir işaret eklemeniz gerekir:
// If your app is compiled with the API level 33 SDK or higher. clipData.apply { description.extras = PersistableBundle().apply { putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true) } } // If your app is compiled with a lower SDK. clipData.apply { description.extras = PersistableBundle().apply { putBoolean("android.content.extra.IS_SENSITIVE", true) } }