Related
I am new to the Blackberry Field, I want to create a customized Horizontal scroll view which should exactly looks like in the below image. Any Help will be Apprreciated
I am using Blackberry Simulator 9900, Thanks in advance .
I guess Middle portion is ONLY scrollable, right ?
You must have one HorizontalFieldManager with HORIZONTAL_SCROLL ( Middle one )
e.g. HorizontalFieldManager hfm = new HorizontalFieldManager( HORIZONTAL_SCROLL );
add your custom field in this manager.
You must add hfm in Custom OuterManager.
For your reference I'm posting my own code here...
private class HScroll extends MainScreen{
public HScroll() {
super( USE_ALL_WIDTH );
OuterManager father = new OuterManager( );
LabelField ll = new LabelField("<");
father.add(ll);
HorizontalFieldManager hfm = new HorizontalFieldManager( HORIZONTAL_SCROLL );
for( int i=0; i<10; i++ ){
ButtonField btn = new ButtonField(" i " + i);
hfm.add(btn);
}
father.add(hfm);
LabelField ll1 = new LabelField(">");
father.add(ll1);
add(father);
}
private class OuterManager extends net.rim.device.api.ui.Manager{
public OuterManager() {
super(USE_ALL_WIDTH);
}
protected void sublayout(int width, int height) {
int x = 0;
Field ff = getField( 0 );
Field ff2 = getField( 2 );
setPositionChild(ff, x, 0);
layoutChild(ff, ff.getPreferredWidth(), ff.getPreferredHeight());
x = x + ff.getPreferredWidth();
Field ff1 = getField( 1 );
setPositionChild(ff1, x , 0);
layoutChild(ff1, width - ff.getPreferredWidth() - ff2.getPreferredWidth() , ff1.getPreferredHeight());
x = width - ff2.getPreferredWidth();
setPositionChild(ff2, x, 0);
layoutChild(ff2, ff2.getPreferredWidth(), ff2.getPreferredHeight());
setExtent(width, height);
}
}
}
I want my application to align two field, one to left and other to extreme left of the screen. For that i am using GridLayoutManager class. Here is my code
GridFieldManager gridFieldManager = new GridFieldManager(2,2, GridFieldManager.PREFERRED_SIZE_WITH_MAXIMUM);
gridFieldManager.add(new ButtonField("Button One"), Field.FIELD_HCENTER);
gridFieldManager.add(new ButtonField("Button Two"), Field.FIELD_RIGHT);
gridFieldManager.add(new ButtonField("HC", Field.FIELD_HCENTER));
gridFieldManager.add(new ButtonField("RT", Field.FIELD_RIGHT));
add(gridFieldManager);
And, here is my output in simulator
Can anyone please help me to align the Button Two to the extreme right of the screen ? Any help will be appreciated.
Basically it's all a matter of alignment flags and grid's column properties.
Changing the GridFieldManager style to Manager.USE_ALL_WIDTH and setting column properties to GridFieldManager.AUTO_SIZE makes all the available space to be divided evently among the two columns.
gridFieldManager.setColumnProperty(0, GridFieldManager.AUTO_SIZE, 0);
gridFieldManager.setColumnProperty(1, GridFieldManager.AUTO_SIZE, 0);
The following code snippet
GridFieldManager gridFieldManager = new GridFieldManager(2,2, Manager.USE_ALL_WIDTH);
gridFieldManager.setColumnProperty(0, GridFieldManager.AUTO_SIZE, 0);
gridFieldManager.setColumnProperty(1, GridFieldManager.AUTO_SIZE, 0);
gridFieldManager.add(new ButtonField("Button One"), Field.FIELD_LEFT);
gridFieldManager.add(new ButtonField("Button Two"), Field.FIELD_RIGHT);
gridFieldManager.add(new ButtonField("HC"), Field.FIELD_LEFT);
gridFieldManager.add(new ButtonField("RT"), Field.FIELD_RIGHT);
add(gridFieldManager);
produces
This slightly modified code snippet
GridFieldManager gridFieldManager = new GridFieldManager(1,2, Manager.USE_ALL_WIDTH);
gridFieldManager.setColumnProperty(0, GridFieldManager.AUTO_SIZE, 0);
gridFieldManager.setColumnProperty(1, GridFieldManager.AUTO_SIZE, 0);
VerticalFieldManager vfmLeft = new VerticalFieldManager();
vfmLeft.add(new ButtonField("Button One", Field.FIELD_HCENTER));
vfmLeft.add(new ButtonField("HC", Field.FIELD_HCENTER));
gridFieldManager.add(vfmLeft, Field.FIELD_LEFT);
VerticalFieldManager vfmRight = new VerticalFieldManager();
vfmRight.add(new ButtonField("Button Two", Field.FIELD_HCENTER));
vfmRight.add(new ButtonField("RT", Field.FIELD_HCENTER));
gridFieldManager.add(vfmRight, Field.FIELD_RIGHT);
add(gridFieldManager);
produces
Finally, to illustrate what I said previously about the available space being divided evently among the two columns, the following code snippet
GridFieldManager gridFieldManager = new GridFieldManager(1,2, Manager.USE_ALL_WIDTH | Manager.USE_ALL_HEIGHT);
gridFieldManager.setColumnProperty(0, GridFieldManager.AUTO_SIZE, 0);
gridFieldManager.setColumnProperty(1, GridFieldManager.AUTO_SIZE, 0);
gridFieldManager.setRowProperty(0, GridFieldManager.AUTO_SIZE, 0);
VerticalFieldManager vfmLeft = new VerticalFieldManager(Manager.USE_ALL_WIDTH | Manager.USE_ALL_HEIGHT);
vfmLeft.setBackground(BackgroundFactory.createSolidBackground(Color.CYAN));
gridFieldManager.add(vfmLeft);
VerticalFieldManager vfmRight = new VerticalFieldManager(Manager.USE_ALL_WIDTH | Manager.USE_ALL_HEIGHT);
vfmRight.setBackground(BackgroundFactory.createSolidBackground(Color.GRAY));
gridFieldManager.add(vfmRight);
add(gridFieldManager);
produces two columns of equal size.
Please use this following class.
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.container.HorizontalFieldManager;
public class HFMLeftFieldRightField extends HorizontalFieldManager {
private Field leftField;
private Field rightField;
private final static int TOP_MARGIN = 0;
private final static int LEFT_MARGIN = 30;
public HFMLeftFieldRightField() {
super(USE_ALL_WIDTH);
}
public HFMLeftFieldRightField(boolean isQatari) {
super(USE_ALL_WIDTH | Field.FIELD_LEFT);
}
public void sublayout(int maxWidth, int maxHeight) {
super.sublayout(maxWidth, maxHeight);
int width = getWidth();
if (rightField != null) {
int x = width - rightField.getWidth() - LEFT_MARGIN;
int y = TOP_MARGIN;
setPositionChild(rightField, x, y);
}
if (leftField != null) {
int y = TOP_MARGIN+rightField.getHeight()/5;
int x = LEFT_MARGIN;
setPositionChild(leftField, 0, y);
}
setExtent(maxWidth, rightField.getHeight() + TOP_MARGIN * 2);
}
public void setLeftButton(Field leftField) {
this.leftField = leftField;
super.add(leftField);
}
public void setRightButton(Field rightField) {
this.rightField = rightField;
super.add(rightField);
}
}
And add field this way.
HFMLeftFieldRightField hfm = new HFMLeftFieldRightField();
hfm.setLeftButton(new EditField("Left"));
hfm.setRightButton(new EditField("Right"));
add(hfm);
More detail http://keraisureshvblackberry.blogspot.in/2012/02/there-are-very-common-there-there-are.html
Hope helpfull..
It seems like you should use JustifiedHorizontalFieldManager instead of GridFieldManager. JustifiedHorizontalFieldManager is not a standard manager included in BlackBerry SDK, but a member of a set of UI components released by RIM later to help developers build more rich UI Interfaces. You have to download the code from here, add it to your proyect and then include the following line:
JustifiedHorizontalFieldManager justifiedManager = new JustifiedHorizontalFieldManager(buttonOne, buttonTwo, false, USE_ALL_WIDTH );
Change the style parameter of your gridFieldManager constructor to
GridFieldManager.USE_ALL_WIDTH
It should be like this
GridFieldManager gridFieldManager = new GridFieldManager(2,2,GridFieldManager.USE_ALL_WIDTH );
I am having 2 EditFields in my login form with names Email: and Password:. Just below email I have login button. Suppose I come down till login, I can scroll back only till password field.The cursor fails to reach Email field. In simulator, I tried using arrow keys as well as trackpad. Please help how to scroll back to first editfield
AbsoluteFieldManager ab = new AbsoluteFieldManager();
add(ab);
new SeparatorField();
et=new EditField("Email-id:","");
pwd=new PasswordEditField("Password:","");
ab.add(et,35,110);
ab.add(pwd,35,150);
I am using AbsoluteFieldManager and developing for OS 6.0. I want the loginscreen to look like facebook login page.
Kindly let me know what can possibly be the reason for not able to scroll up
Maybe it is a RIM bug with the AbsoluteFieldManager. Never used it before so I don't know about it. You can create a work around to solve this problem. Find it below:
et=new EditField("Email-id:","");
pwd=new PasswordEditField("Password:","") {
protected int moveFocus(int amount, int status, int time) {
int cursorPosition = this.getCursorPosition();
if ((cursorPosition == 0) && (amount < 0)) {
et.setFocus();
return 0;
}
else {
return super.moveFocus(amount, status, time);
}
}
};
In this way, when you arrive to the first element in the password edit field, you will oblige the email field to get focused. This will work for you as a work around.
Another way to solve the problem is to add the two fields in an horizontal field manager, in that way I guess this will work for you for sure. If not use the first method. You can find below the code for HorizontalFieldManager:
et=new EditField("Email-id:","");
pwd=new PasswordEditField("Password:","");
HorizontalFieldManager manager = new HorizontalFieldManager();
manager.add(et);
manager.add(pwd);
ab.add(manager, yourX, yourY);
It also may be a RIM bug. What OS do you use? Is it OS 5+? Do you use custom paddings/margins/borders for some of the UI elements on the screen (including the screen itself)? If yes, try to comment out any code that sets paddings/margins/borders to check whether this it the case.
You can use this code for your login page:
public class loginscreen extends MainScreen implements FieldChangeListener {
private int deviceWidth = Display.getWidth();
private int deviceHeight = Display.getHeight();
private VerticalFieldManager subManager;
private VerticalFieldManager mainManager;
public long mycolor = 0x00FFFFFF;
Screen _screen = home.Screen;
TextField heading = new TextField(Field.NON_FOCUSABLE);
TextField username_ef = new TextField();
PasswordEditField password_ef = new PasswordEditField();
CheckboxField rememberpass = new CheckboxField();
public ButtonField login_bt = new ButtonField("Login", ButtonField.CONSUME_CLICK);
public ButtonField register_bt = new ButtonField("Register", ButtonField.CONSUME_CLICK);
public loginscreen()
{
super();
final Bitmap backgroundBitmap = Bitmap.getBitmapResource("bgd.png");
HorizontalFieldManager hfm = new HorizontalFieldManager(Manager.NO_VERTICAL_SCROLL | Manager.NO_VERTICAL_SCROLLBAR )
{
protected void sublayout(int width, int height)
{
Field field;
int numberOfFields = getFieldCount();
int x = 245;
int y = 0;
for (int i = 0;i < numberOfFields;i++)
{
field = getField(i);
setPositionChild(field,x,y);
layoutChild(field, width, height);
x +=_screen.getWidth()-381;
y += 0;//l17
}
width=_screen.getWidth();
height=48;//w19
setExtent(width, height);
}
};
mainManager = new VerticalFieldManager(Manager.NO_VERTICAL_SCROLL | Manager.NO_VERTICAL_SCROLLBAR )
{
public void paint(Graphics graphics)
{
graphics.clear();
graphics.drawBitmap(0, 0, deviceWidth, deviceHeight, backgroundBitmap, 0, 0);
super.paint(graphics);
}
};
//this manger is used for adding the componentes
subManager = new VerticalFieldManager(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR )
{
protected void sublayout( int maxWidth, int maxHeight )
{
int displayWidth = deviceWidth;
int displayHeight = deviceHeight;
super.sublayout( displayWidth, displayHeight);
setExtent( displayWidth, displayHeight);
}
public void paint(Graphics graphics)
{
graphics.setColor((int) mycolor);
super.paint(graphics);
}
};
username_ef.setLabel("Username: ");
password_ef.setLabel("Password: ");
rememberpass.setLabel("Remember Password");
heading.setLabel("Please enter your credentials: ");
username_ef.setMaxSize(8);
password_ef.setMaxSize(20);
subManager.add(heading);
subManager.add(username_ef);
subManager.add(password_ef);
subManager.add(rememberpass);
subManager.add(new SeparatorField());
login_bt.setChangeListener(this);
register_bt.setChangeListener(this);
hfm.add(login_bt);
hfm.add(register_bt);
subManager.add(hfm);
mainManager.add(subManager);
this.add(mainManager);
}
public boolean onSavePrompt()
{
return true;
}
public void fieldChanged(Field field, int context) {
// TODO Auto-generated method stub
if(field == login_bt)
{
//do your code for login button click
}
if(field == register_bt)
{
//code for register button click
}
}}
What you have described is not normal behavior.
My conclusion is that your code has one or more bugs, in order to solve your problem you should modify your code to fix the bugs. You will then be able to scroll up and down through the various fields.
note: As this question stands it's not possible for me to be more specific about the exact bugs. So instead I will show you an example of the layout you described that would scroll properly and you can use as a default to determine which of your deviations have caused your bugs.
// inside MainScreen constructor
add(new EditField("Username:","",0));
add(new EditField("Password:","",0));
add(new ButtonField(buttonBMP,ButtonField.CONSUME_CLICK));
I want my button to be at the right side and bottom side. How it is possible? Please help me. My code below only displays the button on the right side but not bottom.
ButtonField b = new ButtonField("button", Field.FIELD_RIGHT | FIELD_BOTTOM);
VerticalFieldManager vf = new VerticalFieldManager(Field.USE_ALL_WIDTH);
vf.add(b);
add(vf);
By default, a VerticalFieldManager will only use the smallest amount of vertical space necessary to display all of its children. So, your button is displaying at the bottom of the manager, but the manager is only as tall as your button. Also, a VerticalFieldManager is intended for top-down display. Try something like this:
HorizontalFieldManager hfm = new HorizontalFieldManager(USE_ALL_HEIGHT | USE_ALL_WIDTH);
VerticalFieldManager vfm = new VerticalFieldManager(USE_ALL_WIDTH | FIELD_BOTTOM);
ButtonField b = new ButtonField("Button", Field.FIELD_RIGHT);
vfm.add(b);
hfm.add(vfm);
add(hfm);
thanks to all. but i got my answer.
HorizontalFieldManager hfm = new HorizontalFieldManager(USE_ALL_HEIGHT | USE_ALL_WIDTH) {
public int getPreferredWidth() {
return Display.getWidth();
}
public int getPreferredHeight() {
return Display.getHeight();
}
protected void sublayout(int maxWidth, int maxHeight) {
int displayWidth = Display.getWidth();
int displayHeight = Display.getHeight();
super.sublayout(displayWidth, displayHeight);
setExtent( Math.min( Display.getWidth(), getPreferredWidth() ),
Math.min( Display.getHeight(), getPreferredHeight() ) );
}
};
VerticalFieldManager vfm = new VerticalFieldManager(USE_ALL_WIDTH | FIELD_RIGHT);
ButtonField b = new ButtonField("Button", Field.FIELD_RIGHT);
vfm.add(b);
hfm.add(vfm);
add(vfm);
It's perfect work to me.
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.
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...
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");
...
Hey i did the same thing using a HorizontalFieldManager that contains an image and a title
header_img = Bitmap.getBitmapResource("header.png");
title = new LabelField("Welcome",LabelField.FIELD_RIGHT);
header_manager = new HorizontalFieldManager()
{
protected void paint(net.rim.device.api.ui.Graphics graphics)
{
int y = this.getVerticalScroll();
graphics.drawBitmap( 0, y, header_img.getWidth(), header_img.getHeight(), header_img, 0, 0 );
graphics.setColor(Color.LEMONCHIFFON);
super.paint( graphics );
}
protected void sublayout(int maxWidth, int maxHeight)
{
super.sublayout(Display.getWidth(), 240);
Field field = title;
layoutChild(field, title.getWidth(), title.getHeight());
setPositionChild(field, (Display.getWidth()/2) -10, 13);
setExtent(Display.getWidth(),55);
}
};
header_manager.add(title);