今天來學學如何使用Clipboard
其實也就是俗稱的“剪貼簿”啦!(`・ω・´)+
調閱官方網站的資料的話
官網甚至直接命名Copy and Paste
https://developer.android.com/guide/topics/text/copy-paste
要搜尋關鍵字的話,搜尋
- android Copy and Paste
- android clipboard
- android 剪貼簿
- android 文字複製
...等等,基本上就是秀出很多你想知道的資訊了(•ө•)♡
另外,雖然一般而言手機廠商在出廠時其實都會有內建剪貼簿
不過今天想做的事就是針對像是ListView、RecyclerView內部的資料做複製與貼上
那以下就是今天的範例:
以及GitHub:
https://github.com/thumbb13555/ClipboardExample/tree/master
1.功能需求設置介面
1-1功能需求
歸納一下今天想要完成的功能
- 建立一個ListView,再將欲複製之字元串放在裡面
- 長點擊ListView元件即可複製
- 長點擊EditText即可直接將剛才複製的元件貼上去
1-2設置介面
因為這次要設置的東西不多,因此直接貼上來了
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="120dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<EditText
android:id="@+id/editText_in"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPersonName" />
<Button
android:id="@+id/button_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="清除文字" />
</LinearLayout>
<ListView
android:id="@+id/listview_TextBox"
android:layout_width="0dp"
android:layout_height="300dp"
android:layout_marginTop="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>
樹狀圖長這樣
1-3加入震動權限
我刻意讓APP在完成複製或貼上時會讓手機有一個小震動(・∀・)
關於震動的使用方法超簡單,兩行的事兒,沒事兒沒事兒(´υ`)
但是還是得加入震動權限
請點擊AndroidManifest.xml
並在<manifest>標籤外部加入震動權限
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jetec.clipboardexample">
<uses-permission android:name="android.permission.VIBRATE" />
<!--震動權限-->
<application ...
2.功能撰寫
接著撰寫功能的部分
因為程式不多,直接上程式吧
public class MainActivity extends AppCompatActivity {
ArrayList<String> arrayList = new ArrayList<>();
ListView listView;
ClipboardManager clipboard = null;//複製貼上
ClipData clipData = null;//複製貼上
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button clear= findViewById(R.id.button_clear);
EditText editText = findViewById(R.id.editText_in);
listView = findViewById(R.id.listview_TextBox);
/**=========================================設置複製素材庫↓=========================================*/
for (int i=0;i<4;i++){
arrayList.add("複製素材"+i);
}
ArrayAdapter adapter
= new ArrayAdapter(this,android.R.layout.simple_list_item_1,arrayList);
listView.setAdapter(adapter);
/**=========================================設置複製素材庫↑=========================================*/
//ListView素材庫長點擊處理
listView.setOnItemLongClickListener((parent, view, position, id)->{
Vibrator myVibrator = (Vibrator) getApplication()//取得震動
.getSystemService(Service.VIBRATOR_SERVICE);
myVibrator.vibrate(50);
clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
clipData = ClipData.newPlainText(null,arrayList.get(position));
clipboard.setPrimaryClip(clipData);
Toast.makeText(this, "已複製: " + arrayList.get(position)
, Toast.LENGTH_SHORT).show();
return false;
});
//EditText長點擊處理
editText.setOnLongClickListener((v -> {
Vibrator myVibrator = (Vibrator) getApplication()//取得震動
.getSystemService(Service.VIBRATOR_SERVICE);
myVibrator.vibrate(50);
try {//如果未複製任何字就施行貼上,會導致程式閃退
ClipData word = clipboard.getPrimaryClip();
ClipData.Item item = word.getItemAt(0);
String text = item.getText().toString();
editText.setText(editText.getText().toString()+text);
Toast.makeText(this, "已貼上: " + text, Toast.LENGTH_SHORT).show();
}catch (Exception e){
Toast.makeText(this, "未複製任何字串", Toast.LENGTH_SHORT).show();
}
return true;
}));
clear.setOnClickListener(v -> {editText.setText("");});//清除Edittext內字串
}//EndOnCreate
}
幾個顏色部分講解
- 淺紅是onCreate範圍,沒什麼意義
- 綠色是全域變數
- 紫色是使用震動
然後再來詳細看一下複製與貼上的程式碼
複製:
clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
clipData = ClipData.newPlainText(null,arrayList.get(position));
clipboard.setPrimaryClip(clipData);
clipboard的部分是我有在全域變數中(綠色)宣告過的ClipboardManager
以及存放clipData的變數以樣是在全域變數中(綠色)宣告過的ClipData
最後再細看第二行
clipData = ClipData.newPlainText(null,arrayList.get(position));
的部分,紅字的部分是用來存放字串的;官網有寫如果想存放位址(URI)或Intent
可以向官網這個示範
https://developer.android.com/guide/topics/text/copy-paste?hl=zh_cn#Copying
Text官網示範:
ClipData clip = ClipData.newPlainText("simple text", "Hello, World!");
URL官網示範:
// Creates a Uri based on a base Uri and a record ID based on the contact's last name
// Declares the base URI string
private static final String CONTACTS = "content://com.example.contacts";
// Declares a path string for URIs that you use to copy data
private static final String COPY_PATH = "/copy";
// Declares the Uri to paste to the clipboard
Uri copyUri = Uri.parse(CONTACTS + COPY_PATH + "/" + lastName);
...
// Creates a new URI clip object. The system uses the anonymous getContentResolver() object to
// get MIME types from provider. The clip object's label is "URI", and its data is
// the Uri previously created.
ClipData clip = ClipData.newUri(getContentResolver(), "URI", copyUri);
Intent官網示範:
// Creates the Intent
Intent appIntent = new Intent(this, com.example.demo.myapplication.class);
...
// Creates a clip object with the Intent in it. Its label is "Intent" and its data is
// the Intent object created previously
ClipData clip = ClipData.newIntent("Intent", appIntent);
最後解釋一下,在我的示範中,前面那個是null
clipData = ClipData.newPlainText(null,arrayList.get(position));
那這又是什麼?其實這個就有點接近索引標籤
假設A區域複製的東西只能貼在A區域內容
那你的索引就把它設置為A區域的代號
這樣就可以實現在特定區域貼上特定區域的複製內容了(´・з・)
貼上:
ClipData word = clipboard.getPrimaryClip();
ClipData.Item item = word.getItemAt(0);
String text = item.getText().toString();
邏輯事先取得剪貼簿內的陣列(他存在ClipBoard內)
然後以ClipData.Item儲存取得的內容
最後在將它轉型為字串String釋出
請注意這整取出方法跟取陣列特定值的原理是一致的
因此若取出值是空,那就會閃退回報空值指針異常
要特別注意了(・ω・)b
最後將取得到的字放入EditText內,按下執行,就能得出想要的效果囉(・ωー)~☆
結語
講個笑話,其實大部分的使用者直接用手機內建的就好(´・_・`)
不過值得開心的是,按照我的這個方法其實他的剪貼簿可以與手機內建的共用
因此某些程度上來說,只要撰寫ListView的點擊事件基本上就萬事大吉了XD
那麼今天的範例到此,希望對你有幫助
喜歡我的文章可以將我的部落格網頁加入瀏覽器的標籤頁哦!掰逼!
留言列表