Android自定義文字選中模式(全選、複製,剪下,粘帖)
為了方便操作,在PC端我們常用的Ctrl+A(全選)/Ctrl+C(複製)/Ctrl+X(剪下)/Ctrl+V(粘帖)提高了我們的辦公效率。然後在手機端怎麼實現呢?我花了一天的時間研究了一下。
- 首先說一下TextView的選中,要想選中TextView中的文字有兩種方式:
1、setSelectAllOnFocus(true);
2、android:textIsSelectable=”true” - 然後看一下EditText
從上面的圖可以看出EditText是繼承於TextView的,所以setSelectAllOnFocus(true)和android:textIsSelectable=”true”對它也同樣適用,不過EditText預設setSelectAllOnFocus(true),所以沒有必要手動設定;如果真的在佈局檔案中設定了android:textIsSelectable=”true”,那麼EditText就不能被編輯,失去了游標,如下圖:
所以android:textIsSelectable=”true”一般是給TextView設定的。
首先我們看一下預設的選中模式(上面彈出操作提示框):
那麼要想改變原有的東西呢?這裡有一個方法
setCustomSelectionActionModeCallback(new MyActionModeCallback(ActionMode.Callback callback));
通過ActionMode.Callback中的四個回撥方法進行操作:
//建立選單
@Override
public boolean onCreateActionMode (ActionMode actionMode, Menu menu) {
return true;
}
//這個相當於是選單建立好以後的操作
@Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return true;
}
//選單中item的點選處理
@Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
return true;
}
//選單銷燬操作
@Override
public void onDestroyActionMode(ActionMode actionMode) {
}
首先要去自定義一個選單佈局:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
>
<item
android:id="@+id/it_all"
android:title="全選"
android:icon="@drawable/all"
/>
<item
android:id="@+id/it_copy"
android:title="複製"
android:icon="@drawable/copy"
/>
<item
android:id="@+id/it_cut"
android:title="剪下"
android:icon="@drawable/cut"
/>
<item
android:id="@+id/it_paste"
android:title="粘帖"
/>
</menu>
這裡的android:icon=“@drawable/xxx”設定了,但是不顯示。然後在onCreateActionMode方法中去初始化選單;
MenuInflater menuInflater = actionMode.getMenuInflater();
menuInflater.inflate(R.menu.menu,menu);
return true;
選單建立好以後就是具體的操作了。
全選
Edittext有個selectAll()方法來實現全選;這個方法是Edittext獨有的,所以TextView是沒這個方法的。
複製、剪下
複製和剪下的原理一樣,就是最後的處理稍有不同,所以我把他們放在了同一個方法中進行處理。
/**
* 統一處理複製和剪下的操作
* @param mode 用來區別是複製還是剪下
* @return
*/
private String getSelectText(SelectMode mode) {
//獲取剪下班管理者
ClipboardManager cbs = (ClipboardManager) mContext.getSystemService(CLIPBOARD_SERVICE);
//獲取選中的起始位置
int selectionStart = mTvSelect.getSelectionStart();
int selectionEnd = mTvSelect.getSelectionEnd();
Log.i(TAG,"selectionStart="+selectionStart+",selectionEnd="+selectionEnd);
//擷取選中的文字
String txt = mTvSelect.getText().toString();
String substring = txt.substring(selectionStart, selectionEnd);
Log.i(TAG,"substring="+substring);
//將選中的文字放到剪下板
cbs.setPrimaryClip(ClipData.newPlainText(null,substring));
//如果是複製就不往下操作了
if (mode==SelectMode.COPY)
return txt;
//把剪下後的資料替換""
txt = txt.replace(substring, "");
return txt;
}
/**
* 用列舉來區分是複製還是剪下
*/
public enum SelectMode{
COPY,CUT;
}
這裡我把相容低版本沒有做,API Level 11以前用的setText(),getText(),hasText()這三個方法做複製粘帖的操作(只限於對文字的操作);以後的API中廢棄了以前的三個方法,通過ClipData物件來操作文字、Uri和Intent,用ClipboardManager.setPrimaryClip(ClipData data),ClipboardManager.getPrimaryClip()和hasPrimaryClip()代替前面的三個方法了。這裡操作的就不是純文字,而是複雜的物件了。
ClipData 的三個靜態方法分別擔任不同的工作(ClipData物件中包含一個或多個ClipData.Item物件)
- ClipData.newPlainText(“Label”, “Content”)建立普通字元型ClipData
- ClipData.newRawUri(“Label”, Uri.parse(“https://www.baidu.com/“)) 建立URL型ClipData
- ClipData.newIntent(“Label”, intent)建立Intent型ClipData
粘帖
//獲取剪下班管理者
ClipboardManager cbs = (ClipboardManager) mContext.getSystemService(CLIPBOARD_SERVICE);
if (cbs.hasPrimaryClip()){
mTvSelect.setText(cbs.getPrimaryClip().getItemAt(0).getText());
}
基本操作就OK了,我把完整的Java程式碼貼一下。
/**
* 描述:文字的選中模式的使用
* 開發者:開發者的樂趣JRT
* 建立時間:2017-3-12 12:29
* CSDN地址:http://blog.csdn.net/Jiang_Rong_Tao/article
* E-mail:[email protected]
**/
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private EditText mTvSelect;
private MainActivity mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext =this;
init();
}
private void init() {
mTvSelect = (EditText) findViewById(R.id.tv_select);
mTvSelect.setCustomSelectionActionModeCallback(new MyActionModeCallback());
}
private class MyActionModeCallback implements ActionMode.Callback {
private Menu mMenu;
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
MenuInflater menuInflater = actionMode.getMenuInflater();
menuInflater.inflate(R.menu.menu,menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
//選單建立完成以後獲取到其物件,便於後續操作
this.mMenu=menu;
return true;
}
@Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
switch (menuItem.getItemId()){
case R.id.it_all:
//全選
mTvSelect.selectAll();
Toast.makeText(mContext, "完成全選", Toast.LENGTH_SHORT).show();
break;
case R.id.it_copy:
String selectText = getSelectText(SelectMode.COPY);
//setText(selectText)是為了後面的this.mMenu.close()起作用
mTvSelect.setText(selectText);
Toast.makeText(mContext, "選中的內容已複製到剪下板", Toast.LENGTH_SHORT).show();
this.mMenu.close();
break;
case R.id.it_cut:
//剪下
String txt = getSelectText(SelectMode.CUT);
mTvSelect.setText(txt);
Toast.makeText(mContext, "選中的內容已剪下到剪下板", Toast.LENGTH_SHORT).show();
this.mMenu.close();
break;
case R.id.it_paste:
//獲取剪下班管理者
ClipboardManager cbs = (ClipboardManager) mContext.getSystemService(CLIPBOARD_SERVICE);
if (cbs.hasPrimaryClip()){
mTvSelect.setText(cbs.getPrimaryClip().getItemAt(0).getText());
}
this.mMenu.close();
break;
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode actionMode) {
}
}
/**
* 統一處理複製和剪下的操作
* @param mode 用來區別是複製還是剪下
* @return
*/
private String getSelectText(SelectMode mode) {
//獲取剪下班管理者
ClipboardManager cbs = (ClipboardManager) mContext.getSystemService(CLIPBOARD_SERVICE);
//獲取選中的起始位置
int selectionStart = mTvSelect.getSelectionStart();
int selectionEnd = mTvSelect.getSelectionEnd();
Log.i(TAG,"selectionStart="+selectionStart+",selectionEnd="+selectionEnd);
//擷取選中的文字
String txt = mTvSelect.getText().toString();
String substring = txt.substring(selectionStart, selectionEnd);
Log.i(TAG,"substring="+substring);
//將選中的文字放到剪下板
cbs.setPrimaryClip(ClipData.newPlainText(null,substring));
//如果是複製就不往下操作了
if (mode==SelectMode.COPY)
return txt;
txt = txt.replace(substring, "");
return txt;
}
/**
* 用列舉來區分是複製還是剪下
*/
public enum SelectMode{
COPY,CUT;
}
}
注意:這裡this.mMenu.close()有個細節,如果單純的呼叫close方法是不起作用的,必須EditText的文字有所變化
- 如果不重新設定EditText的文字,則menu的close方法不管用
- 重新設定文字後
總結
基本的操作就到此結束了,EditText的UI和選中後的游標也有點抽,這些都是可以自定義改變的,具體操作,自行Search。
github:原始碼下載
相關推薦
Android自定義文字選中模式(全選、複製,剪下,粘帖)
為了方便操作,在PC端我們常用的Ctrl+A(全選)/Ctrl+C(複製)/Ctrl+X(剪下)/Ctrl+V(粘帖)提高了我們的辦公效率。然後在手機端怎麼實現呢?我花了一天的時間研究了一下。 首先說一下TextView的選中,要想選中TextV
【朝花夕拾】Android自定義View篇之(四)Canvas繪製文字教程
前言 前面的文章中在介紹Canvas的時候,提到過後續單獨講Canvas繪製文字,因為這一節內容比較細緻,內容很多。這裡先宣告一下,本文的內容的來源於騰訊課堂中“仍物線學堂”中課件,因為該課件對常用的繪製文字基本技巧做了比較詳細的講解
TabTopAutoTextSizeLayout【自定義文字字號區域(動態選項卡數據且可滑動)】
標題 unit near cnblogs 重新 auto target 類文件 fault 版權聲明:本文為HaiyuKing原創文章,轉載請註明出處! 前言 自定義頂部選項卡布局LinearLayout類,實現可滑動效果。【實際情況中建議使用RecyclerView】
android 自定義文字字型
@SuppressLint("AppCompatCustomView") public class TypefaceTextView extends TextView { //字型檔案放在assets檔案中 // fongUrl是自定義字型分類的名稱 private static S
Android 自定義橫向進度條(可動態設定最大值)
自定義橫向進度條 主佈局檔案中包 含 <LinearLayout android:id="@+id/linearlayout" android:layout_width="match_parent" androi
android自定義文字框,後面帶清空按鈕
class MyEditText extends EditText { private final String TAG = "MyEditText"; private Drawable dRight; private Rect rBounds; // 構造器 public MyEditText(Conte
Android 自定義view --圓形百分比(進度條)
注:本文由於是在學習過程中寫的,存在大量問題(overdraw onDraw new物件),請讀者們不要被誤導!!解決辦法見後面的部落格。 起因 最近公司專案有需求需要用到輕量級圖表如下
android 自定義dialog的實現(自定義大小、去除黑色邊框等)
搜尋相關關鍵字網上一大堆實現,但是看完總覺得缺胳膊少腿,繞了不少彎路,終於弄好了自定義dialog。把自己整合的完整程式碼發上來。 要點: 1、設定自定義dialog的佈局檔案my_dialog.xml 2、設定一份自定義的樣式檔案styles_wx.xml,該檔案用於覆
Android自定義view第一彈(防小米計步)
廢話不多說,先上效果圖: 右上腳的計步(有動畫效果) 從來不說廢話,上程式碼: 一.自定義View 程式碼 /** * 計步View * Created by DYJ on 2017/8/3. */ public class RunningV
簡單談談android自定義相機的實現(上 android.hardware.Camera)
通常情況下,呼叫android系統相機基本上可以滿足拍照的需求,而自定義相機的需求一般來自於開發自己的相機應用,今天我們來簡單聊聊android自定義相機的實現,限於篇幅,我們上篇只討論android.hardware.Camera,下篇我會和大家一起討論一下a
Android自定義視訊播放器(三)
一、引言 在上文中,我們通過自定義控制面板的佈局,來實現自定義的播放控制,下面來對裡面的各個元件進行事件繫結。 @Override public void onClick(View v) { if ( v == btnVoice ) {
Android自定義文字閃爍漸變色的跑馬燈
最近因為專案需要,一直都在尋找比較貼合專案主題的跑馬燈,但是寫的demo都是可以執行的,但是整合到專案中的時候就不起作用了,看了許多的資料,最後總結這都是執行緒的問題,後來各種搗騰,終於寫出了一個比較合適的跑馬燈,整合到專案中也是可以執行的,希望大神能多多指點 自定義一個控
Android 自定義View--ProgressBar篇(一)
1、概述 1.1 目的 : 在我們的日常開發中,有很多Android UI介面上有一些特殊或者特別的控制元件與介面,是Android自帶的控制元件所不能滿足的,需要我們自己定製一些適合的控制元件來完成。 1.2 Android自定義View步驟 : 自定
Android自定義視訊播放器(六)
一、引言 現在已經差不多完成了一個自定義的視訊播放器,還有一個讓視訊全屏播放的按鈕事件沒有繫結,下面會介紹。此外還要一個非常重要的功能就是,已經寫好了自定義的播放器,那麼就應該能被其他應用調起,來播放視訊,下面來完善這兩個功能。 二、全屏按鈕事件
android自定義環形統計圖(帶動畫)
一、測試截圖 二、實現原理 package com.freedomanlib; import java.util.Timer; import java.util.TimerTask; import android.annotation.SuppressLint;
Android自定義視訊播放器(一)
一、引言 我們在開發Android多媒體應用時,有兩種方式來播放多媒體資源。第一種是使用隱式的Intent,來使用系統或者手機已經安裝的第三方播放器應用來播放音視訊,第二種是使用Android自帶的、我們自定義的播放器來播放,這種主要是採用Android提供的
android自定義view之地圖(一)
最近參加了一個比賽,要用到自己做一個自定義的小地圖,所以在網上查找了一些關於自定義view的有關資料,也瞭解了自定義控制元件的初步知識。 效果圖 第一階段我畫了一個自制的網格圖,點哪個網格就會哪個網格就會顯示。 工作環境圖 程式碼介紹
Android自定義ActionBar背景顏色(從原始碼分析)
Android自定義ActionBar背景顏色 修改前後效果圖: 在style.xml里加一行程式碼搞定 <!-- Base application theme. --> <style name="AppTheme" parent="
Android 自定義鍵盤 隨機鍵盤(完全定製,向上頂佈局,點選按鈕進行隱藏)
之前上傳的另外一個自定義鍵盤,並沒有實現鍵盤彈出的時候,佈局向上自動調整。(網路上所有的自定義鍵盤都沒有新增自適應的功能,而且佈局沒這麼好看,上一個例子資源連結為:http://download.csdn.net/detail/omayyouhappy/91118
Android自定義AutoCompleteTextView實現自動補全Email
本篇主要實現了你可以自行控制從第一個字元開始進行聯想 public class AutoComplete extends AutoCompleteTextView { //輸入字元進行聯想,@163.com、@126.com、@qq.com、@sina.com、