android如果重寫onDraw實現一個類似TextView可以顯示表情和連結的控制項(一)

來源:互聯網
上載者:User

android如果重寫onDraw實現一個類似TextView可以顯示表情和連結的控制項(一)

先看:


寫一個超串連支援的對象:

/**作為超串連顯示的對象*/public class LinkInfo implements Comparable{    private String content;    private String type;    private String id;    private boolean bIsFace = false;    private boolean bSelected = false;    public static final String EMAIL = "Email";    public static final String WEBURL = "WebUrl";    public static final String PHONENUMBER = "PhoneNumber";    private int startIndex;    private int endIndex;}

對於以下的字串做這樣的解析:

String s = "(#大笑)%$%$%3434343434343$%$%youjiancau@163.com$dfsfsfsdffds^15959224872)dfsfdsafsaf@153.cn&&fefrewafrewfjwio(fsfsfsd@tre.com.cn()()()www.baidu.com3242343243www.sohu.com@afjiofjfjaof";

private static Pattern EMAIL_PATTERN = Patterns.EMAIL_ADDRESS;private static Pattern PHONE_PATTERN = Patterns.PHONE;private static Pattern WEBURL_PATTERN = Patterns.WEB_URL;public static ArrayList parseStr(String strLink) {if(TextUtils.isEmpty(strLink)){    return null;    }ArrayList resultList = new ArrayList();    ArrayList infoList = null;    try{    infoList = new ArrayList();    Matcher matcher = EMAIL_PATTERN.matcher(strLink); //尋找字串裡的email的位置    int begin = 0;    while(matcher.find()) {    int start = matcher.start();    int end = matcher.end();        LinkInfo info = new LinkInfo();        info.setStartIndex(start);        info.setEndIndex(end);            info.setContent(matcher.group());            info.setType(LinkInfo.EMAIL);        infoList.add(info);    }        Matcher matcher1 = PHONE_PATTERN.matcher(strLink);//尋找字串裡的號碼的位置    while(matcher1.find()) {    int start = matcher1.start();    int end = matcher1.end();        LinkInfo info = new LinkInfo();        info.setStartIndex(start);        info.setEndIndex(end);            info.setContent(matcher1.group());            info.setType(LinkInfo.PHONENUMBER);        infoList.add(info);    }        //(#大笑)    Pattern pattern = Pattern.compile("(\\(#\\S{1,2}\\))");        Matcher matcher2 = pattern.matcher(strLink);     while(matcher2.find()) {    int start = matcher2.start();    int end = matcher2.end();    System.out.println("====start="+start+"end="+end+"match group="+matcher2.group());        LinkInfo info = new LinkInfo();        info.setStartIndex(start);        info.setEndIndex(end);            info.setContent(matcher2.group());            info.setFace(true);        infoList.add(info);    }        Collections.sort(infoList);    int last = 0;    for(int i=0;i
activity的Layout:

                        


IntroView有這樣一個方法來載入字串:
public class IntroView extends TextView {private ArrayList titleList;private int displayWidth = 0;private float displayHeight = 0;private float curLen = 0;private Bitmap starBmp;private Bitmap selectedBmp;private float posX = 0;private float posY = 0;private LinkInfo curInfo;//當前點擊的Link對象private OnClickLinkListener Listener;private String mFaceType = MSG_FACE_TYPE;public static final String MSG_FACE_TYPE = "msgtype";public static final String STATUS_FACE_TYPE = "statustype";public IntroView(Context context) {super(context);}public IntroView(Context context, AttributeSet attrs) {super(context, attrs);}public IntroView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public void setTitleList(ArrayList titleList){this.titleList = titleList;displayHeight = 0;        requestLayout();}}                                    
activity裡這樣來調用:
IntroView news_item_text = (IntroView)findViewById(R.id.news_item_text);
//不支援字串裡有\n
String s = "(#大笑)%$%$%3434343434343$%$%youjiancau@163.com$dfsfsfsdffds^15959224872)dfsfdsafsaf@153.cn&&fefrewafrewfjwio(fsfsfsd@tre.com.cn()()()www.baidu.com3242343243www.sohu.com@afjiofjfjaof";
news_item_text.setTitleList(ParseNewsInfoUtil.parseStr(s));
news_item_text.setOnClickLinkListener(this);
IntroView的主題思想是在onMeasure裡的measureWidth和measureHeight時來擷取ArrayList titleList每個LinkInfo的位置資訊,並擷取這個IntroView的高度和寬度,
然後onDraw的時候通過迴圈來繪製titleList的每個LinkInfo
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){super.onMeasure(widthMeasureSpec, heightMeasureSpec);try{int width = measureWidth(widthMeasureSpec);int height = measureHeight(heightMeasureSpec);setMeasuredDimension(width, height);}catch(Exception ex){ex.printStackTrace();}}
 
 private int measureWidth(int measureSpec) {        int result = 0;                int specMode = MeasureSpec.getMode(measureSpec);        int specSize = MeasureSpec.getSize(measureSpec);        int initialWidth = getPaddingLeft() + getPaddingRight();        int width = initialWidth;        int maxWidth = 0;                TextPaint tempPaint = null;        if (specMode == MeasureSpec.EXACTLY) {            result = specSize;        } else {            if (tempPaint == null) {                tempPaint = new TextPaint();                tempPaint.setStyle(Style.FILL);                tempPaint.setAntiAlias(true);                tempPaint.setTextSize(getTextSize());            }                        if (titleList != null && titleList.size() > 0) {                maxWidth = specSize;                                int size = titleList.size();forLable:                                for (int i = 0; i < size; i++) {                    LinkInfo info = titleList.get(i);                                        if (info.isFace()) {                    Bitmap faceBmp = null;        if(mFaceType == MSG_FACE_TYPE) {        faceBmp = MessageFaceModel.getInstance().getFaceIcon(info.getContent());        }                        if (faceBmp != null) {                            int wSize = faceBmp.getWidth() + 4;                            if (width + wSize >= maxWidth) { //這裡表示已經計算的寬度大於控制項的寬度,那就返回maxWidth就可以了                                width = maxWidth;                                break forLable;                            }                            width += wSize;                        }                        continue;                    }                                        String text = info.getContent();                    text = text.replaceAll("\n", " "); //因為該控制項不支援\n,所以把這個換成空格                    if (!TextUtils.isEmpty(text)) {                        float wSize = tempPaint.measureText(text);                        if (width + wSize >= maxWidth) {                            width = maxWidth;                            break forLable;                        }                        width += wSize;                    }                                    }            }                        result = width;        }        displayWidth = result;        return result;    }

                                                                                

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.