package com.jmheart.view.textview;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.ImageSpan;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
import com.jmheart.R;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;
/**
*
* ���ı���ʾTextView
*/
public class RichText extends TextView {
private Drawable placeHolder, errorImage;//ռλͼ������ͼ
private OnImageClickListener onImageClickListener;//ͼƬ����ص�
public RichText(Context context) {
this(context, null);
}
public RichText(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RichText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RichText);
placeHolder = typedArray.getDrawable(R.styleable.RichText_placeHolder);
errorImage = typedArray.getDrawable(R.styleable.RichText_errorImage);
if (placeHolder == null) {
placeHolder = new ColorDrawable(Color.GRAY);
}
if (errorImage == null) {
errorImage = new ColorDrawable(Color.GRAY);
}
typedArray.recycle();
}
/**
* ���ø��ı�
*
* @param text ���ı�
*/
public void setRichText(String text) {
Spanned spanned = Html.fromHtml(text, asyncImageGetter, null);
SpannableStringBuilder spannableStringBuilder;
if (spanned instanceof SpannableStringBuilder) {
spannableStringBuilder = (SpannableStringBuilder) spanned;
} else {
spannableStringBuilder = new SpannableStringBuilder(spanned);
}
ImageSpan[] imageSpans = spannableStringBuilder.getSpans(0, spannableStringBuilder.length(), ImageSpan.class);
final List<String> imageUrls = new ArrayList<String>();
for (int i = 0, size = imageSpans.length; i < size; i++) {
ImageSpan imageSpan = imageSpans[i];
String imageUrl = imageSpan.getSource();
int start = spannableStringBuilder.getSpanStart(imageSpan);
int end = spannableStringBuilder.getSpanEnd(imageSpan);
imageUrls.add(imageUrl);
final int finalI = i;
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View widget) {
if (onImageClickListener != null) {
onImageClickListener.imageClicked(imageUrls, finalI);
}
}
};
ClickableSpan[] clickableSpans = spannableStringBuilder.getSpans(start, end, ClickableSpan.class);
if (clickableSpans != null && clickableSpans.length != 0) {
for (ClickableSpan cs : clickableSpans) {
spannableStringBuilder.removeSpan(cs);
}
}
spannableStringBuilder.setSpan(clickableSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
super.setText(spanned);
setMovementMethod(LinkMovementMethod.getInstance());
}
/**
* �첽����ͼƬ��������Picasso��
*/
private Html.ImageGetter asyncImageGetter = new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
final URLDrawable urlDrawable = new URLDrawable();
Picasso.with(getContext()).load(source).placeholder(placeHolder).error(errorImage).into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Drawable drawable = new BitmapDrawable(getContext().getResources(), bitmap);
drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
urlDrawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
urlDrawable.setDrawable(drawable);
RichText.this.setText(getText());
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
urlDrawable.setBounds(errorDrawable.getBounds());
urlDrawable.setDrawable(errorDrawable);
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
urlDrawable.setBounds(placeHolderDrawable.getBounds());
urlDrawable.setDrawable(placeHolderDrawable);
}
});
return urlDrawable;
}
};
public static class URLDrawable extends BitmapDrawable {
private Drawable drawable;
@SuppressWarnings("deprecation")
public URLDrawable() {
drawable = new ColorDrawable(Color.GRAY);
}
@Override
public void draw(Canvas canvas) {
if (drawable != null)
drawable.draw(canvas);
}
public void setDrawable(Drawable drawable) {
this.drawable = drawable;
}
}
public void setPlaceHolder(Drawable placeHolder) {
this.placeHolder = placeHolder;
}
public void setErrorImage(Drawable errorImage) {
this.errorImage = errorImage;
}
public void setOnImageClickListener(OnImageClickListener onImageClickListener) {
this.onImageClickListener = onImageClickListener;
}
public interface OnImageClickListener {
/**
* ͼƬ�������Ļص�����
*
* @param imageUrls ��ƪ���ı��������ȫ��ͼƬ
* @param position �����ͼƬ��imageUrls�е�λ��
*/
void imageClicked(List<String> imageUrls, int position);
}
}