日期:2014-05-20 浏览次数:20753 次
这阵子忙项目,写了个控件,有点像文本域,显示文章用的,带滚动条,有拖拽事件,不过还是有个小问题不咋完美。
?
我承认我的代码不适合阅读,因为注释比较少,并且这个控件的开发难度有点大,主要是拖拽的地方有点复杂,最重要的是,代码还经过一定的优化,合并了许多变量,不过有兴趣的人也可以挑战一下~?
?
设计思路很简单,滚动条的走动依附文本的走动,根据倍数算出各个变量。
?
具体的实现我自己都不愿意回忆了。
?
该代码发布之意在于供人使用,不侧重于供人学习阅读。
?
package com.ctai.items.textarea; import java.util.Vector; import javax.microedition.lcdui.Font; import javax.microedition.lcdui.Graphics; import com.ctai.utils.ColorSet; import com.ctai.utils.DefaultProperties; public class Textarea { /** 文字颜色 */ private int i_c_strColor; /** x, y, 宽, 高*/ public int x, y, width, hight; /** 文字整体高度 */ private int i_allStrHight; /** 整体高度 */ private int i_strHight; private Vector v; /** 倍数 */ private int Multiple; /** 滚动条高度 */ private int scrollHight; /** 滚动条的X和Y坐标 */ private int scrollX, scrollY; /** ↑↓按钮方块固定Y */ private int boxY; /** ↑↓按钮方块的宽高 */ private int boxWH = 16; /** 方向键滚屏像素值 */ private int rollValue; /** 方向键滚屏侧滑块移动的偏差像素值 */ private int rollMoveScrollValue; /** 临时变量 */ private int temp, temp2, temp3, temp4, temp5, temp6, temp7, temp8; /** 文字是否超过一篇 */ private boolean b_isHaveMore = true; private int i_dragged[] = new int[2]; /** * 文本域 * @param st_strOut 文本域内文字 * @param font 当前g的字体 * @param i_c_strColor 文字颜色 * @param x * @param y * @param width 宽 * @param hight 高 * @param rollValue 方向键滚屏像素值 * */ public Textarea(String st_strOut, Font font, int i_c_strColor, int x, int y, int width, int hight, int rollValue) { this.i_c_strColor = i_c_strColor; this.x = x; this.scrollX = x + width; // 滑块X的坐标初始化 this.y = y; this.temp7 = y; this.boxY = y; this.scrollY = y + boxWH; // 滑块Y的坐标初始化 this.width = width; this.hight = hight; this.rollValue = rollValue; v = getSubsection(st_strOut, font, width, "\r\n"); // 赋值vector init(); temp8 = 320 - (boxY + boxWH * 2 + scrollHight + 30); } public void init() { Multiple = (temp6 + ((260 / i_strHight) - 1)) / (260 / i_strHight); //倍数 if (Multiple == 1) { b_isHaveMore = false; } else { scrollHight = (hight - boxWH * 2) * 260 / (temp6 * i_strHight); } temp = hight - boxWH; temp2 = (boxWH >> 2); temp3 = scrollX + (boxWH >> 1); temp4 = temp2 * 3; temp5 = boxWH * 2; } public void paint(Graphics g) { g.setColor(i_c_strColor); if (v != null && v.size() > 0) { for (int i = 0; i < v.size(); i++) { g.drawString(v.elementAt(i).toString(), x, i * i_strHight + y, 0); } } // 画整个滚动条 g.setColor(ColorSet.scrollBackColor); g.fillRect(scrollX - 1, boxY - 1, boxWH + 2, hight + 2); // 画上、下小箭头块边框 g.setColor(ColorSet.scrollBorderColor); g.fillRect(scrollX - 1, boxY - 1, boxWH + 2, boxWH + 2); g.fillRect(scrollX - 1, boxY + temp - 1, boxWH + 2, boxWH + 2); // 画上、下箭头小块 g.setColor(ColorSet.scrollFontColor); g.fillRect(scrollX, boxY, boxWH, boxWH); g.fillRect(scrollX, boxY + temp, boxWH, boxWH); // 画箭头 g.setColor(ColorSet.scrollIcoColor); // 画∧ // 画/ g.drawLine(temp3, boxY + temp2, scrollX + temp2, boxY + temp4); // 画\ g.drawLine(temp3, boxY + temp2, scrollX + temp4, boxY + temp4); // 画∨ // 画\ g.drawLine(temp3, boxY + temp + temp4, scrollX + temp2, boxY + temp + temp2); // 画/ g.drawLine(temp3, boxY + temp + temp4, scrollX + temp4, boxY + temp + temp2); g.setColor(ColorSet.scrollBorderColor); g.fillRect(scrollX, scrollY + rollMoveScrollValue, boxWH, scrollHight); g.setColor(ColorSet.scrollFontColor); g.fillRect(scrollX + 1, scrollY + rollMoveScrollValue + 1, boxWH - 2, scrollHight - 2); } public void pointerDragged(int x, int y) { if(b_isHaveMore) { i_dragged[1] = i_dragged[0]; i_dragged[0] = y; if(x < scrollX && y > boxY && y < 290) { this.y -= i_dragged[0] - i_dragged[1]; if (this.y - this.temp7 <= i_allStrHight) { this.y = i_allStrHight + this.temp7; } else if (this.y >= boxY) { this.y = boxY; } rollMoveScrollValue = getXY(temp8, this.y - this.temp7, i_allStrHight); if (rollMoveScrollValue < 0) { rollMoveScrollValue = 0; } } if(x > scrollX && x < 239 && y > scrollY + rollMoveScrollValue && y < scrollY + rollMoveScrollValue + scrollHight) { this.y += (i_dragged[0] - i_dragged[1]) * (i_allStrHight / (hight - (boxWH * 2) - scrollHight)); if (this.y - this.temp7 <= i_allStrHight) { this.y = i_allStrHight + this.temp7; } else if (this.y >= boxY) { this.y = boxY; } rollMoveScrollValue = getXY(temp8, this.y - this.temp7, i_allStrHight); if (rollMoveScrollValue < 0) { rollMoveScrollValue = 0; } } } } public void keyPressed(int keyCode) { if (b_isHaveMore) { if (keyCode == DefaultProperties.KEY_DOWN) { this.y -= rollValue; if (this.y - this.temp7 <= i_allStrHight) { this.y = i_allStrHight + this.temp7 + 2; } } if (keyCode == DefaultProperties.KEY_UP) { this.y += rollValue; if (this.y >= boxY) { this.y = boxY; } } rollMoveScrollValue = getXY(temp8, this.y - this.temp7, i_allStrHight); if (rollMoveScrollValue < 0) { rollMoveScrollValue = 0; } } } public void pointerPressed(int x, int y) { if (b_isHaveMore) { i_dragged[1] = y; i_dragged[0] = y; if (x > scrollX && x < scrollX + boxWH && y > scrollY && y < scrollY + hight - temp5) // 在滑块内点击时间的捕捉 { if (y < scrollY + rollMoveScrollValue) { this.y += hight; if (this.y >= boxY) { this.y = boxY; } } else if (y > scrollY + rollMoveScrollValue + scrollHight) { this.y -= hight; if (this.y - this.temp7 <= i_allStrHight) { this.y = i_allStrHight + this.temp7 + 2; } } rollMoveScrollValue = getXY(temp8, this.y - this.temp7, i_allStrHight); if (rollMoveScrollValue < 0) { rollMoveScrollValue = 0; } } else if (x > scrollX && x < scrollX + boxWH && y > boxY && y < boxY + boxWH) { this.y += rollValue; if (this.y >= boxY) { this.y = boxY; } rollMoveScrollValue = getXY(temp8, this.y - this.temp7, i_allStrHight); if (rollMoveScrollValue < 0) { rollMoveScrollValue = 0; } } else if (x > scrollX && x < scrollX + boxWH && y > boxY + temp && y < boxY + hight) { this.y -= rollValue; if (this.y - this.temp7 <= i_allStrHight) { this.y = i_allStrHight + this.temp7 + 2; } rollMoveScrollValue = getXY(temp8, this.y - this.temp7, i_allStrHight); } } } private final int getXY(int w, int x, int Exp) { return (int) (((long) (x * w) * 1000000) / ((long) Exp * 1000000)); } /** 此方法会根据文字内容自动返回长度适应给定width的vector */ public Vector getSubsection(String strSource, Font font, int width, String strSplit) { Vector vector = new Vector(); String temp = strSource; int i, j; int LastLength = 1; int step = 0; try { while (!temp.equals("")) { i = temp.indexOf("\n"); if (i > 0) { if (font.stringWidth(temp.substring(0, i - 1)) >= width) { i = -1; } } if (i == -1) { if (LastLength > temp.length()) { i = temp.length(); } else { i = LastLength; step = font.stringWidth(temp.substring(0, i)) > width ? -1 : 1; if (i < temp.length()) { while (!(font.stringWidth(temp.substring(0, i)) <= width && font.stringWidth(temp.substring(0, i + 1)) > width)) { i = i + step; if (i == temp.length()) { break; } } } } if (!strSplit.equals("")) { j = i; if (i < temp.length()) { while (strSplit.indexOf(temp.substring(i - 1, i)) == -1) { i--; if (i == 0) { i = j; break; } } } } } LastLength = i; vector.addElement(temp.substring(0, i)); if (i == temp.length()) { temp = ""; } else { temp = temp.substring(i); if (temp.substring(0, 1).equals("\n")) { temp = temp.substring(1); } } } } catch (Exception e) { System.out.println("getSubsection:" + e); } temp6 = vector.size(); i_strHight = font.getHeight(); i_allStrHight = 320 - boxY - 30 - vector.size() * i_strHight; return vector; } }
?
?
有些颜色的静态变量是另一个颜色管理类的,使用时替换成你想要的颜色即可。
?
此控件支持的触屏事件:文字域的拖拽,滚动条的拖拽,上下按钮的点击,滚动条底色区域的翻屏事件
此控件支持的按键事件:手机键盘上下按钮文字像素滚动。
?
?
?
附件有这个类的源码。