• EditText图文混排


    下面就具体说一下我遇到的问题,首先是EditText里面的图文混排问题,这个问题的难点就是三点:

    1.怎么插图片 

    2.怎么保存插入的图片和文字 

    3.怎么解析回图片和文字

     

    解决:

    一.怎么插入图片

     

    在这里定义了两个Button按钮和一个EditText,插入图片的话,就是点击插入图片按钮然后从sd卡中选择一张图片出来。下面是实现代码:

     

    首先是button的监听事件:

    btn_insertImage.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Intent getImage = new Intent(Intent.ACTION_GET_CONTENT);
                    getImage.addCategory(Intent.CATEGORY_OPENABLE);
                    getImage.setType("image/*");
                    startActivityForResult(getImage, 1);
                }
            });

    来分析一下代码:

    1.ACTION_GET_CONTENT是标准的Activity Action的一种,那什么是Activity Action呢,简单来说就是让用户选择一种特殊的数据并得到它。
    2.通过以上分析,可以知道我们定义了这样一个intent,要取得数据,取得数据要能够被打开,且类型为image,这样我们就可以执行了。
    3.addCategory是要增加一个分类,增加一个什么分类呢?就是增加CATEGORY_OPENABLE,从字面意思值是增加一个可以打开的分类,也即是取得的uri要可以被ContentResolver解析,注意这里的分类即是执行的附加条件。
    4.通过以上分析,可以知道我们定义了这样一个intent,要取得数据,取得数据要能够被打开,且类型为image,这样我们就可以执行了。

    @Override
        protected void onActivityResult(int requestCode, int resultCode,
                Intent intent) {
            // TODO Auto-generated method stub
            super.onActivityResult(requestCode, resultCode, intent);
            ContentResolver resolver = getContentResolver();
            if (resultCode == RESULT_OK) {
                if (requestCode == 1) {
                    originalUri = intent.getData();
                    try {
                        Bitmap originalBitmap = BitmapFactory.decodeStream(resolver
                                .openInputStream(originalUri));
                        bitmap = resizeImage(originalBitmap, 100, 100);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                    if (bitmap != null) {
                        editText = (EditText) findViewById(R.id.edit);
                        insertIntoEditText(getBitmapMime(bitmap, originalUri));
                    } else {
                        Toast.makeText(MainActivity.this, "获取图片失败",
                                Toast.LENGTH_SHORT).show();
                    }
                }
            }
            if (bitmap != null) {
            }
        }

    代码分析:

    1.首先使用intent.getData得到uri

    2.然后调用BitmapFactory的解码函数decodeStream且要求的参数为流(Stream),所以要用ContentResolver解析uri为流。

    3.接着通过一个resizeImage函数重新调整bitmap大小,这里不再给出

    4.然后就是要把所得到的图片放到EditText里了

     

    private SpannableString getBitmapMime(Bitmap pic, Uri uri) {
            String path = uri.getPath();
            SpannableString ss = new SpannableString(path);
            ImageSpan span = new ImageSpan(this, pic);
            ss.setSpan(span, 0, path.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            return ss;
        }

     

    private void insertIntoEditText(SpannableString ss) {
        Editable et = editText.getText();// 先获取Edittext中的内容
        int start = editText.getSelectionStart();
        et.insert(start, ss);// 设置ss要添加的位置
        editText.setText(et);// 把et添加到Edittext中
        editText.setSelection(start + ss.length());// 设置Edittext中光标在最后面显示
    }

    代码分析:

    1.在getBitmapMime()中,首先建立一个SpannableString,r然后我们要给它附一张图片,这张图片来自我们的sd卡,然后是 setSpan()函数,这里有4个参数,分别是要插入的对象,起始位置,终止位置,标记,在本程序里插入的对象为一张图片,起始位置为0,终止位置为 path的长度,标记为会删除缓冲区里原有的text,这里即为path。

    2.在insertIntoEditText()中,因为是动态添加,所以要用到Editable,然后先把ss添加到et里,然后在放到editText里,最后在设置一下光标的位置为最后

    至此,插入图片完成

    二. 怎么保存图片?

    保存按钮的监听事件代码:

    Button btn_save = (Button) findViewById(R.id.save);
            btn_save.setOnClickListener(new OnClickListener() {
             
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    String content = editText.getText().toString();
                    Bundle data = new Bundle();
                    data.putString("nei", content);
                    Intent intent = new Intent(MainActivity.this, Display.class);
                    intent.putExtra("neirong", data);
                    startActivity(intent);
                }
            });

    代码分析:

    代码非常简单,我们只需保存editText里面的内容转化成String存到content中,(注意:这里的图片会变为它的路径即为/mnt/sdcard/.........这样的形式),

    然后我们启动另外一个Activity,这里当然也可以保存content到数据库中。

    至此,保存图片完成

    3. 怎么解析回图片和文字

    首先,我们有另外一个Activity,名字为display,注这里不在给图,因为view里只有一个EditText

    EditText display;
           
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.display);
        display = (EditText) findViewById(R.id.display);
        String imagePath = getIntent().getBundleExtra("neirong").getString(
                "nei");
        SpannableString ss = new SpannableString(imagePath);
        Pattern p=Pattern.compile("/mnt/sdcard/.+?\.\w{3}");
        Matcher m=p.matcher(imagePath);
        while(m.find()){
            Bitmap bm = BitmapFactory.decodeFile(m.group());
            Bitmap rbm = resizeImage(bm, 100, 100);
            ImageSpan span = new ImageSpan(this, rbm);
            ss.setSpan(span, m.start(), m.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        display.setText(ss);
    }

    代码分析:

    首先取出上一个Activity里面的内容,保存到imagePath中,接下来就是把imagePath中的图片改为图片即可,同样使用SpannableString,但怎么在一个很长的String中找到图片的路径呢,要使用正则表达式,这里是我写的一个正则表达式/mnt/sdcard/.+?\.\w{3}写的比较差,呵呵,通过正则表达式找到路径,就可以在BitmapFactory中找到图片,然后就可以利用setSpan()函数进行替换,最后在显示出来。

    至此,解析回图片和文字完成


    另外一种实现图文混编的方式:是通过html的<img>标签的方式插入到edittext中去:

    标 记中有一个<img>标记。通过这个标记,可以很容易地实现将图像插入到EditText的功能。不过使用<img>标签要比使 用其他的标签多一个步骤,这就是要实现一个ImageGetter接口,通过这个接口,可以获得一个Drawable对象。先看看如下的代码:

     @Override     
             public Drawable getDrawable(String source)     
             {     
                 int id = Integer.parseInt(source);     
                 Drawable d = getResources().getDrawable(id);     
                 d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());     
                 return d;     
             }   

    上面的代码通过ImageGetter接口的getDrawable方法返回了一个Drawable对象,其中source参数的值就是<img>标签的src属性的值。我们需要通过如下的代码来使用<img>标签。

        editText.append(Html.fromHtml("<imgsrc='"+ faces[new Random().nextInt(6)] +"'/>", imageGetter, null));  

    其 中faces是一个int类型数组,保存了相应的drawable资源的ID值。在使用<img>标签之前需要使用 Html.fromHtml方法来封装这些标签,如果使用的是<img>标签,需要使用fromHtml方法的第2个参数指定 ImageGetter对象,以便通过<img>标签的src属性获得相应的Drawable对象。通过EditText.append方法 插入<img>标签后,系统会自动将<img>标签转换成相应的图像显示在EditText中.

     

     

  • 相关阅读:
    Matlab 基础
    C# 基础
    Linux Shell
    【Luogu3381】【模板】缩点
    KMP学习笔记
    品味题目的味道
    【NOI2015】【BZOJ4196】软件包管理器
    宝藏
    状态压缩动态规划
    第一篇随笔
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/4176273.html
Copyright © 2020-2023  润新知