当我键入超过TextField的宽度的文本时,它向左滚动
使用了HorizonalFieldManager
但现在的问题是如果我用鼠标右键单击并滚动它
它的长度不足
但是不要停止我打字的最后一个字
这里有什么问题?
这是一个bug吗
我只需要它来达到最后一个字时禁用HorizontalScrolling
它应该能够在最后一个单词的开始和结束之间滚动
查看代码
- import net.rim.device.api.ui.Color;
- import net.rim.device.api.ui.Field;
- import net.rim.device.api.ui.FocusChangeListener;
- import net.rim.device.api.ui.Graphics;
- import net.rim.device.api.ui.Manager;
- import net.rim.device.api.ui.XYEdges;
- import net.rim.device.api.ui.XYRect;
- import net.rim.device.api.ui.component.BasicEditField;
- import net.rim.device.api.ui.container.HorizontalFieldManager;
- import net.rim.device.api.ui.container.VerticalFieldManager;
- import net.rim.device.api.ui.decor.Border;
- import net.rim.device.api.ui.decor.BorderFactory;
- public class CustomTextField extends VerticalFieldManager {
- private int textWidth=0;
- private int textHeight=0;
- private BasicEditField basicEditField;
- private HorizontalFieldManager hfm;
- //Border border;
- public CustomTextField(int width,int height) {
- super();
- textWidth=width;
- textHeight=height;
- //border=BorderFactory.createSimpleBorder(new XYEdges(1,1,1));
- hfm=new HorizontalFieldManager(Manager.HORIZONTAL_SCROLL){
- protected void sublayout(int maxWidth,int maxHeight) {
- super.sublayout(maxWidth,maxHeight);
- setExtent(textWidth,textHeight);
- }
- };
- basicEditField=new BasicEditField("","",200,BasicEditField.NO_NEWLINE);
- //basicEditField.setBorder(border);
- hfm.add(basicEditField);
- add(hfm);
- }
- protected void sublayout(int maxWidth,int maxHeight) {
- super.sublayout(textWidth,textHeight);
- setExtent(textWidth,textHeight);
- }
- protected void paint(Graphics graphics) {
- super.paint(graphics);
- graphics.setColor(Color.BLACK);
- graphics.drawRect(0,textWidth,textHeight);
- }
- }
我已经将其初始化为
- CustomTextField textField=new CustomTextField(200,20);
- add(textField);
解决方法
@H_502_26@ 所以,在黑莓领域,范围是一个字段的实际视觉尺寸.但是,虚拟范围是可以使用的逻辑大小,其中一些可能不可见.对于要滚动的管理器,通常将虚拟扩展范围设置为大于该范围.我使用这个概念来动态地改变您的HorizontalFieldManager的虚拟范围,这取决于当前需要多少空间才能适应BasicEditField中的文本.为此,我必须让HorizontalFieldManager通过实现FieldChangeListener监听BasicEditField的更改.然后,当每个字符输入到编辑字段时,水平字段管理器将重新计算现在在该字段中的文本量所需的宽度.然后将虚拟宽度重新设置为该宽度.
这使得水平字段管理器只允许滚动到输入的文本的末尾,而不是右边的方式,这是代码最初工作的方式.
所以,我不认为黑莓手机做错了什么…没有操作系统的bug.以前,虚拟范围没有设置.
我将您的HorizontalFieldManager拆分成一个新的私有类,因为当逻辑超过5行代码时,我不喜欢使用匿名类.所以,下面的解决方案有所不同.
其他想法:
1)由于您尝试使用自定义paint()实现绘制边框,因此存在绘图工件.但是,那个bug最初在那里,我把这个问题解释成是滚动问题.看起来您正在尝试使用Border对象,这可能是实现滚动字段边框的更好方式.
2)使用我的新解决方案,实际的CustomTextField类没有太多的内容.它只是CustomHorizontalFieldManager的容器(Manager).如果你想要的话,你可能会摆脱外层.但是,我知道有时你发布代码时,会删除对您遇到麻烦的事情不重要的细节.所以,也许需要一个VerticalFieldManager包含一个HorizontalFieldManager,它包含一个BasicEditField.我会把它留给你,但它只会是可选的清理.
3)我在5.0 Storm2模拟器上测试了这个.
- import net.rim.device.api.ui.Color;
- import net.rim.device.api.ui.Field;
- import net.rim.device.api.ui.FieldChangeListener;
- import net.rim.device.api.ui.Graphics;
- import net.rim.device.api.ui.Manager;
- import net.rim.device.api.ui.component.BasicEditField;
- import net.rim.device.api.ui.container.HorizontalFieldManager;
- import net.rim.device.api.ui.container.VerticalFieldManager;
- import net.rim.device.api.util.Arrays;
- public class CustomTextField extends VerticalFieldManager {
- private int textWidth = 0;
- private int textHeight = 0;
- private CustomHorizontalFieldManager hfm;
- public CustomTextField(int width,int height) {
- super();
- textWidth = width;
- textHeight = height;
- hfm = new CustomHorizontalFieldManager();
- add(hfm);
- }
- protected void sublayout(int maxWidth,int maxHeight) {
- super.sublayout(textWidth,textHeight);
- setExtent(textWidth,textHeight);
- }
- protected void paint(Graphics graphics) {
- // TODO: change me!
- super.paint(graphics);
- graphics.setColor(Color.BLACK);
- graphics.drawRect(0,textHeight);
- }
- private class CustomHorizontalFieldManager extends HorizontalFieldManager implements FieldChangeListener {
- private BasicEditField basicEditField;
- /** the maximum virtual width of the edit field,based on the max num of chars */
- private int maxVirtualWidth;
- public CustomHorizontalFieldManager() {
- super(Manager.HORIZONTAL_SCROLL);
- int maxNumChars = 200;
- basicEditField = new BasicEditField("",maxNumChars,BasicEditField.NO_NEWLINE);
- // determine how wide the field would need to be to hold 'maxNumChars',with the font
- // in use ... just pick a long string of all W's,since that's usually the widest char
- char[] buffer = new char[maxNumChars];
- Arrays.fill(buffer,'W');
- String spacer = new String(buffer);
- maxVirtualWidth = basicEditField.getFont().getAdvance(spacer);
- // we need to listen as the user types in this field,so we can dynamically alter its
- // virtual width
- basicEditField.setChangeListener(this);
- add(basicEditField);
- }
- protected void sublayout(int maxWidth,int maxHeight) {
- super.sublayout(maxWidth,maxHeight);
- // extent is the visible size,virtual extent can be wider if we want scrolling
- setExtent(textWidth,textHeight);
- setVirtualExtent(maxVirtualWidth,textHeight);
- }
- public void fieldChanged(Field f,int context) {
- if (f == basicEditField) {
- // recalculate how much virtual width the edit field needs,based on the
- // current text content
- int newWidth = basicEditField.getFont().getAdvance(basicEditField.getText());
- setVirtualExtent(newWidth,textHeight);
- }
- }
- }
- }