尝试在BlackBerry 6上实现图片库时,我遇到了这个恼人的问题。
一切正常,但是当焦点从顶部按钮改变到屏幕下方的图片时,图像似乎有毛刺而不能正确地绘画。请参阅下面的图片以获取示例:
(焦点位于屏幕顶部(未显示))
(焦点现在位于左下方的图像上,请注意顶部图像现在因未知原因而空白)
无论我在tumbnail画廊添加多少张照片,都会发生这种情况。
现在这是我的代码,(关于缩略图绘制的一部分)
public ProductImage(String productName){
super(VERTICAL_SCROLL|VERTICAL_SCROLLBAR);
currentProduct = productName;
createGUI();
}
public void createGUI(){
deleteAll();
try{
Storage.loadPicture();
}catch(NullPointerException e){
e.printStackTrace();
}
this.setTitle(new LabelField(_resources.getString(PRODUCT_IMAGE), Field.FIELD_HCENTER));
if(ToolbarManager.isToolbarSupported())
{
Toolbar tb = new Toolbar();
setToolbar(tb.createToolBar());
}
else{
Toolbar tb = new Toolbar();
add(tb.createNavBar());
}
picVector = Storage.getPicture(currentProduct);
EncodedImage enc = EncodedImage.getEncodedImageResource("camera.png");
EncodedImage sizeEnc = ImageResizer.sizeImage(enc, Display.getHeight(), Display.getHeight());
takenPicture = new BitmapField(enc.getBitmap());
vfMain = new VerticalFieldManager();
vfMain.add(logo);
vfMain.add(new SeparatorField());
add(vfMain);
prepareBmpFields();
}
private void prepareBmpFields() {
System.out.println("This is the vector size: " + picVector.getPicVector().size());
LayoutManager manager = new LayoutManager();
FieldChangeListener itemListener = new ButtonListener();
mBmpFields = new ImageButtonField[picVector.getPicVector().size()];
for (int i = 0; i < picVector.getPicVector().size(); i++) {
/*EncodedImage image = EncodedImage
.getEncodedImageResource((String)imageVector.elementAt(i));*/
byte[] data = getData((String)picVector.getPicVector().elementAt(i));
//Encode and Resize image
EncodedImage eImage = EncodedImage.createEncodedImage(data,0,data.length);
eImage = ImageResizer.resizeImage(eImage, mImgWidth, mImgHeight);
ImageButtonField currentImage = new ImageButtonField(eImage.getBitmap());
currentImage.setAssociatedPath((String)picVector.getPicVector().elementAt(i));
mBmpFields[i] = currentImage;
mBmpFields[i].setChangeListener(itemListener);
manager.add(mBmpFields[i]);
}
vfMain.add(manager);
}
private class LayoutManager extends VerticalFieldManager {
public LayoutManager() {
super(VERTICAL_SCROLL | VERTICAL_SCROLLBAR);
}
protected void sublayout(int width, int height) {
int columns = mScrWidth / (mImgWidth + 2 * mImgMargin);
int scrWidth = Display.getWidth();
int rows = mBmpFields.length / columns
+ (mBmpFields.length % columns > 0 ? 1 : 0);
int counter = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
int posX = j * (mImgWidth + 2 * mImgMargin) + mImgMargin;
int posY = i * (mImgHeight + 2 * mImgMargin) + mImgMargin;
if(mBmpFields.length > counter){
Field field = mBmpFields[counter];
layoutChild(field, mImgWidth, mImgHeight);
setPositionChild(field, posX, posY);
counter++;
};
}
}
if(Display.getWidth() < Display.getHeight()){
setExtent(mScrWidth, (int)(mScrHeight*1.25));
}
else{
setExtent(mScrWidth, (int)(mScrHeight*2));
}
}
public int getPreferredWidth() {
return mScrWidth;
}
public int getPreferredHeight() {
return mScrHeight;
}
}
}
我删除了许多不相关的代码部分,但所需的代码就在那里。
有谁知道可能导致此问题的原因?谢谢你的帮助!
编辑:根据要求,这是我对ImageButtonField类的实现:
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Characters;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.component.BitmapField;
public class ImageButtonField extends BitmapField{
String associatedPath ="";
BitmapField image2;
public ImageButtonField(Bitmap image) {
super(image);
}
public void setAssociatedPath(String path){
associatedPath = path;
}
public String getAssociatedPath(){
return associatedPath;
}
public boolean isFocusable() {
return true;
}
protected void applyTheme(Graphics arg0, boolean arg1) {
}
protected void drawFocus(Graphics graphics, boolean on) {
}
protected void onFocus(int direction) {
// only change appearance if this button is enabled (aka editable)
if (isEditable()) {
invalidate(); // repaint
}
super.onFocus(direction);
}
public void onUnfocus() {
invalidate(); // repaint
super.onUnfocus();
}
protected boolean navigationClick(int status, int time) {
fieldChangeNotify(0);
return true;
}
protected boolean trackwheelClick(int status, int time) {
fieldChangeNotify(0);
return true;
}
protected void paint(Graphics graphics) {
super.paint(graphics);
if (isFocus()) {
graphics.setGlobalAlpha(128);
graphics.setColor(0x888888);
graphics.fillRect(0, 0, getWidth(), getHeight());
}else{
graphics.setGlobalAlpha(0);
graphics.setColor(0x000000);
graphics.fillRect(0, 0, getWidth(), getHeight());
//graphics.drawBitmap(0, 0, getWidth(), getHeight(), image2.getB, 0, 0);
}
}
protected boolean keyChar(char character, int status, int time) {
if(Characters.ENTER == character || Characters.SPACE == character) {
fieldChangeNotify(0);
return true;
}
return super.keyChar(character, status, time);
}
}
答案 0 :(得分:1)
好的,所以你可以忽略我的第一个答案,但由于我当时没有你的ImageButtonField
代码,我不想把它扔掉......也许其他人会觉得它很有用
最后,我不需要对ImageButtonField
进行任何更改,但我确实更改了您的LayoutManager
课程。我发现这是问题的方式是我刚开始用内置的UI替换你的自定义UI类。我将ImageButtonField
替换为BitmapField
。这没有解决它。然后,我将LayoutManager
替换为FlowFieldManager
并修复了它。所以,我知道问题出在哪里。
我的解决方案:
private class LayoutManager extends Manager {
public LayoutManager() {
super(VERTICAL_SCROLL | VERTICAL_SCROLLBAR);
}
protected void sublayout(int width, int height) {
setExtent(width, height);
// TODO: maybe always set the same virtual extent?
if (Display.getWidth() < Display.getHeight()) {
setVirtualExtent(mScrWidth, (int) (mScrHeight * 1.25));
} else {
setVirtualExtent(mScrWidth, (int) (mScrHeight * 2));
}
int columns = mScrWidth / (mImgWidth + 2 * mImgMargin);
// int scrWidth = Display.getWidth();
int rows = mBmpFields.length / columns + (mBmpFields.length % columns > 0 ? 1 : 0);
int counter = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
int posX = j * (mImgWidth + 2 * mImgMargin) + mImgMargin;
int posY = i * (mImgHeight + 2 * mImgMargin) + mImgMargin;
if (mBmpFields.length > counter) {
Field field = mBmpFields[counter];
layoutChild(field, mImgWidth, mImgHeight);
setPositionChild(field, posX, posY);
counter++;
}
}
}
}
public int getPreferredWidth() {
return mScrWidth;
}
public int getPreferredHeight() {
return mScrHeight;
}
}
我无法肯定地说我理解为什么你的原始代码不起作用,但我可以说我不会在原始代码中做过一些事情:
原始代码正在扩展VerticalFieldManager
,但正在sublayout()
中完成所有工作。所以,我认为没有任何意义延伸VerticalFieldManager
。我将其更改为只展开Manager
。
原始代码使用不同大小调用setExtent()
。我不认为这就是你想要的。 范围是Field
的实际尺寸。 虚拟范围是虚拟大小,您希望将其设置为大于实际范围,以便启用滚动。您不需要为纵向与横向动态计算不同的范围,因为传递给width
的{{1}}和height
参数已经反映了这一点。我不确定你是否真的需要设置不同的虚拟范围。我认为你应该总是将虚拟范围高度设置为图片高度的行数,占边距。
原始代码中有一个未使用的变量sublayout()
。我在上面评论过它。
答案 1 :(得分:0)
你也是posted this question recently,对吗?假设您在此引用的ImageButtonField
与您在另一个问题中所处理的ImageButtonField
相同,我是否正确?
我看不到你ImageButtonField
的完整实现,你也可以在这里发布。但是,看看你的另一个问题的答案,我感觉你在Field
做了一些自定义焦点处理,也许它没有做得很好。在任何情况下,该类可能是问题所在。
我有一个类似我自己的public class CustomButtonField extends Field {
private Bitmap _button; // the currently displayed button image
private Bitmap _on; // image for 'on' state (aka in-focus)
private Bitmap _off; // image for 'off' state (aka out-of-focus)
protected void onFocus(int direction) {
// only change appearance if this button is enabled (aka editable)
if (isEditable()) {
_button = _on;
invalidate(); // repaint
}
super.onFocus(direction);
}
protected void onUnfocus() {
_button = _off;
invalidate(); // repaint
super.onUnfocus();
}
protected void drawFocus(Graphics graphics, boolean on) {
// override superclass implementation and do nothing
}
public boolean isFocusable() {
return true;
}
子类,这里是我定义的焦点处理方法:
paint()
我还有paint()
的自定义实现。我不会在这里显示所有内容,因为很多代码可能与您的问题无关,但我的graphics.drawBitmap(_padding, _padding, _fieldWidth, _fieldHeight, _button, 0, 0);
确实包含此调用:
onFocus()
您可能不关心我为聚焦和未聚焦状态分别创建图像的事实......也许您始终会显示相同的图像。
但是,可能需要检查的是onUnfocus()
和invalidate()
方法。您可能需要像我一样添加对ImageButtonField.paint()
的调用。
看看Rupak对你的另一个问题的回答,检查你的{{1}}方法也是一件好事,并确保如果该字段不是焦点,你不会忽视做重要的绘图步骤。