Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android如果重寫onDraw實現一個類似TextView可以顯示表情和鏈接的控件(一)

android如果重寫onDraw實現一個類似TextView可以顯示表情和鏈接的控件(一)

編輯:關於Android編程

先看效果圖:

\

寫一個超連接支持的對象:

/**作為超連接顯示的對象*/
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$%$%[email protected]$dfsfsfsdffds^15959224872)[email protected]&&fefrewafrewfjwio([email protected]()()()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$%$%[email protected]$dfsfsfsdffds^15959224872)[email protected]&&fefrewafrewfjwio([email protected]()()()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
	@Override
	protected 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;
    }


                                                                                

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved