How to create Horizontal scroll view with the TextField in Blackberry - blackberry

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

Related

Blackberry how to design the Screen like Profile Screen !! Code for Blackberry 7.0

i am trying to make the Profile screen for my Application and the Requirement is :
I have the Data with me in the Vector and Image in bitmap form.. Only problem is that i am Struggling to figure out how it can be achieved, How to make the Photo Section parallel to the multiple Fields in Right hand Side..
Please help me out..
Thanks in Advance..
You haven't specified everything about how this should work. You may want the profile picture to scale with the screen size. Some of the fields may be editable. I'm not sure if you want backgrounds or borders drawn around the 3 rows of Text/Number. So, I had to make some guesses. But, this should get you started, and help you understand what's needed to create a custom Manager subclass, which is one of the ways to solve this problem.
public class ProfileScreen extends MainScreen {
public ProfileScreen() {
super(MainScreen.NO_VERTICAL_SCROLL | MainScreen.NO_VERTICAL_SCROLLBAR);
add(new ProfileManager());
}
private class ProfileManager extends Manager {
private static final int PADDING = 20; // TODO: might make this depend on screen size!
private static final int ROW_PAD = PADDING / 2;
private static final int NUM_ROWS = 3;
private String _name = "Nate";
private String _place = "USA";
private String _phone = "1-206-123-4567";
private String _email = "nate#stackoverflow.com";
private Bitmap _photo;
private Vector _text;
private Vector _numbers;
private LabelField _nameField;
private LabelField _placeField;
private LabelField _phoneField;
private LabelField _emailField;
private BitmapField _photoField;
private LabelField[] _textFields;
private LabelField[] _numberFields;
private int[] _rowLocations;
public ProfileManager() {
super(Manager.NO_VERTICAL_SCROLL | Manager.NO_VERTICAL_SCROLLBAR);
// Create the data and the fields ... this would probably be more
// dynamic in your production code, so the profile could change.
_nameField = new LabelField(_name);
_placeField = new LabelField(_place);
_phoneField = new LabelField(_phone);
_emailField = new LabelField(_email);
_photo = Bitmap.getBitmapResource("avatar.png");
_photoField = new BitmapField(_photo);
_text = new Vector();
_textFields = new LabelField[NUM_ROWS];
for (int i = 0; i < NUM_ROWS; i++) {
_text.insertElementAt("Text" + (i + 1), i);
_textFields[i] = new LabelField(_text.elementAt(i),
Field.USE_ALL_WIDTH | DrawStyle.HCENTER);
}
_numbers = new Vector();
_numberFields = new LabelField[NUM_ROWS];
for (int i = 0; i < NUM_ROWS; i++) {
_numbers.insertElementAt("Number" + (i + 1), i);
_numberFields[i] = new LabelField(_numbers.elementAt(i),
Field.USE_ALL_WIDTH | DrawStyle.HCENTER);
}
// We will store the bottom 3 row locations for use in paint()
_rowLocations = new int[NUM_ROWS];
// Add the fields to this manager
add(_photoField);
add(_nameField);
add(_placeField);
add(_phoneField);
add(_emailField);
for (int i = 0; i < NUM_ROWS; i++) {
// Add one row of Text and Number fields
add(_textFields[i]);
add(_numberFields[i]);
}
}
public int getPreferredHeight() {
return Display.getHeight(); // full screen
}
public int getPreferredWidth() {
return Display.getWidth(); // full screen
}
protected void sublayout(int width, int height) {
setExtent(width, height);
int x = PADDING;
int y = PADDING;
setPositionChild(_photoField, x, y);
layoutChild(_photoField, _photo.getWidth(), _photo.getHeight());
x += _photo.getWidth() + PADDING;
int widthMinusPhoto = width - 3 * PADDING - _photo.getWidth();
setPositionChild(_nameField, x, y);
layoutChild(_nameField, widthMinusPhoto, _nameField.getPreferredHeight());
y += _nameField.getHeight() + ROW_PAD;
setPositionChild(_placeField, x, y);
layoutChild(_placeField, widthMinusPhoto, _placeField.getPreferredHeight());
y += _placeField.getHeight() + ROW_PAD;
setPositionChild(_phoneField, x, y);
layoutChild(_phoneField, widthMinusPhoto, _phoneField.getPreferredHeight());
y += _phoneField.getHeight() + ROW_PAD;
setPositionChild(_emailField, x, y);
layoutChild(_emailField, widthMinusPhoto, _emailField.getPreferredHeight());
// layout the 3 rows of Text and Numbers (1/3 width for each label field (?)
x = PADDING;
y = PADDING + _photo.getHeight() + PADDING + ROW_PAD;
for (int i = 0; i < NUM_ROWS; i++) {
setPositionChild(_textFields[i], x, y);
// record the y coordinate of this row, to use in paint()
_rowLocations[i] = y;
layoutChild(_textFields[i],
width / 3, _textFields[i].getPreferredHeight());
setPositionChild(_numberFields[i], width - PADDING - width / 3, y);
layoutChild(_numberFields[i],
width / 3, _numberFields[i].getPreferredHeight());
y += _textFields[i].getPreferredHeight() + PADDING + 2 * ROW_PAD;
}
}
// paint overridden to draw gray box behind Text/Number rows
protected void paint(Graphics graphics) {
int oldColor = graphics.getColor();
// paint a light gray background behind each row of Text/Numbers
graphics.setColor(Color.LIGHTGRAY);
for (int i = 0; i < NUM_ROWS; i++) {
// if you want a solid border, use drawRect() instead of fillRect():
graphics.fillRect(PADDING, _rowLocations[i] - ROW_PAD,
getWidth() - 2 * PADDING, _textFields[i].getHeight() + 2 * ROW_PAD);
}
graphics.setColor(oldColor); // reset the color for super.paint()
super.paint(graphics);
}
}
}
It's not always required to override paint() in a custom Manager class. sublayout() is where most of the work is done, to position the fields. In this case, I chose to override paint() in order to provide a custom border around more than one field. This isn't the only way to do that, but there are definitely times when you'll want to be able to add custom drawing code, to improve the look of your UIs.
Results

Scroll only single listfield in multiple listfields blackberry

I'm new to blackberry and I've a question, I've 3 listfields in a row like
[--------One--------][--Two--][--Three--]
but when I scroll single one, every one scrolls!, how do I restrict scroll of others when focused one is scrolling?
EDIT
// ListFields
HorizontalFieldManager hfmMain = new HorizontalFieldManager();
HorizontalFieldManager hfmFist = new HorizontalFieldManager(FIELD_LEFT);
hfmFist.add(myListView);
HorizontalFieldManager hfmSecond = new HorizontalFieldManager();
hfmSecond.add(hizabListView);
HorizontalFieldManager hfmThird = new HorizontalFieldManager();
hfmThird.add(paraListView);
hfmMain.add(hfmFist);
hfmMain.add(hfmSecond);
hfmMain.add(hfmThird);
add(hfmMain);
The key is that you need to disable vertical scrolling for the Screen that contains all these managers and fields.
Then, you can create one horizontal field manager. And then, three vertical field managers. Put each list in its own vertical field manager, and then all three vertical field managers go into the horizontal field manager.
Here's a simple prototype that I tested:
public class ListFocusScreen extends MainScreen implements ListFieldCallback {
private ObjectListField list1;
private ListField list2;
private ListField list3;
private Bitmap icon2; // for list 2 cell background
private Bitmap icon3; // for list 3 cell background
public ListFocusScreen() {
// Do NOT allow vertical scrolling at the Screen level!!
super(MainScreen.NO_VERTICAL_SCROLL | MainScreen.NO_VERTICAL_SCROLLBAR);
// A container for the "row" of three side-by-side lists
HorizontalFieldManager hfm = new HorizontalFieldManager(Field.USE_ALL_WIDTH);
// Do create a vertical field manager for each list, that scrolls
VerticalFieldManager vfm1 = new VerticalFieldManager(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR) {
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(2 * Display.getWidth() / 3, maxHeight); // 2/3 width
}
};
VerticalFieldManager vfm2 = new VerticalFieldManager(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR) {
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(Display.getWidth() / 6, maxHeight); // 1/6 width
}
};
VerticalFieldManager vfm3 = new VerticalFieldManager(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR) {
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(Display.getWidth() / 6, maxHeight); // 1/6 width
}
};
Object[] listData1 = new Object[24];
for (int i = 0; i < listData1.length; i++) {
// generate fake data for list1
listData1[i] = String.valueOf(i) + ". Click to Download";
}
list1 = new ObjectListField();
list1.set(listData1);
list2 = new ListField();
list2.setCallback(this);
icon2 = Bitmap.getBitmapResource("octagon.png");
list2.setSize(15);
list3 = new ListField();
list3.setCallback(this);
icon3 = Bitmap.getBitmapResource("frame.png");
list3.setSize(15);
vfm1.add(list1);
vfm2.add(list2);
vfm3.add(list3);
hfm.add(vfm1);
hfm.add(vfm2);
hfm.add(vfm3);
add(hfm);
}
public void drawListRow(ListField listField, Graphics graphics, int index,
int y, int width) {
// this same method will be used for custom drawing of both lists 2 and 3
final int PAD = 4;
String text = (String)get(listField, index);
if (listField == list2) {
graphics.drawBitmap(0, y, width, width, icon2, 0, 0);
graphics.drawText(text, PAD, y + PAD);
} else if (listField == list3) {
graphics.drawBitmap(0, y, width, width, icon3, 0, 0);
graphics.drawText(text, PAD, y + PAD);
}
}
public Object get(ListField listField, int index) {
// TODO: normally, get this value from a vector of actual
// data for each list
return String.valueOf(index);
}
public int getPreferredWidth(ListField listField) {
return Display.getWidth() / 6;
}
public int indexOfList(ListField listField, String prefix, int start) {
return -1; // no search support
}
}
Results
As you can see, I was able to get each list scrolling vertically, independently.
You have several list fields into one screen manager and when you scroll down and when this manager is selected, then the scroll event is being sent to all these fields. And all of them are scrolling simultaneously.
I would separate every listfield into its own manager.

how can i remove a field from the manager in blackberry

first , please try to understand my problem because i know their are too many questions related to this , but in my case no-one is working
why i dont know , please see my code .
this is working
public final class MyScreen extends MainScreen implements FieldChangeListener
{
private combine enter_in;
private manager_s ms , ms_1 ;
private Bitmap img;
LabelField lb_1 , lb_2 , lb_3 ;
public MyScreen()
{
setTitle("MyTitle");
img = Bitmap.getBitmapResource("icon.png");
//Bitmap img_1 = Bitmap.getBitmapResource("icon.png");
enter_in = new combine ( Field.FOCUSABLE , img );
enter_in.setChangeListener(this);
ms = new manager_s( 0 , 4 );
ms.add(enter_in);
lb_1 = new LabelField("Menu") ;
lb_2 = new LabelField("Favorites") ;
lb_3 = new LabelField("Reserved") ;
ms.add(lb_1);
ms.add(lb_2);
ms.add(lb_3);
add(ms);
}
}
but when i am implementing FieldChangedListener , at that time ms.delete(lb_1) is not working but delete(ms) is working , please help solve this problem
public void fieldChanged(Field field, int context)
{
if ( field == enter_in )
{
ms.delete(lb_1);
}
}
so , i am asking that is , there any reason for ms.delete(lb_1) not working under MyScreen class .
see this is my manager_class which i am using as , Manager ( custom_manager ) and this manager is extended by my class , for adding the fields inside the screen
public class manager_s extends Manager
{
int col ;
int w_1 = 20 ;
protected manager_s(long style , int col )
{
super(style);
this.col = col ;
}
protected void sublayout(int width, int height)
{
for ( int i = 0 ; i < col ; i ++ )
{
Field field = getField (i);
layoutChild( field , 130 , 100 );
}
for ( int i = 0 ; i < col ; i ++ )
{
Field field = getField (i);
setPositionChild ( field , w_1 , 20 );
w_1 = w_1 + 135 ;
setExtent ( width , 200 );
}
}
}
and the error is INDEX_OUT_OF_BOUND_EXCEPTION , thats my question that , because every one on internet ( as a resource ) is saying that remove the field , but i my case nothing is working .
try this -
setTitle("MyTitle");
final ButtonField enter_in=new ButtonField("enter_in");
add(enter_in);
lb_1 = new LabelField("Menu") ;
lb_2 = new LabelField("Favorites") ;
lb_3 = new LabelField("Reserved") ;
final HorizontalFieldManager ms=new HorizontalFieldManager();
ms.add(lb_1);
lb_1.setMargin(0,50,0,0);//Here you can set the spacing between the Fields.
ms.add(lb_2);
lb_2.setMargin(0,50,0,0);//Here you can set the spacing between the Fields.
ms.add(lb_3);
add(ms);
FieldChangeListener listener=new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
if(field==enter_in){
ms.delete(lb_1);
ms.invalidate();
}
}
};
enter_in.setChangeListener(listener);
In place of my ButtonField , you can use your combine.

howto center a label on a screen using horizontalfield

I want to center a logo and a textfield in the middle of the screen, both vertically and horizontally. What is the best way to achieve this?
i have been trying with this so far..
public upd8rMainScreen(){
Bitmap logoBitmap = Bitmap.getBitmapResource("upd8rLOGO.png");
bitmapField = new BitmapField(logoBitmap, Field.FIELD_VCENTER);
labelfield = new LabelField("Tap Your Phone Onto The Reader To Activate",Field.FIELD_VCENTER);
topHfm = new HorizontalFieldManager(Manager.VERTICAL_SCROLL);
middleHfm = new HorizontalFieldManager(Manager.VERTICAL_SCROLL);
vfm = new VerticalFieldManager();
topHfm.add(bitmapField);
middleHfm.add(labelfield);
vfm.add(topHfm);
vfm.add(middleHfm);
add(vfm);
}
May be it help you Try this
Bitmap logoBitmap = Bitmap.getBitmapResource("basket.png");
bitmapField = new BitmapField(logoBitmap,Field.FIELD_HCENTER);
labelfield = new LabelField("Tap Your Phone Onto ",Field.FIELD_HCENTER);
//
VerticalFieldManager vrt=new VerticalFieldManager(USE_ALL_WIDTH)
{
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(Display.getWidth(),Display.getHeight());
setExtent(Display.getWidth(),Display.getHeight());
}
};
Font f=labelfield.getFont();
int hight1=f.getAdvance(labelfield.getText());
int k=labelfield.getPreferredHeight();
int number=hight1/Display.getWidth()+1;
int hight2=logoBitmap.getHeight();
int padding=(Display.getHeight()-((number*k)+hight2))/2;
if(padding>0){
bitmapField.setPadding(padding,0,0,0);
}
vrt.add(bitmapField);
vrt.add(labelfield);
image display like following
You can try re-setting the margin of the VerticalFieldManager like this :
topHfm = new HorizontalFieldManager(Manager.FIELD_HCENTER | Manager.FIELD_VCENTER);
midHfm = new HorizontalFieldManager(Manager.FIELD_HCENTER | Manager.FIELD_VCENTER);
topHfm.add(bitmapField);
midHfm.add(new LabelField("My Label", Manager.FIELD_HCENTER));
VerticalFieldManager vfm = new VerticalFieldManager(Manager.FIELD_VCENTER);
vfm.add(topHfm);
vfm.add(midHfm);
int screenHeight = Display.getHeight();
int screenWidth = Display.getWidth();
int totalContentHeight = topHfm.getPreferredHeight()+ midHfm.getPreferredHeight();
int maxContentWidth = (topHfm.getPreferredWidth()>midHfm.getPreferredWidth()) ? topHfm.getPreferredWidth() : midHfm.getPreferredWidth() ;
int marginTop = (screenHeight>totalContentHeight)? (screenHeight - totalContentHeight) / 2 : 0;
int marginLeft = (screenWidth>maxContentWidth)? (screenWidth - maxContentWidth ) / 2 : 0;
vfm.setMargin(marginTop, 0, 0, marginLeft);
add(vfm);
I don't claim this is the "best way" to do this, but I hope it'll work for your case.

accessing Inner class while creating BitmapField & adding it in HorizontalFieldManager

I'm creating a inner class in a method. After that I am accessing some statements like,
public class Test extends MainScreen
{
HorizontalFieldManager hfm;
Bitmap bitmap[] = new Bitmap[100];
BitmapField[] bitmapField = new BitmapField[100];
int countBitmap = 0;
Test()
{
VerticalFieldManager vfm_Main = new VerticalFieldManager();
hfm = new HorizontalFieldManager(HorizontalFieldManager.USE_ALL_WIDTH);
vfm_Main.add(hfm);
add(vfm_Main);
}
void drawBitmap()
{
bitmap[countBitmap] = new Bitmap(100, 100);
bitmapField[countBitmap] = new BitmapField(bitmap[countBitmap]){
public void paint(Graphics g)
{
................
................
g.drawLine(x1,y1,x2,y2);
}
}
synchronized(UiApplication.getEventLock())
{
for(int i = 0 ; i < bitmapField.length; i++)
{
if(bitmapField[i] != null)
{
bitmapField[i].setBitmap(bitmap[i]);
}
}
hfm.add(bitmapField[countBitmap]);
countBitmap++;
But here the problem is after creating the bitmap & before creating the bitmapField, control goes to
synchronized(UiApplication.getEventLock()){hfm.add(bitmapField[countBitmap]); }
So before creating the bitmapField, it adds it in hfm.
So the output is coming like "Everytime a new BitmapField is added in hfm (means at the same position by replacing the previous one)". But I want the BitmapFields come next to each other in hfm.
How to do it?
Any solution why the control goes first to hfm.add() before the new bitmapField() inner class?
first of all, several suggestions about code:
see no reason using synchronized since it's UI thread
don't setBitmap, bitmap is already passed to BitmapField constructor
actually all BitmapFields come next to each other in hfm, to make it clear, I've add number to each one.
if you want some custom constructor or new fields in BitmapField, it's better to create new class as an extension of BitmapField
class TestScr extends MainScreen {
HorizontalFieldManager hfm;
Bitmap bitmap[] = new Bitmap[100];
BitmapField[] bitmapField = new BitmapField[100];
TestScr() {
hfm = new HorizontalFieldManager();
add(hfm);
drawBitmap();
}
void drawBitmap() {
for (int i = 0; i < 5; i++) {
bitmap[i] = new Bitmap(50, 50);
Graphics graphics = new Graphics(bitmap[i]);
graphics.setColor(Color.RED);
String number = Integer.toString(i);
Font font = graphics.getFont().derive(Font.BOLD, 40, Ui.UNITS_px);
graphics.setFont(font);
int textWidth = graphics.getFont().getAdvance(number);
int textHeight = graphics.getFont().getHeight();
int x = (bitmap[i].getWidth() - textWidth) / 2;
int y = (bitmap[i].getHeight() - textHeight) / 2;
graphics.drawText(number, x, y);
bitmapField[i] = new BitmapField(bitmap[i]) {
public void paint(Graphics g) {
super.paint(g);
int width = getWidth() - 1;
int height = getHeight() - 1;
g.setColor(Color.GREEN);
g.drawLine(0, 0, width, 0);
g.drawLine(width, 0, width, height);
g.drawLine(width, height, 0, height);
g.drawLine(0, height, 0, 0);
}
};
hfm.add(bitmapField[i]);
}
}
}

Resources