网上发现有大神写的一些好东西,我自己也收藏下,
【链接】LiushuiXiaoxia/TextStylePlus
https://github.com/LiushuiXiaoxia/TextStylePlus
这个图文加载textview 比我自己整的好很多,就是不适合大图以及不规则顺序的加载,适合图标+文字布局,合并一个控件显示
如果从网上获取数据,数据包含图文结合,那么这个方法用不了,就用自己写的
String html = t.getComment(); if (html.contains(".jpg") || html.contains(".png") || html.contains("jpeg") || html.contains(".gif")) { if (html.contains("http://") || html.contains("https://")) { String regexstr = "<(?!img).*?>"; // // 去除所有标签,只剩img html = html.replaceAll(regexstr, ""); } } else { html = html.replaceAll("\r", ""); html = html.replaceAll("\n", ""); html = html.replaceAll("\t", ""); html = html.replaceAll("</?[p|P][^>]*>", ""); } if(t.getIsreply().equals("1")){ String str ="<font color=\"#298fb7\">" + t.getReauthor() + "</font>回复"+"<font color=\"#298fb7\">" + t.getAuthor() + "</font>:"; html =str+html; }else{ String str ="<font color=\"#298fb7\">" + t.getAuthor() + "</font>:"; html =str+html; } Spanned spanned = Html.fromHtml(html, new MyImageGetter(mContext, replytv, memoryCache, null, null), null);
public class MyImageGetter implements ImageGetter { private Context context; private TextView tv; private MemoryCache memoryCache ; private Map<String, Bitmap> bitmapList; private ArrayList<String> imageStrs ; private Drawable drawable = null; private int simplesize = 1; //图片压缩的倍数 private int imageWid = 480; //图片有服务器压缩为480宽度 // private int imgdelarea = 60; //图片减去的显示区域 // private int byimgarea = 30; //old版本的 private int imgdelarea = 40; //图片减去的显示区域 private int byimgarea = 20; // private Bitmap bmp=null ; public MyImageGetter(Context context, TextView tv, MemoryCache memoryCache, Map<String, Bitmap> bitmapList, ArrayList<String> imageStrs) { this.context = context; this.tv = tv; this.memoryCache = memoryCache; this.bitmapList = bitmapList; this.imageStrs = imageStrs; imgdelarea = deletewidthpx(); } @Override public Drawable getDrawable(String source) { // 先判断回复的图片是否是本地的表情 int smilyId = Common.getSmilyStr(source); if (smilyId != 0) { // 是本地的表情 WindowManager wm = (WindowManager) context //context .getSystemService(Context.WINDOW_SERVICE); int width = wm.getDefaultDisplay().getWidth(); drawable = context.getResources().getDrawable(smilyId); // drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), // drawable.getIntrinsicHeight()); drawable.setBounds(0, 0, width / 20, width / 20); return drawable; } else { Resources res = context.getResources(); String height = ForumPostActivity.imageHeight.get(source); String width = ForumPostActivity.imageHeight.get(source+"_w"); URLDrawable drawable ; if(height!=null && !height.equals("") && !height.equals("0")) { drawable = new URLDrawable(null, height, width); // res.getDrawable(R.drawable.post_bgimg), height, width); DisplayMetrics metrics = new DisplayMetrics(); ((Activity) context).getWindowManager().getDefaultDisplay() .getMetrics(metrics); // 取drawable的原始尺寸 int wid = 0; if(width!=null && !width.equals("")) if (width.contains(".")) { int index =width.indexOf("."); width =width.substring(0, index); } wid = Integer.parseInt(width); if (height.contains(".")) { int index =height.indexOf("."); height =height.substring(0, index); } int hid = Integer.parseInt(height); int img_area = metrics.widthPixels - imgdelarea;// 图片显示区域尺寸 if (wid > img_area) {// 图片原宽度超出图片显示区域,则进行缩放,不超过则显示原始尺寸 wid = img_area;// 设置图片显示大小和图片显示区域一致 } if(wid > 300) { int imgarea_height = (img_area * hid / wid); drawable.setBounds(0, 0, img_area, imgarea_height); } else { drawable.setBounds(0, 0, wid, hid); } } else { drawable = new URLDrawable( res.getDrawable(R.drawable.post_default_img3), height, width); } //先从内存缓存中查找 Bitmap bitmap = null; if(bitmapList!=null) { //回复的图片 bitmap = bitmapList.get(source); } else if(memoryCache!=null){ bitmap = memoryCache.get(source); } Drawable drawablenew = null; if(bitmap!=null) { drawablenew = new BitmapDrawable(bitmap); drawablenew.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight()); if(drawablenew!=null) { drawable.setDrawable(drawablenew); tv.setText(tv.getText()); // 通过这里的重新设置 TextView 的文字来更新UI } } else { if (null != source && !"".equals(source)) { new ImageAsync(drawable).execute(source); } } return drawable; } } //根据手机分辨率来计算图片所占用的区域 public int deletewidthpx() { DisplayMetrics metrics = new DisplayMetrics(); ((Activity) context).getWindowManager().getDefaultDisplay() .getMetrics(metrics); int areaPx = metrics.widthPixels / 240; return areaPx * byimgarea; } //对图片的质量进行压缩 private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 35, baos);//质量压缩方法 ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中 Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片 //释放image占用的资源 if(image!=null && !image.isRecycled()) { image.recycle(); image = null; } try { baos.close(); isBm.close(); } catch (IOException e) { e.printStackTrace(); } return bitmap; } private class ImageAsync extends AsyncTask<String, Integer, Drawable> { private URLDrawable drawable; public ImageAsync(URLDrawable drawable) { this.drawable = drawable; } @Override protected Drawable doInBackground(String... params) { // TODO Auto-generated method stub String source = params[0];// 图片URL Drawable draw = fetchDrawable(source); if(draw==null) { draw = fetchDrawable(source); } return draw; } @Override protected void onPostExecute(Drawable result) { // TODO Auto-generated method stub super.onPostExecute(result); if (result != null) { drawable.setDrawable(result); tv.setText(tv.getText()); // 通过这里的重新设置 TextView 的文字来更新UI } } } //通过urlstring获取图片inputstream private InputStream fetchin(String urlString) throws MalformedURLException, IOException { DefaultHttpClient httpClient = new DefaultHttpClient(); HttpGet request = new HttpGet(urlString); HttpResponse response = httpClient.execute(request); return response.getEntity().getContent(); } // 获取URL的Drawable对象 public Drawable fetchDrawable(String urlString) { // BitmapDrawable bitmap = null; Drawable drawable = null; Bitmap bitmap = null; int width=0,height=0; try { // BitmapFactory.Options options = new BitmapFactory.Options(); // options.inJustDecodeBounds = true; // BitmapFactory.decodeStream(new URL(urlString).openStream(), null, // options); // 避免内存溢出 // // width = options.outWidth; // height = options.outHeight; // options.inJustDecodeBounds = false; // int scale = 1; // int temp = width > height ? width : height; // while (true) { // if (temp / 2 < 120) // break; // temp = temp / 2; // scale = 1; // } BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inSampleSize = simplesize; opt.inPreferredConfig = Bitmap.Config.RGB_565;// 565代表对应三原色占的位数 opt.inPurgeable = true;// 设置图片可以被回收 opt.inInputShareable = true; // InputStream in = new URL(urlString).openStream(); //mx4通过此方法获取不到图片 InputStream in = fetchin(urlString); //mx4通过http协议进行获取图片 bitmap = BitmapFactory.decodeStream(in, null, opt); // 容易内存溢出 if (in != null) { in.close(); } } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (OutOfMemoryError e) {// 若内存溢出,则不做处理 // TODO: handle exception clearBitmap(); //释放bitmap占用的资源 return null; // // 再重新获取 } finally { if (null != bitmap) { if(bitmapList==null) memoryCache.put(urlString, bitmap); else if(bitmapList!=null && !bitmapList.containsKey(urlString)) { bitmapList.put(urlString, bitmap); imageStrs.add(urlString); } drawable = new BitmapDrawable(bitmap); DisplayMetrics metrics = new DisplayMetrics(); ((Activity) context).getWindowManager().getDefaultDisplay() .getMetrics(metrics); if (width > metrics.widthPixels || height > metrics.heightPixels) // 进行等比例缩放程序 drawable.setBounds( 0, 0, metrics.widthPixels, (metrics.widthPixels * height / width)); else drawable.setBounds(0, 0, width, height); } } return drawable; } //从第一张开始清理 public void clearBitmap() { if(bitmapList!=null) { try { for(int i=0;i<10;i++) { if(imageStrs.size()>0) { String src = imageStrs.get(0); Bitmap bitmap = bitmapList.get(src); if(bitmap!=null && !bitmap.isRecycled()) { bitmap.recycle(); bitmap = null; } imageStrs.remove(0); bitmapList.remove(src); } } } catch (Exception e) { e.printStackTrace(); } } } //释放 bitmap public void clearBitmapList() { if(bitmapList!=null) { try { Iterator<Entry<String, Bitmap>> iter = bitmapList.entrySet().iterator(); int cleanCount = 0; while(iter.hasNext() && cleanCount++ <= 10) { Entry<String, Bitmap> entry = iter.next(); Bitmap bitmap = entry.getValue(); if(bitmap!=null && !bitmap.isRecycled()) { bitmap.recycle(); bitmap = null; } iter.remove(); } } catch (Exception e) { e.printStackTrace(); } } } public class URLDrawable extends BitmapDrawable { private Drawable drawable; private String height, width; public URLDrawable(Drawable defaultDraw, String height, String width) { this.height = height; this.width = width; setDrawable(defaultDraw); } private void setDrawable(Drawable nDrawable) { drawable = nDrawable; getDrawable(); } @Override public void draw(Canvas canvas) { // TODO Auto-generated method stub try { if(height!=null && !height.equals("") && !height.equals("0")) { try { bmp = BitmapFactory.decodeResource( context.getResources(), R.drawable.post_default_img3); if (Integer.parseInt(width) >= bmp.getWidth() && Integer.parseInt(height) >= bmp.getHeight()) { int draWidth = 0, draHeight = 0; DisplayMetrics metrics = new DisplayMetrics(); ((Activity) context).getWindowManager() .getDefaultDisplay().getMetrics(metrics); // 取drawable的原始尺寸 int wid = Integer.parseInt(width); // 图片原始宽度 int hid = Integer.parseInt(height); // 图片原始高度 int img_area = metrics.widthPixels - imgdelarea;// 图片显示区域尺寸 if (wid > img_area) {// 图片原宽度超出图片显示区域,则进行缩放,不超过则显示原始尺寸 wid = img_area;// 设置图片显示大小和图片显示区域一致 } if (wid > 300) { draWidth = img_area; draHeight = (img_area * hid / wid); } else { draWidth = wid; draHeight = hid; } Paint mPaint = new Paint(); mPaint.setColor(context.getResources().getColor( color.post_defaultimgbg)); Rect rtSource = new Rect(0, 0, draWidth, draHeight); canvas.drawRect(rtSource, mPaint); int startx = (draWidth - bmp.getWidth()) / 2; int starty = (draHeight - bmp.getHeight()) / 2; canvas.drawBitmap(bmp, startx, starty, null); } if (bmp != null && !bmp.isRecycled()) { bmp.recycle(); bmp = null; } } catch(OutOfMemoryError e) { } } drawable.draw(canvas); } catch(Exception e) { // e.printStackTrace(); // Resources res = context.getResources(); // Drawable dradefault = res.getDrawable(R.drawable.post_default_img3); // // DisplayMetrics metrics = new DisplayMetrics(); // ((Activity) context).getWindowManager().getDefaultDisplay() // .getMetrics(metrics); // int wid, hid, img_area; // // 取drawable的原始尺寸 // wid = (int) (dradefault.getIntrinsicWidth() * metrics.density);// 图片原始宽度 // hid = (int) (dradefault.getIntrinsicHeight() * metrics.density);// 图片原始高度 // // 进行等比例缩放程序 // dradefault.setBounds(0, 0, wid, hid); // dradefault.draw(canvas); } } private void getDrawable() { if (null != drawable) { DisplayMetrics metrics = new DisplayMetrics(); ((Activity) context).getWindowManager().getDefaultDisplay() .getMetrics(metrics); int wid, hid, img_area; // 取drawable的原始尺寸 wid = (int) (drawable.getIntrinsicWidth() * metrics.density);// 图片原始宽度 hid = (int) (drawable.getIntrinsicHeight() * metrics.density);// 图片原始高度 img_area = metrics.widthPixels - imgdelarea;// 图片显示区域尺寸 if (wid > img_area) {// 图片原宽度超出图片显示区域,则进行缩放,不超过则显示原始尺寸 wid = img_area;// 设置图片显示大小和图片显示区域一致 } // 进行等比例缩放程序 // drawable.setBounds(0, 0, wid, hid); // setBounds(0, 0, wid, hid); if(wid*simplesize > 300) { int imgarea_height = (img_area * hid / wid); drawable.setBounds(0, 0, img_area, imgarea_height); setBounds(0, 0, img_area, imgarea_height); } else { int bynum = 1; if(metrics.widthPixels > imageWid) bynum = simplesize; drawable.setBounds(0, 0, wid*bynum, hid*bynum); setBounds(0, 0, wid*bynum, hid*bynum); } } } } }
相关推荐
5. **图文混排**:在TextView中,不仅要处理文字,还要插入图片,这需要对布局和样式有深入理解。可以使用`<img>`标签插入图片,利用CSS控制其大小和位置,以实现与文字的混排。 6. **公式不自动换行问题**:公式的...
在Android开发中,`TextView`通常用于显示纯文本内容,但有时我们可能需要在文本中嵌入图片,这时就可以利用`TextView`加载HTML格式的文本,实现图文混排。本篇将详细介绍如何在`TextView`中加载包含图片的HTML内容...
简单的图文混排可以通过将这两个控件组合在一个布局中实现,例如LinearLayout或RelativeLayout。然而,这种方式往往难以满足复杂的需求,如文字环绕图片等。 2. **自定义ViewGroup**:为了实现更复杂的图文混排,...
6. **富文本布局**:在图文混排中,需要注意文本和图像的布局。这可能涉及到计算图像和文本的尺寸,以及根据需要调整它们的对齐方式。 7. **KVC(Key-Value Coding)**:在某些情况下,可能需要通过KVC来动态设置`...
在本项目中,通过YYText,我们可以创建自定义的TextView或Label,实现文字和图片的混合布局。具体步骤如下: 1. 引入YYText库:首先,我们需要在项目中引入YYText库,可以通过CocoaPods或Carthage等依赖管理工具...
在Android中,我们可以使用`TextView`和`ImageView`结合布局管理器(如`LinearLayout`、`RelativeLayout`或`ConstraintLayout`)来实现。另外,`WebView`也是一个强大的工具,可以处理复杂的图文混排,支持HTML、CSS...
这里,`asGif()`指定了加载类型,`load()`加载资源,最后`into()`将GIF注入到`TextView`。 2. **自定义控件** 对于更复杂的需求,比如图文混排,我们可能需要创建自定义的`TextView`。这通常涉及重写`TextView`的...
这个“ios-textKit实现图文混排最简单的实现.zip”压缩包显然是一个示例项目,用于演示如何利用TextKit来实现图文混排的功能。接下来,我们将深入探讨TextKit以及如何在TextView中实现图文混排。 1. **TextKit框架...
在Android开发中,图文加载是一项基础且重要的任务,它涉及到用户界面(UI)的设计和用户体验(UX)。在Android应用中,我们经常需要显示各种类型的图片和文字信息,比如新闻、博客、产品详情等。"安卓图文加载"这个...
本示例项目"Android-TextViewDemo图文混排"着重展示了如何利用`TextView`进行丰富的文本格式化和交互设计。下面将详细讲解这些知识点。 1. **关键字高亮**: 在应用中,有时需要突出显示特定的关键词,例如搜索...
可以使用`ImageView`和`TextView`来展示图片和文本,并使用`LinearLayout`或`RelativeLayout`进行布局管理。 在Activity中,实例化Adapter并将其设置给ListView,同时为SwipeRefreshLayout设置刷新监听器,以便在...
本示例“Android加载HTML图文并排”提供了一种解决方案,它允许开发者将HTML内容与图片并列显示在TextView中,为用户提供更加丰富的视觉体验。下面我们将详细讲解如何实现这一功能。 首先,我们需要理解Android中的...
在Android开发中,TextView是用于显示文本的基本组件,但其实它并不局限于纯文本,还能通过一些方式来显示图片。这个Demo就是关于如何在TextView中嵌入并显示图片的一个实例。以下我们将详细探讨如何利用TextView的...
例如,你可能有一个简单的文本布局(layout_item_text.xml)和一个包含图片和文本的复杂布局(layout_item_image_text.xml)。 2. **自定义Adapter**:继承自BaseAdapter或者ArrayAdapter,并重写其中的关键方法。...
在Android中,我们可以使用`EditText`、`WebView`、`TextView`、`ImageView`等原生控件,通过自定义布局和逻辑来实现这一功能。 1. **使用EditText实现基本文本编辑**: `EditText`是Android中的基础文本输入控件...
2. **数据结构**:为了支持图文混排,数据源通常不再是简单的字符串数组,而是一个包含图片URL或本地路径和对应文本的对象列表。例如,可以创建一个`SpinnerItem`类,包含一个`String`类型的标题字段和一个`Drawable...
布局文件可以包含ImageView和TextView,分别用来显示图片和文字。通过设置适配器的数据源(如ArrayList),并将适配器绑定到ListView,即可实现图文并茂的效果。 2. **上拉加载(Load More)**: 上拉加载功能允许...
"安卓自定义图文混排"是指开发者根据具体需求,自定义控件来实现这一功能,以达到更加灵活、个性化的布局效果。在本项目中,"QuoteTextView-master"可能是一个开源库或者示例代码,用于帮助开发者实现这种混排。 ...
图文混排是指在一个布局中同时显示图像和文本,并使它们相互协调,形成美观且易读的展示效果。在Android中,这通常涉及到TextView和ImageView的组合使用,或者使用自定义View来实现更复杂的布局。 1. **使用...
这可以是流式布局(类似TextView的换行),网格布局,或者是自定义的复杂布局。在Android中,可以通过测量(`measure()`)和布置(`layout()`)过程来实现。 4. 触摸事件处理:在`onTouchEvent()`中,根据触摸点...