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

來源:互聯網
上載者:User

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

下面來寫IntroView的onMeasureHeight:

private int measureHeight(int measureSpec) {        int result = 0;        int specMode = MeasureSpec.getMode(measureSpec);        int specSize = MeasureSpec.getSize(measureSpec);        Paint paint = new Paint();        paint.setTextSize(getTextSize());        paint.setAntiAlias(true);        paint.setStyle(Style.FILL);        displayHeight = -paint.ascent() + paint.descent() + 2;//-paint.ascent() 為字型高於baseLine的部分  paint.descent() 為低於baseline的部分        measureList(paint, titleList, 0);                if (specMode == MeasureSpec.EXACTLY) {            result = specSize;        } else {            if (specMode == MeasureSpec.AT_MOST) {                result = Math.min((int)displayHeight, specSize);            }            else{            result = (int)displayHeight;            }        }        return result;    }private float measureList(Paint paint, ArrayList infoList, float StartX){if(infoList == null || infoList.size() == 0){    displayHeight = StartX;return StartX;}float x = StartX;int len = infoList.size();//FontMetrics fontMetrics = paint.getFontMetrics();float fontHeight = -paint.ascent() + paint.descent();//fontMetrics.bottom - fontMetrics.top;for(int i = 0; i < len; i++){LinkInfo info = infoList.get(i);//這裡開始計算每個連結的點擊地區info.getRectFList().clear();if(info.isFace()){//Emoji排版Bitmap faceBmp = null;if(mFaceType == MSG_FACE_TYPE) {faceBmp = MessageFaceModel.getInstance().getFaceIcon(info.getContent());}if(faceBmp != null){int xLen = faceBmp.getWidth() + 4;//表情表徵圖左右各空兩個像素    if(x + xLen >= displayWidth){    displayHeight += fontHeight;x = 0;    }    x += xLen;}    continue;}String strContent = info.getContent();strContent = strContent.replaceAll("\n", " ");float xLen = paint.measureText(strContent);//這裡處理換行的情況if(x + xLen >= displayWidth){float startX = x;int lenStr = strContent.length();for(int j = 0; j < lenStr; j++){float width = paint.measureText(strContent, j, j + 1);if(x + width >= displayWidth){RectF rectF = new RectF();rectF.set(startX, displayHeight - fontHeight, x, displayHeight);info.addRectF(rectF);displayHeight += fontHeight;x = width;//下一行的X方向起始位移量,width是一個字元的位移量,所以這裡rectF只在換行的時候執行一次startX = 0;}else{x += width;}}RectF rectF = new RectF();//如果換行則startX為0,x為第下一行的寬度rectF.set(startX, displayHeight - fontHeight, x - startX, displayHeight);info.addRectF(rectF);}else{RectF rectF = new RectF();rectF.set(x, displayHeight - fontHeight, x + xLen, displayHeight);info.addRectF(rectF);x += xLen;}}return x;}

onDraw:

@Overrideprotected void onDraw(Canvas canvas){super.onDraw(canvas);try{if(titleList == null || titleList.size() == 0){return;}curLen = 0;Paint paint = new Paint();paint.setTextSize(getTextSize());paint.setAntiAlias(true);paint.setStyle(Style.FILL);float y = -paint.ascent();//(fontMetrics.bottom - fontMetrics.ascent);y = drawList(canvas, paint, titleList, y);}catch(Exception ex){}}private float drawList(Canvas canvas, Paint paint, ArrayList infoList, float StartY){if(infoList == null || infoList.size() == 0){return StartY;}float y = StartY;float fontHeight = -paint.ascent() + paint.descent();//fontMetrics.bottom - fontMetrics.ascent;int len = infoList.size();int color = getCurrentTextColor();for(int i = 0; i < len; i++){LinkInfo info = infoList.get(i);if(info.isFace()){//Emoji排版Bitmap faceBmp = null;if(mFaceType == MSG_FACE_TYPE) {faceBmp = MessageFaceModel.getInstance().getFaceIcon(info.getContent());}    if(faceBmp != null){int xLen = faceBmp.getWidth() + 4;//表情表徵圖左右各空兩個像素    if(curLen + xLen >= displayWidth){    y += fontHeight;    curLen = 0;    }    canvas.drawBitmap(faceBmp, curLen + 2, y - fontHeight + 4, paint);    curLen += xLen;    }    continue;}String strContent = info.getContent();if(mFaceType == MSG_FACE_TYPE && strContent.startsWith("\n")){y += fontHeight;curLen = 0;}strContent = strContent.replaceAll("\n", " ");if((info.isEmail() || info.isPhoneNumber() || info.isWebUrl()) && info.isSelected()){paintSelectRectF(canvas, paint, info);}float xLen = paint.measureText(strContent);int starLen = 0;if(info.isCommonString()){    paint.setColor(color);}else{paint.setColor(getResources().getColor(R.drawable.blue1));}if(curLen + xLen + starLen >= displayWidth){int lenStr = strContent.length();for(int j = 0; j < lenStr; j++){float width = paint.measureText(strContent, j, j + 1);if(curLen + width >= displayWidth){y += fontHeight;curLen = 0;}canvas.drawText(strContent, j, j + 1, curLen, y, paint);curLen += width;}}else{canvas.drawText(strContent, curLen, y, paint);curLen += xLen;}}return y;}

onTouch事件,可以點擊Text裡面的連結(email,phone)

@Overridepublic boolean onTouchEvent(MotionEvent event){super.onTouchEvent(event);if(!this.isEnabled() || Listener == null){return false;}if(event.getAction() == MotionEvent.ACTION_UP){float x = event.getX();float y = event.getY();boolean flag = cancelCurInfo(x, y);if(flag){return false;//up時的座標已經不在down時記錄的Link對象中,則直接返回}if(clickLink(titleList, x, y, MotionEvent.ACTION_UP)){//Log.i("curInfo", "ACTION_UP");return true;}}else if(event.getAction() == MotionEvent.ACTION_DOWN){float x = event.getX();float y = event.getY();boolean flag = clickLink(titleList, x, y, MotionEvent.ACTION_DOWN);if(flag){//Log.i("curInfo", "ACTION_DOWN");return true;}}else{float x = event.getX();float y = event.getY();cancelCurInfo(x, y);}return false; }private void paintSelectRectF(Canvas canvas, Paint paint, LinkInfo info){ArrayList rectList = info.getRectFList();int len = rectList.size();for(int i = 0; i < len; i++){RectF rectF = rectList.get(i);paint.setColor(this.getContext().getResources().getColor(R.drawable.gray3));canvas.drawRect(rectF.left, rectF.top - 2, rectF.right, rectF.bottom - 2, paint);}}/** x,y所代表的點已經不在當前Link對象中,則清除掉當前Link對象的選中效果 */private boolean cancelCurInfo(float x, float y){if(curInfo == null){return true;}if(!curInfo.contains(x, y)){curInfo.setSelected(false);this.invalidate();curInfo = null;return true;}return false;}private boolean clickLink(ArrayList infoList, float x, float y, int action){if(infoList == null){return false;}int len = infoList.size();for(int i = 0; i < len; i++){LinkInfo info = infoList.get(i);if(info.isCommonString()){continue;}if(info.contains(x, y)){if(action == MotionEvent.ACTION_DOWN){info.setSelected(true);this.invalidate();this.curInfo = info;}else if(action == MotionEvent.ACTION_UP){this.curInfo = null;info.setSelected(false);this.invalidate();Listener.onClick(info);}return true;}}return false;}

Listener:

private OnClickLinkListener Listener;public void setOnClickLinkListener(OnClickLinkListener listener){this.Listener = listener;}public interface OnClickLinkListener{/**點擊了動態中的某個連結化物件*/public abstract void onClick(LinkInfo linkInfo);}


代碼:http://download.csdn.net/detail/baidu_nod/7736733

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.