Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blackberry VerticalFieldManager with fixed size : Scroll issue

Tags:

blackberry

I'm trying to have a full screen UI with a fix header ( a manager with some fields) and a scrollable contents (a list of custom field). The idea is to emulate a kind of scrollable list.

For this I made a custom VerticalFieldManager that accept a maxHeight (the screen height - the header height).

I got the following problems:

  • The scroll arrows do not show up (ever)
  • On OS 4.7 (Storm), I can scroll lower that the last item, until having nothing on my screen but the header.

My code need to compile with the JDE 4.2.1 & 4.7 and to run on Pearl and Storm. (at worst I could have two version of this class)

I suspect the two problems are related. I probably do something wrong. I looked at a few example/forum and always found similar solution/code. Do you guys can tell me what I did wrong?

/**
 *  custom class, so we can set a max height (to keep the header visible)
 */
class myVerticalFieldManager extends VerticalFieldManager{
private int maxHeight = 0;

myVerticalFieldManager(int _maxHeight){
  super(
   //this provoc an "empty scrollable zone" on Storm
   // but if you don't put it, on other OS, the vertical manager does not scroll at all.
   Manager.VERTICAL_SCROLL 

   | Manager.VERTICAL_SCROLLBAR
   ); 
  maxHeight = _maxHeight;
}


protected void sublayout(int width, int height){
        super.sublayout(width, getPreferredHeight());
        setExtent(width, getPreferredHeight());
}

public int getPreferredWidth() {
    return Graphics.getScreenWidth();
}

/**
 * allow the manager to use all the given height. (vs auto Height)
 */
public boolean forceMaxHeight = false;
public int getPreferredHeight() {
  if (forceMaxHeight) return maxHeight;
  int m = super.getPreferredHeight();
  if (m > maxHeight) m = maxHeight;
  return m;   
}    

////////////////////////////////////////////////////////////////////////////

protected boolean isUpArrowShown(){
  //TODO: does not seem to work (4.2.1 emulator & 4.5 device). (called with good return value but the arrows are not painted)
  int i = getFieldWithFocusIndex();
  //Trace("isUpArrowShown " + i);
  return i > 0;
  // note: algo not correct, cause the up arrow will be visible event when no field are hidden.
  //       but not so bad, so the user "know" that he can go up.
}

protected boolean isDownArrowShown(){
  int i = getFieldWithFocusIndex();
  return i < getFieldCount();
}

////////////////////////////////////////////////////////////////////////////
// note : since 4.6 you can use
// http://www.blackberry.com/developers/docs/4.6.0api/net/rim/device/api/ui/decor/Background.html

public int myBackgroundColor = 0xffffff;
protected void paint(Graphics g){
    g.setBackgroundColor(myBackgroundColor);
    // Clears the entire graphic area to the current background
    g.clear();
    super.paint(g);
}


} 

any helps is welcome.

like image 259
Loda Avatar asked Nov 25 '25 00:11

Loda


2 Answers

so,

I came with this workaround for the "empty scrollable zone" problem on STORM it's ugly and doesn't allow a custom ScrollChangeListener, but it's working on Pearl & Storm

implements ScrollChangeListener

 //in constructor:

  setScrollListener(null);
  setScrollListener(this);


private boolean MY_CHANGING_SCROLL = false;
public void scrollChanged(Manager manager, int newHorizontalScroll, int newVerticalScroll){
  if (!MY_CHANGING_SCROLL){
    MY_CHANGING_SCROLL = true;
    myCheckVerticalScroll();
    MY_CHANGING_SCROLL = false;
  }      
}  


protected int myMaxVerticalScrollPosition(){
  int vh = getVirtualHeight();
  int h = getHeight();
  if (vh < h ) return 0; // no scroll
  return vh - h; // don't scroll lower than limit.
}

protected void invCheckVerticalScroll() {
    int i = getVerticalScroll();
    int m = myMaxVerticalScrollPosition();
    if ( i > m){
        i = m;
        setVerticalScroll(i);
    }
}

I'm still looking for a solution to the scroll arrows problem... If anybody got an idea...

like image 53
Loda Avatar answered Nov 28 '25 01:11

Loda


You can use the method setBanner() instead of add for your header. Then you can add a default VerticalFieldManager to the screen and it will scroll normally but won't hide the header. Note that the MainScreen delegate manager is a VerticalScrollManager so you might not need a second vfm.

HorizontalFieldManager hfm = new HorizontalFieldManager();
setBanner(hfm)

add(new ButtonField("Hello 1");
add(new ButtonField("Hello 2");

...

like image 32
SamuelD Avatar answered Nov 28 '25 01:11

SamuelD