編輯:關於Android編程
下面來寫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()){//表情符排版
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;
} @Override
protected 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()){//表情符排版
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;
} @Override
public 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;
} 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
Android實戰技巧之四十五:復用原有C代碼的方案
任務描述有一套C寫的代號為“Shooter”的核心算法庫可以解決我們面臨的一些問題,只是這個庫一直用在其他平台。我們現在的任務是將其復用到Andr
Android AlertDialog對話框自定義風格的另類實現
一、引子 學過Android的同學都知道,對話框的重要程度非常高,任何一款 app幾乎都離不開對話框,值得慶幸的是,對話框的運用在Android中還是相對比較容易的。雖然
高通Quick Charge 2.0快充技術從入門到精通
高通Quick Charge 2.0快充技術(下稱QC2.0),近日成為了我們關注的焦點,同時也是整個行業熱議的話題。在此之前快充只能通過提升電流的方式來達
微信被人舉報後怎麼解除 微信被舉報解除方法
如果你的微信被舉報了,怎麼辦呢?是慢慢等著自動解封,還是自己動手呢?下面就來看看手機微信被人舉報後怎麼解除吧!舉報現象:1、一種是你真的發布了違背法律法規、