以前一直不明白,可以插入图片,和文本的记事本如何实现的,以前用ListView 实现过,好多监听事件处理不好,就放下了。
在网上找到一个开源的RichText,把我隐藏在心里的疑惑解开了。它采用自定义ScrollView ,添加EditText 和ImageView 来做处理。
完美实现了可以插入图片和文本的EditText.
代码有的地方不知道如何用的,就自己按照自己的思路在这个基础上改,改成自己可以理解的思路。
public class RichTextEditor extends ScrollView
初始化首先添加十几个EditText ,其中只有第一个,第二个为可编辑状态,标题和文本内容的EditText,其它的EditText
都是setEnable设置false
我们来看一下初始化的方法
public RichTextEditor(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
inflater = LayoutInflater.from(context);
this.context = context;
list_et = new ArrayList<>();//存储EditText 的实例集合
// 1. 初始化allLayout
allLayout = new LinearLayout(context);//初始化垂直方向的LinearLayout 用 来添加EditText 和ImageView
allLayout.setOrientation(LinearLayout.VERTICAL);
allLayout.setBackgroundColor(Color.WHITE);
setupLayoutTransitions();//设置添加ImageView的动画
LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
addView(allLayout, layoutParams);
// 2. 初始化键盘退格监听
// 主要用来处理点击回删按钮时,view的一些列合并操作
keyListener = new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
Log.e("gac","onKey");
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
Log.e("gac","onKey del");//监听EditText退格事件,用来删除ImageView,或者将EditText焦点,转移到上一行
LineEditText edit = (LineEditText) v;//EditText焦点
onBackspacePress(edit);
return false;
}
if(event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER){
Log.e("gac","onKey enter");//监听回车事件
LineEditText editText = (LineEditText)v;
int index = (int)editText.getTag();//获取EditText在集合中的位置
Log.e("gac","index:"+index);
Log.e("gac","viewTagIndex:"+viewTagIndex);//viewTagIndex 为EditText集合的个数
if(index == 0){//如果是第一个EditText的回车事件 则设置第二个EditText获取焦点
setEnableEditText(list_et.get(1));//
return true;
}
if(index < viewTagIndex-1){//如果index不是最后一个则下一个EditText获取焦点
setEnableEditText(list_et.get(index + 1));//
}else{//如果index是最后一个则创建一个新的EditText 并且设置焦点
Log.e("gac","create text");
lastFocusEdit = createLineEditText("", true);
setEnableEditText(list_et.get(index+1));
}
return true;
}
return false;
}
};
// 3. 图片叉掉处理
btnListener = new OnClickListener() {//图片上面的close图标的监听事件
@Override
public void onClick(View v) {
RelativeLayout parentView = (RelativeLayout) v.getParent();
onImageCloseClick(parentView);
}
};
focusListener = new OnFocusChangeListener() {//每当某个EditText获取焦点则 记录这个EditText
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
lastFocusEdit = (LineEditText) v;
}
}
};
initRichEditText(context);//初始化文本EditText 12个EditText 最好根据屏幕的高度计算出Edittext的行数
//createFirstEditText();
}
//监听退格事件删除图片的函数
private void onBackspacePress(LineEditText editTxt) {
int startSelection = editTxt.getSelectionStart();
// 只有在光标已经顶到文本输入框的最前方,在判定是否删除之前的图片,或两个View合并
if (startSelection == 0) {
int editIndex = allLayout.indexOfChild(editTxt);
View preView = allLayout.getChildAt(editIndex - 1); // 如果editIndex-1<0,
// 则返回的是null
if (null != preView) {
if (preView instanceof RelativeLayout) {
// 光标EditText的上一个view对应的是图片
onImageCloseClick(preView);
} else if (preView instanceof EditText) {
// 光标EditText的上一个view对应的还是文本框EditText
setEnableEditText((LineEditText)preView);
}
}
}
}
/**
* 处理图片叉掉的点击事件
*
* @param view
* 整个image对应的relativeLayout view
* @type 删除类型 0代表backspace删除 1代表按红叉按钮删除
*/
private void onImageCloseClick(View view) {
if (!mTransitioner.isRunning()) {
disappearingImageIndex = allLayout.indexOfChild(view);
allLayout.removeView(view);
}
}
//当在文本框中插入图片的函数
/**
* 根据绝对路径添加view
*
* @param imagePath
*/
public void insertImage(String imagePath) {
Log.e("gac", "iamgePath:" + imagePath);
Bitmap bmp = getScaledBitmap(imagePath, getWidth());
if(bmp == null){
//此处可以插入 默认的照片丢失的图片
//Log.e("gac","bmp is null");
return;
}else{
//Log.e("gac","bmp is not null");
}
insertImage(bmp, imagePath);
}
/**
* 插入一张图片
*/
private void insertImage(Bitmap bitmap, String imagePath) {
//获取最后一个获取焦点的EditText
String lastEditStr = lastFocusEdit.getText().toString();
int cursorIndex = lastFocusEdit.getSelectionStart();
String editStr1 = lastEditStr.substring(0, cursorIndex).trim();
int lastEditIndex = allLayout.indexOfChild(lastFocusEdit);//图片插入的位置
int foucseditindex = (int)lastFocusEdit.getTag();//EditText list集合中的位置
Log.e("gac","lastEditIndex:"+foucseditindex);
//文本内容为空的时候则在EditText的上方插入图片
if (lastEditStr.length() == 0 || editStr1.length() == 0) {
if(lastEditIndex == 0){
//防止标题栏上面插入图片
lastEditIndex = 1;
setEnableEditText(list_et.get(1));
addImageViewAtIndex(lastEditIndex, bitmap, imagePath,1);
}else{
// 如果EditText为空,或者光标已经顶在了editText的最前面,则直接插入图片,并且EditText下移即可
addImageViewAtIndex(lastEditIndex, bitmap, imagePath,foucseditindex);
}
} else {
//edittext有内容的时候 则在EditText下面添加图片 给下一个EditText获取焦点
// 当前editext是否是最后一个edittext 是则创建新的edittext 给下一个EditText获取焦点
if (allLayout.getChildCount() - 1 == lastEditIndex) {
setEnableEditText(createLineEditText("", true));
addImageViewAtIndex(lastEditIndex + 1, bitmap, imagePath,foucseditindex+1);
} else {
addImageViewAtIndex(lastEditIndex + 1, bitmap, imagePath,foucseditindex+1);
}
// lastFocusEdit.requestFocus();
// lastFocusEdit.setSelection(editStr1.length(), editStr1.length());
}
hideKeyBoard();//隐藏软键盘
}
以上是这个richEditText关键代码,虽然看似简单,但是让我实现,我真可能写不出来。。
接着就可以扩展自己的richEdittext 添加音频,标签等功能。现在就相当于一个可以实现很多东西的富文本了。
哎,以前天真的以为真是EditText做的。