🎊 Android自定义文本选中模式(全选、复制,剪切,粘帖)

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

}

首先要去自定义一个菜单布局:

>

android:id="@+id/it_all"

android:title="全选"

android:icon="@drawable/all"

/>

android:id="@+id/it_copy"

android:title="复制"

android:icon="@drawable/copy"

/>

android:id="@+id/it_cut"

android:title="剪切"

android:icon="@drawable/cut"

/>

android:id="@+id/it_paste"

android:title="粘帖"

/>

这里的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”)创建普通字符型ClipDataClipData.newRawUri(“Label”, Uri.parse(“https://www.baidu.com/“)) 创建URL型ClipDataClipData.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:jrtxb520@163.com

**/

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:源码下载

🎁 相关推荐

课后星官方版下载
🎯 365足彩推荐

课后星官方版下载

📅 06-28 👀 7092
浏览器能上网但下载不了软件的解决办法
🎯 365bet中文网站

浏览器能上网但下载不了软件的解决办法

📅 06-28 👀 1154
excel工作表怎么做封面
🎯 bat365官方网站

excel工作表怎么做封面

📅 06-27 👀 9971