How to customize listfield items? - blackberry

I am new to Blackberry development.My application contain five list items having strings each item.My requirement is when one cell is selected it should enlarge and other items adjust space automatically among them.
I took two types of images for list items one for general view and one for displaying the selected item when user clicked on it which is of more height than previous.
But the problem is when I selected one item it is enlarging and overlapped on the next item and is not displaying full item and not adjusting the space among them.
can anyone give me the solution for this. I am using the following code snippet....
_listField.setCallback(this);
_listField.setRowHeight(45);
_listField.setChangeListener(this);
public void drawListRow(ListField arg0, Graphics graphics, int index,
int y, int width) {
if (listFieldIndex != index) {
graphics.drawBitmap(0, y, listBkgrnd.getWidth(), listBkgrnd
.getHeight(), listBkgrnd, 0, 0);
graphics.setColor(0xAA0000);
graphics.setFont(this.getFont().derive(Font.BOLD, 17));
graphics.drawText(((Station) _stationList.elementAt(index))
.getStationName(), 15, y + 15, 0,
(listBkgrnd.getWidth() - 70));
graphics.setColor(0x770000);
graphics.setFont(this.getFont().derive(Font.PLAIN, 13));
// graphics.drawText(
// ((Station) _stationList.elementAt(index)).getCT(), 15,
// y + 40, 0, (listBkgrnd.getWidth() - 65));
} else {
graphics.drawBitmap(0, y, playBkgrnd.getWidth(), playBkgrnd
.getHeight(), playBkgrnd, 0, 0);
graphics.setColor(0xAA0000);
graphics.setFont(this.getFont().derive(Font.BOLD, 17));
graphics.drawText(((Station) _stationList.elementAt(index))
.getStationName(), 15, y + 15, 0,
(playBkgrnd.getWidth() - 70));
graphics.setColor(0x770000);
graphics.setFont(this.getFont().derive(Font.PLAIN, 13));
graphics.drawText(
s.getCT(), 15,
y + 40, 0, (playBkgrnd.getWidth() - 65));
}
}

List fields on BlackBerry assume that all rows are the same height.
To get the kind of effect you want, use a bunch of selectable fields in a VerticalFieldManager, you'll get a similar effect to a ListField. Be sure to make your items focusable, and call updateLayout whenever they gain or lose focus, then in your layout method, set the field's height according to whether or not it's focused. Something like the following outline:
public class CustomListFieldItem extends Field {
public boolean isFocusable() {
return true;
}
protected void onFocus(int direction) {
super.onFocus(direction);
updateLayout();
}
protected void onUnfocus() {
super.onUnfocus();
updateLayout();
}
protected void layout(int width, int height) {
if (isFocus()) {
setExtent(width, playBkgrnd.getHeight());
}
else {
setExtent(width, listBkgrnd.getHeight());
}
}
protected void paint(Graphics graphics) {
if (isFocus()) {
// draw selected item
}
else {
// draw unselected item
}
}
}

Related

Blackberry Custom Tab Fit to All Device Screen

i wanna know, how to fit screen my tabulation bar on blackberry. because my tab is match with blackberry 9700 but for blackberry 9900, my tab is too small. i wanna my tab is fit to all device scree.
thanks in advance :)
this is the code, i got from other post. sorry:
BottomPanel class
public class BottomPanel extends VerticalFieldManager implements
FieldChangeListener {
Bitmap home_bit = Bitmap.getBitmapResource("home.png");
Bitmap home_bit_hover = Bitmap.getBitmapResource("home_h.png");
Bitmap map_bit = Bitmap.getBitmapResource("map.png");
Bitmap map_bit_hover = Bitmap.getBitmapResource("map_h.png");
Bitmap contact_bit = Bitmap.getBitmapResource("contact.png");
Bitmap contact_bit_hover = Bitmap.getBitmapResource("contact_h.png");
PictureBackgroundButtonField home_pic, map_pic, contact_pic;
HorizontalFieldManager hr;
int current_index = 0;
public BottomPanel(int current_index) {
super(FOCUSABLE);
this.current_index = current_index;
VerticalFieldManager ver = new VerticalFieldManager(USE_ALL_WIDTH
| USE_ALL_HEIGHT) {
protected void sublayout(int width, int height) {
super.sublayout(width, home_bit.getHeight());
setExtent(width, home_bit.getHeight());
}
};
hr = new HorizontalFieldManager(FIELD_HCENTER);
if (current_index == 1) {
home_pic = new PictureBackgroundButtonField(home_bit.getWidth(),
home_bit.getHeight(), Field.NON_FOCUSABLE
| Field.FIELD_VCENTER, home_bit_hover,
home_bit_hover);
} else {
home_pic = new PictureBackgroundButtonField(home_bit.getWidth(),
home_bit.getHeight(),
Field.FOCUSABLE | Field.FIELD_VCENTER, home_bit,
home_bit_hover);
}
home_pic.setChangeListener(this);
hr.add(home_pic);
if (current_index == 2) {
map_pic = new PictureBackgroundButtonField(map_bit.getWidth(),
map_bit.getHeight(), Field.NON_FOCUSABLE
| Field.FIELD_VCENTER, map_bit_hover, map_bit_hover);
} else {
map_pic = new PictureBackgroundButtonField(map_bit.getWidth(),
map_bit.getHeight(), Field.FOCUSABLE | Field.FIELD_VCENTER,
map_bit, map_bit_hover);
}
map_pic.setChangeListener(this);
hr.add(map_pic);
if (current_index == 3) {
contact_pic = new PictureBackgroundButtonField(
contact_bit.getWidth(), contact_bit.getHeight(),
Field.NON_FOCUSABLE | Field.FIELD_VCENTER,
contact_bit_hover, contact_bit_hover);
} else {
contact_pic = new PictureBackgroundButtonField(
contact_bit.getWidth(), contact_bit.getHeight(),
Field.FOCUSABLE | Field.FIELD_VCENTER, contact_bit,
contact_bit_hover);
}
contact_pic.setChangeListener(this);
hr.add(contact_pic);
ver.add(hr);
add(ver);
}
public void fieldChanged(Field field, int context) {
if (field == home_pic) {
LoadingScreen loadingScreen = new LoadingScreen(1);
UiApplication.getUiApplication().popScreen(
UiApplication.getUiApplication().getActiveScreen());
UiApplication.getUiApplication().pushScreen(loadingScreen);
loadingScreen.createGUI();
} else if (field == map_pic) {
LoadingScreen loadingScreen = new LoadingScreen(2);
UiApplication.getUiApplication().popScreen(
UiApplication.getUiApplication().getActiveScreen());
UiApplication.getUiApplication().pushScreen(loadingScreen);
loadingScreen.createGUI();
} else if (field == contact_pic) {
LoadingScreen loadingScreen = new LoadingScreen(3);
UiApplication.getUiApplication().popScreen(
UiApplication.getUiApplication().getActiveScreen());
UiApplication.getUiApplication().pushScreen(loadingScreen);
loadingScreen.createGUI();
}
}
Loading Screen class
public class LoadingScreen extends MainScreen {
private LabelField text;
private LabelField texthasil;
private VerticalFieldManager manager;
int current_index = 0;
BottomPanel bottomPanel;
public LoadingScreen(int current_index) {
this.current_index = current_index;
bottomPanel = new BottomPanel(current_index);
setStatus(bottomPanel);
}
public void createGUI() {
manager = new VerticalFieldManager(Manager.VERTICAL_SCROLL
| Manager.VERTICAL_SCROLLBAR);
setStatus(bottomPanel);
}
PictureBackgroundButtonField class
public class PictureBackgroundButtonField extends Field {
private String _label;
private int _labelHeight;
private int _labelWidth;
private Font _font;
private Bitmap _currentPicture;
private Bitmap _onPicture;
private Bitmap _offPicture;
public PictureBackgroundButtonField(int width, int height, long style,
Bitmap picture, Bitmap selectedPic) {
super(style);
_font = getFont();
_label = "";
_labelHeight = height;
_labelWidth = width;
_currentPicture = picture;
_onPicture = selectedPic;
_offPicture = picture;
}
protected void drawFocus(Graphics graphics, boolean on) {
// Do nothing
}
public int getPreferredHeight() {
return _labelHeight;
}
public int getPreferredWidth() {
return _labelWidth;
}
protected void layout(int width, int height) {
setExtent(getPreferredWidth(), getPreferredHeight());
}
protected boolean navigationClick(int status, int time) {
fieldChangeNotify(1);
return true;
}
protected void onFocus(int direction) {
_currentPicture = _onPicture;
invalidate();
}
protected void onUnfocus() {
_currentPicture = _offPicture;
invalidate();
}
protected void paint(Graphics graphics) {
graphics.drawBitmap(0, 0, getPreferredWidth(), getPreferredHeight(),
_currentPicture, 0, 0);
graphics.setFont(_font);
graphics.drawText(
_label,
4,
2,
(int) (getStyle() & DrawStyle.ELLIPSIS | DrawStyle.HALIGN_MASK),
getWidth() - 6);
}
You don't show us what kind of tab bar background you have, and the solution does depend a little on that. If you are happy having a tab bar that is always the same height (in pixels), but just changes width, then you could use something like this.
I create a Manager subclass called TabBarManager. It will span the whole width of your screen, with a fixed height. It can have Field objects added to it like any normal manager. It is intended to have button fields added to it, so that when you click the button field, something happens. Probably, you'd also want the appearance of the button fields to change, depending on which tab is selected. However, it wasn't clear that this question was about that problem, so I didn't show that code. All this code does is give you a Manager to add tab fields to, that will draw a full-width background.
The tab bar fields that you add to this should contain icon images and/or labels, that have transparent backgrounds. For example, a white silhouette icon of a globe, if the tab is a map view. The transparent background shows through to the TabBarManager background.
The technique is to draw (in Photoshop, or whatever) three images. A left, right, and center image. Think of drawing a full tab bar image. Then, crop off the left few pixels, and save as TabBar-left.png. Crop the right few pixels and save as TabBar-right.png, and then crop a few pixels out of the center, and save as TabBar-center.png. Example images are shown below the code:
/**
* A TabBarManager provides a horizontal bar of button fields, that serve as a tab bar
* header or footer, used to select between available subviews in a larger Screen.
*/
private final class TabBarManager extends HorizontalFieldManager {
private int height;
private Bitmap left;
private Bitmap center;
private Bitmap right;
public TabBarManager() {
super(HorizontalFieldManager.NO_VERTICAL_SCROLL); // tab bar itself doesn't scroll
left = Bitmap.getBitmapResource("TabBar-left.png");
right = Bitmap.getBitmapResource("TabBar-right.png");
center = Bitmap.getBitmapResource("TabBar-center.png");
height = left.getHeight();
}
public void sublayout(int width, int h) {
super.sublayout(width, height);
setExtent(width, height); // restrict height to a fixed value
}
public int getPreferredHeight() {
return height;
}
public void paint(Graphics g) {
// draw the background image for the tab bar with two sides and a center section,
// to account for the fact that different devices have different widths
int width = Display.getWidth();
g.drawBitmap(0, 0, left.getWidth(), height, left, 0, 0);
// fill in the center by repeating the center image as many times as needed
int x = left.getWidth();
int centerWidth = center.getWidth();
int leftEdgeOfRightBitmap = width - right.getWidth();
while (x < leftEdgeOfRightBitmap) {
g.drawBitmap(x, 0, centerWidth, height, center, 0, 0);
x += centerWidth;
}
// draw right side
g.drawBitmap(leftEdgeOfRightBitmap, 0, right.getWidth(), height, right, 0, 0);
// use super.paint() to draw the icons/labels on top of our background
super.paint(g);
}
}
Left, center, and right PNGs (must be same height ... width doesn't matter):
, ,
How You Use It
In the code you show, you can either replace your hr variable with an instance of my TabBarManager. Or you can rename my TabBarManager class to BottomPanel, and add the additional code you need to it ... things like the current index, and the field change listener callback.
Limitations
The above implementation will only stretch the tab bar's width. The height is fixed. For a fully stretchable tab bar, you could either mimic a 9-patch image by drawing 9 images (top-left, top-center, top-right, left, center, right, bottom-left, bottom-center, bottom-right). Or use something like this to get 9-patch stretchable images for BlackBerry
References
http://supportforums.blackberry.com/t5/Java-Development/Create-tabbed-view-screens/ta-p/444969

Strange things happen when set margin to VerticalFieldManager

I'd like to generate a VerticalFieldManager that has a none-zero margin, so I create a VerticalFieldManager, and then use vfm.setMargin(10, 10, 10, 10); after that, put some fields(buttonField, ObjectChoiceField) in it.
It seems too simple, right? but strange thing happens. When I focus to the last ObjectChoiceField and press space to toggle choice of it, the ObjectChoiceField disappeared.
How can that be? here is the demo code, anyone kindly find the bug?
final class HelloWorldScreen extends MainScreen{
HelloWorldScreen() {
// just a demo to show the strange thing
String [] arr = {"a","b"};
for(int i = 0; i < 10; i++){
VerticalFieldManager vfm = new VerticalFieldManager(); // Field.USE_ALL_WIDTH
vfm.setMargin(10, 10, 10, 10);
ButtonField btn = new ButtonField(String.valueOf(i));
ObjectChoiceField ch = new ObjectChoiceField(String.valueOf(i), arr);
vfm.add(btn);
vfm.add(ch);
add(vfm);
}
}
}
Edit: screenshot of desired UI margins:
That is strange.
For the benefit of those who don't run your code, what's happening is that when you click on the object choice fields, the whole screen is scrolling a little bit vertically. After each vertical scroll, the screen loses the ability to scroll all the way down to the bottom. After many such operations, eventually much of the lower part of this screen is no longer accessible.
I don't know why this is happening. (looks like a BlackBerry bug to me)
What I observed is that if you take out the call to
vfm.setMargin(10, 10, 10, 10);
the problem goes away.
May I suggest a workaround where you use
vfm.setPadding(10, 10, 10, 10);
instead?
I know that margin and padding are not the same thing. However, depending on what your full UI design is (which I cannot see), in this case, setting a 10 pixel padding may be sufficient to do what you were trying to do.
Update: based on the screenshot of your desired UI, I was able to produce that with this workaround. Again, it shouldn't be this much work, but this additional code worked for me:
public class BugScreen extends MainScreen {
private static final int BG_COLOR = Color.LIGHTGRAY;
private static final int FG_COLOR = Color.WHITE;
private static final int BORDER_LINE_COLOR = Color.GRAY;
private static final int PAD = 10;
public BugScreen() {
super(MainScreen.VERTICAL_SCROLL | MainScreen.VERTICAL_SCROLLBAR);
getMainManager().setBackground(BackgroundFactory.createSolidBackground(BG_COLOR));
// this additional call ensures that when scrolling bounces, the area "behind"
// the normal visible area is ALSO of BG_COLOR
setBackground(BackgroundFactory.createSolidBackground(BG_COLOR));
// this will establish a thin gray padding on the screen's left/right sides
// NOTE: I seem to get drawing artifacts if I try to use this for ALL sides!
getMainManager().setPadding(0, PAD, 0, PAD);
String [] arr = {"a","b"};
for(int i = 0; i < 10; i++){
VerticalFieldManager vfm = new VerticalFieldManager(Field.USE_ALL_WIDTH) {
public int getPreferredWidth() {
return Display.getWidth() - 2 * PAD;
}
public void paint(Graphics graphics) {
int oldColor = graphics.getColor();
super.paint(graphics);
graphics.setColor(BORDER_LINE_COLOR);
// draw the (1-pixel wide) border size you would like.
graphics.drawRect(0, 0, getPreferredWidth(), getHeight());
graphics.setColor(oldColor);
}
};
vfm.setBackground(BackgroundFactory.createSolidBackground(FG_COLOR));
ButtonField btn = new ButtonField(String.valueOf(i));
ObjectChoiceField ch = new ObjectChoiceField(String.valueOf(i), arr);
vfm.add(btn);
vfm.add(ch);
// add a separator field to get thin gray margin between (vfm) fields
add(new MarginField());
add(vfm);
}
// add one last margin field at the bottom
add(new MarginField());
}
private class MarginField extends Field {
public MarginField() {
super(Field.USE_ALL_WIDTH);
}
public int getPreferredHeight() { return PAD; }
protected void paint(Graphics g) {
int oldColor = g.getColor();
g.setColor(BG_COLOR);
g.fillRect(0, 0, getWidth(), getPreferredHeight());
g.setColor(oldColor);
}
protected void layout(int width, int height) {
setExtent(width, getPreferredHeight());
}
}
}

Auto Expand Textbox in Blackberry

I have implemented the Custom Textbox in my app and it works well but now client need is to auto expand the texbox while typing like (BBM chat textbox ). Is there any way to override defualt Editfield to auto expand. Please suggest me.
This might do what you want; auto increase the height of the EditField:
class MyEditField extends EditField
{
public MyEditField (long style)
{
super (style);
setBorder (BorderFactory.createSimpleBorder(new XYEdges (1, 1, 1, 1)));
}
public int getPreferredHeight()
{
return Font.getDefault.getHeight() * 3; //setting the height of edit field as 3 rows
}
public void layout (int width, int height)
{
super.layout (width, height);
if (getExtent().height < getPreferredHeight())
setExtent (width, getPreferredHeight());
}
}

Blackberry Listfield highlight color

what is the best way to change the highlight (focus) color of a blackberry ListField, I have used the drawFocus method it does highlight thing but it's performance too slow to go on with
Code in drawlistrow
Item item = (Item)this.listData.elementAt(this.getSelectedIndex());
g.drawText (item.getItemNumber(), 2, y, Graphics.LEFT,20);
g.drawText (item.getDescription(), 25, y, Graphics.LEFT,30);
g.drawText (item.getItemType(), 60, y, Graphics.LEFT,15);
g.setColor(0xC4C3C4);
g.drawLine(2, y, 2, 115);
You can set the list field highlight colour using the following code
if (g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS)) {
//change focus color
g.setBackgroundColor(MyColors.LIGHT_GRAY);
g.clear();
//draw text
g.setFont(boldTextFont);
g.setColor(MyColors.White);
g.drawText(text, 12, y);
}
Do add your drawlistrow code so we can help you improve the performance.
create one boolean for this screen. boolean _inFocus = false; . Than add two method (onfocus, onunfocus)in your Listfield constructor .protected void onFocus(int direction)
{
_inFocus = true;
super.onFocus(direction);
}
protected void onUnfocus()
{
_inFocus = false;
super.onUnfocus();
} .
Than write down the below method in your drawListRow method . In the below method we will check that row is focusable or not.
if(_inFocus)
{
if(listField.getSelectedIndex() == index)
{
g.setGlobalAlpha(100);
g.setColor(0xff9600);
g.fillRect(0,y,getWidth(),getHeight());
//invalidate();
}
}
This is the simple way to highlight row in Listfield .
i hope it will help you.

not display cursor in custom BasicEditField bb

please check it
BasicEditField demo = ew BasicEditField("", number, 15,
BasicEditField.FILTER_NUMERIC
| BasicEditField.FIELD_LEFT) {
public int getPreferredWidth() {
int Width = Graphics.getScreenWidth() - 180;
return Width;
}
public int getPreferredHeight() {
return 30;
}
public void paint(Graphics g) {
g.setColor(Color.LINEN);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.BLUE);
g.drawText(getText(), 0, 0);
super.paint(g);
}
protected void layout(int arg0, int arg1) {
super.layout(getPreferredWidth(), getPreferredHeight());
super.setExtent(getPreferredWidth(), getPreferredHeight());
}
};
this is my code help me out?
Kalpana, I checked your code. Yes, It is not showing cursor. I suggest you to use EditField instead of BasicEditField. You can override these methods for Editfield also. I tried it and it is showing cursor.
I think I may have solved this by adding another field to the manager before this custom BasicEditField. Add a field that doesn't do anything. Something like this:
BitmapField bugFix = new BitmapField(Bitmap.getBitmapResource("empty_image.png"));
myFieldManager.add(bugFix);
myFieldManager.add(demo);
However, what I found is that the size of the dummy field (BitmapField in this case) matters. If your "empty_image.png" image is only 2px high, only the top 2px of the cursor will display. So, if you can deal with the extra padding, add a field that has at least 20px or so and the entire cursor should display. I should also add that this bug does not seem to show up on any subsequent custom BasicEditFields that you add to the manager... only the first one. Hmmm...

Resources