1

BlackBerry 6に画像ギャラリーを実装しようとすると、この厄介な問題が発生します。

すべてが機能しますが、フォーカスが上部のボタンから画面のさらに下の画像に変わると、画像がグリッチし、正しくペイントされないように見えます。例については、以下の画像を参照してください。

(フォーカスは画面の上部にあります(表示されていません)) 初期画面

(フォーカスは左下の画像にあります。不明な理由で上の画像が空白になっていることに注意してください)

スクロール画面後

そして、これは私がタンブネイルギャラリーにいくつの写真を追加しても起こります。

これが私のコードです(サムネイルの描画に関するコードの一部です)

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);
}

}

4

2 に答える 2

1

さて、あなたは私の最初の答えを無視することができますが、私はImageButtonFieldその時にあなたのコードを持っていなかったので、私はそれを捨てたくありません...多分誰か他の人がそれを役に立つでしょう。

結局、変更する必要はありませんでしImageButtonFieldたが、LayoutManagerクラスを変更しました。それが問題であると私が理解した方法は、カスタムUIクラスを組み込みのUIクラスに置き換え始めたところです。に置き換えImageButtonFieldましたBitmapField。それはそれを修正しませんでした。その後、に置き換えLayoutManagerFlowFieldManager修正しました。だから、私は問題がどこにあるかを知っていました。

私の解決策:

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;
  }
}

元のコードが機能しなかった理由を理解しているとは言えませんが、元のコードでいくつかのことをしなかったとは言えます。

  1. 元のコードは拡張VerticalFieldManagerされていましたが、ですべての作業自体を実行していましたsublayout()。ですから、延長する意味はなかったと思いますVerticalFieldManager。ただ拡張するように変更しましたManager

  2. setExtent()元のコードはさまざまなサイズで呼び出していました。私はそれがあなたが望んでいたことではないと思います。 エクステントは、の実際のサイズですField仮想範囲は、スクロールを有効にするために実際の範囲よりも大きく設定する仮想サイズです。に渡されるパラメータとパラメータはすでにそれを反映しているため、ポートレートとランドスケープの異なる範囲を動的に計算する必要はありません。異なる仮想エクステントを設定する必要があるかどうかもわかりません。おそらく、マージンを考慮して、仮想エクステントの高さを行数×画像の高さに設定する必要があると思いますwidthheightsublayout()

  3. scrWidth元のコードに未使用の変数がありました。私はそれを上でコメントアウトしました。

于 2012-06-16T01:31:17.527 に答える
0

最近この質問も投稿しましたよね?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()ん。

他の質問に対するRupakの回答を見て、ImageButtonField.paint()方法を確認し、フィールドに焦点が合っていない場合に重要な描画手順を実行することを怠っていないことを確認することもお勧めします。

于 2012-06-14T00:21:02.063 に答える