I am developing an application which requires me to create a progress bar moving from right to left.
I tried using GaugeField by filling startVal as 100 and then on decrementing it but I couldn't achieve it.
Is there any way in BlackBerry say paint() method or drawRect() using timer where we can fill it from right to left?
Check following code for an implementation of Custom GaugeField.
Output
Implementation of CustomGaugeField
class CustomGaugeField extends GaugeField {
// Default constructor, need improvement
public CustomGaugeField() {
super("", 0, 100, 0, GaugeField.PERCENT);
}
// Colors
private static final int BG_COLOR = 0xd6d7d6;
private static final int BAR_COLOR = 0x63cb52;
private static final int FONT_COLOR = 0x5a55c6;
protected void paint(Graphics graphics) {
int xProgress = (int) ((getWidth() / 100.0) * getValue());
int xProgressInv = getWidth() - xProgress;
// draw background
graphics.setBackgroundColor(BG_COLOR);
graphics.clear();
// draw progress bar
graphics.setColor(BAR_COLOR);
graphics.fillRect(xProgressInv, 0, xProgress, getHeight());
// draw progress indicator text
String text = getValue() + "%";
Font font = graphics.getFont();
int xText = (getWidth() - font.getAdvance(text)) / 2;
int yText = (getHeight() - font.getHeight()) / 2;
graphics.setColor(FONT_COLOR);
graphics.drawText(text, xText, yText);
}
}
How to use
class MyScreen extends MainScreen {
public MyScreen() {
setTitle("Custom GaugeField Demo");
GaugeField gField;
for (int i = 0; i < 6; i++) {
gField = new CustomGaugeField();
gField.setMargin(10, 10, 10, 10);
add(gField);
}
startProgressTimer();
}
private void startProgressTimer() {
TimerTask ttask = new TimerTask() {
public void run() {
Field f;
for (int i = 0; i < getFieldCount(); i++) {
f = getField(i);
if (f instanceof CustomGaugeField) {
final CustomGaugeField gField = (CustomGaugeField) f;
final int increment = (i + 1) * 2;
UiApplication.getUiApplication().invokeLater(
new Runnable() {
public void run() {
gField.setValue((gField.getValue() + increment) % 101);
}
}
);
}
}
}
};
Timer ttimer = new Timer();
ttimer.schedule(ttask, 1000, 300);
}
}
Here is what I recommend you do. Download the BlackBerry Advanced UI Samples ... select the Download as Zip button.
Take a look at some screenshots of what the samples have here. The one you need to use is the Bitmap Gauge Field:
What you can do is modify the BitmapGaugeField class that they have in the sample folder, under Advanced UI -> src/com/samples/toolkit/ui/component
In BitmapGaugeField.java, you will only need to change the drawHorizontalPill() method:
private void drawHorizontalPill( Graphics g, Bitmap baseImage, Bitmap centerTile, int clipLeft, int clipRight, int width )
{
int yPosition = ( _height - baseImage.getHeight() ) >> 1;
width = Math.max( width, clipLeft + clipRight );
// ORIGINAL IMPLEMENTATION COMMENTED OUT HERE:
// Left
//g.drawBitmap( 0, yPosition, clipLeft, baseImage.getHeight(), baseImage, 0, 0);
// Middle
//g.tileRop( _rop, clipLeft, yPosition, Math.max( 0, width - clipLeft - clipRight ), centerTile.getHeight(), centerTile, 0, 0);
// Right
//g.drawBitmap( width - clipRight, yPosition, clipRight, baseImage.getHeight(), baseImage, baseImage.getWidth() - clipRight, 0);
int offset = _width - width;
// Left
g.drawBitmap( 0 + offset, yPosition, clipLeft, baseImage.getHeight(), baseImage, 0, 0);
// Middle
g.tileRop( _rop, clipLeft + offset, yPosition, Math.max( 0, width - clipLeft - clipRight ), centerTile.getHeight(), centerTile, 0, 0);
// Right
g.drawBitmap( width - clipRight + offset, yPosition, clipRight, baseImage.getHeight(), baseImage, baseImage.getWidth() - clipRight, 0);
}
The way you use this class is to pass in values for the background, and foreground (fill) stretchable bitmaps, the range of values, initial value, and some clipping margins.
public BitmapGaugeField(
Bitmap background, /** bitmap to draw for gauge background */
Bitmap progress, /** bitmap to draw for gauge foreground */
int numValues, /** this is the discrete range, not including 0 */
int initialValue,
int leadingBackgroundClip,
int trailingBackgroundClip,
int leadingProgressClip,
int trailingProgressClip,
boolean horizontal ) /** it looks like you could even do vertical! */
An example, if you want this gauge to go from 0 to 100, and have an initial value of 30 (this code goes in a Manager class):
Bitmap gaugeBack3 = Bitmap.getBitmapResource( "gauge_back_3.png" );
Bitmap gaugeProgress3 = Bitmap.getBitmapResource( "gauge_progress_3.png" );
BitmapGaugeField bitGauge3 = new BitmapGaugeField( gaugeBack3, gaugeProgress3,
100, 30,
14, 14, 14, 14,
true );
bitGauge3.setPadding(15,5,15,5);
add(bitGauge3);
bitGauge3.setValue(80); // change the initial value from 30 to 80
You'll find in the project some PNG images, like gauge_back_3.png and gauge_progress_3.png. If you don't like the colors or shapes, you can swap those images out for ones you draw yourself (in Photoshop, or another drawing program).
Good luck!
Related
I want to implement something like this in my application:
That is, each image contains one heart icon. I want to handle the click event on heart click and for that I have the following code
list.setEmptyString("No Image Available", DrawStyle.HCENTER);
list.setRowHeight(Display.getHeight() - 100);
list.setSize(data.size());
if (listVManager != null && listVManager.getFieldCount() > 0) {
listVManager.deleteAll();
}
list.setCallback(new ListFieldCallback() {
public void drawListRow(ListField list, Graphics graphics,
int index, int y, int w) {
int yPos = y + list.getRowHeight() - 1;
graphics.setColor(0x434343);
graphics.fillRect(0, y, w, list.getRowHeight());
if (logoThumbnailImage != null
&& logoThumbnailImage.length > index
&& logoThumbnailImage[index] != null) {
EncodedImage img = logoThumbnailImage[index];
graphics.drawImage(0, y + 10, Display.getWidth(),
Display.getHeight() - 100, img, 0, 0, 0);
graphics.drawText("Hello", 10,
Display.getHeight() - 150);
graphics.drawImage(Display.getWidth() - 70,
Display.getHeight() - 150 + 300,
heart.getWidth(), heart.getHeight(), heart,
0, 0, 0);
} else {
graphics.drawImage(
15,
y + 10,
Display.getWidth(),
Display.getHeight() - 100,
sizeImage(iconImage, Display.getWidth(),
Display.getHeight() - 100), 0, 0, 0);
}
graphics.drawText("Hello", 10,
Display.getHeight() - 150);
graphics.drawLine(0, yPos, w, yPos);
}
public Object get(ListField listField, int index) {
return null;
}
public int getPreferredWidth(ListField listField) {
return Display.getWidth();
}
public int indexOfList(ListField listField, String prefix,
int start) {
return 0;
}
});
listVManager.add(list);
loadImages = new LoadImages(80, 80);
loadImages.start();
}
});
here load image is thread that load images in background and store them in logoThumbnailImage array and invalidate list from there when the it loads the image.
The Load image thread class:
private class LoadImages extends Thread {
int widthL;
int heightL;
LoadImages(int width, int height) {
this.widthL = width;
this.heightL = height;
}
public void run() {
logoThumbnailImage=new EncodedImage[numberOfItem];
if (object != null) {
for (int i = 0; i < numberOfItem; i++) {
try {
String text=object[i].getJSONArray("UrlArray").getString(0).toString();
EncodedImage encodedImg = JPEGEncodedImage.encode(connectServerForImage(text), quality); //connectserverForImage load Images from server
logoThumbnailImage[i] = sizeImage(encodedImg, Display.getWidth(), Display.getHeight()-100);
list.invalidate();
} catch (Exception e)
{
e.printStackTrace();
}
}
} else {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert("No Data Found");
}
});
}
}
}
The application runs smoothly but I got the following output:
I have the following problem
1. The heart and description is displayed on only one list row. Can any one tell me what I am missing?
2. How to perform the click event on heart
Having looked at this only briefly, the problem appears to be that you are, in places, ignoring the 'y' position that is passed in to your drawListRow() method:
public void drawListRow(ListField list, Graphics graphics,
int index, int y, int w) {
Effectively the 'canvas' that you should be using to paint the current row (the row identified using int index) is bounded by the rectangle
(0, y, w, list.getRowHeight()).
In fact, you can actually paint anywhere in the extent that belongs to the ListField, i.e. the area you can paint onto is actually the rectangle
(0, 0, list.getWidth(), list.getHeight()).
You can do this, but you shouldn't. If you go outside your row's rectangle you will be painting over another row.
In your case, painting outside the selected row is exactly what your code does. You do this:
graphics.drawText("Hello", 10,
Display.getHeight() - 150);
This will actually be positioned on the ListField, 10 pixels in from the left and Display.getHeight() - 150 down from the top. It will be positioned at this point in the ListField, regardless of which row you are painting. So every row will put the Hello text in the same place.
So when coding your drawListRow(), make sure you offset all the positions to stay within the bounds of the row you are supposed to be painting. The origin of the area you are painting is (0, y), so offset all vertical positions using y. Do not use Display.getHeight(), use list.getRowHeight() to get the height you can paint (starting at y), and do not use Display.getWidth(), use the w variable that is passed in to get the width that you can paint. All your graphics actions should occur within these bounds.
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
I'm working on my own custom manager, and I've gotten it complete so far, but it setsMargins using a percentage of the screen resolution.
Here's how I call the following class:
LabelIconCommandManager licm3 = new LabelIconCommandManager("Address blah bklahblah ", 0);
licm3.add(new ImageButtonField(b1, b2, b3, Field.FIELD_LEFT | ImageButtonField.CONSUME_CLICK));
Here's the class [I've marked in a comment where it returns 0 and where it returns 219. please tell me why this happens:
public class LabelIconCommandManager extends HorizontalFieldManager implements BCMSField
{
LabelIconCommandManager me = this;
EvenlySpacedHorizontalFieldManager buttonManager = new EvenlySpacedHorizontalFieldManager(0);
LabelField labelField;
int side = 0;
int HPADDING = 3;
int VPADDING = 4;
int screenWidth = Display.getWidth();
int labelField_width = 40;
public LabelIconCommandManager()
{
this("", 0);
}
public LabelIconCommandManager(String label, long style)
{
super(USE_ALL_WIDTH| FOCUSABLE);
this.setBorder(BorderFactory.createBitmapBorder(new XYEdges(15, 20, 15, 20),Bitmap.getBitmapResource( "border_edit.png" )));
this.setMargin(1,10,1,10);
labelField = new LabelField(label,LabelField.ELLIPSIS)
{
public void layout(int width, int height)
{
// Done because otherwise ellipses dont work with labelfields
super.layout((int)(screenWidth * 0.61), getHeight());
setExtent((int)(screenWidth * 0.61), getHeight());
labelField_width = labelField.getWidth();
DisplayDialog.alert("labelField_width = " + labelField_width); // returns 219
}
};
// Top Right Bottom Left
labelField.setMargin(VPADDING, HPADDING, VPADDING, 0);
// super because we want this horizontalfieldManager to add it
super.add(labelField);
super.add(buttonManager);
}
public void alternateConstructor(Attributes atts)
{
labelField = new LabelField(atts.getValue("label"), 0);
}
public void onFocus(int direction)
{
this.setBorder(BorderFactory.createBitmapBorder(new XYEdges(15, 20, 15, 20),Bitmap.getBitmapResource( "border_edit_select.png" )));
// uses the same color as listStyleButtonField selections
this.setBackground(BackgroundFactory.createSolidBackground(0x186DEF));
super.onFocus(direction);
}
//Invoked when a field loses the focus.
public void onUnfocus()
{
//top, right,bottom,left
this.setBorder(BorderFactory.createBitmapBorder(new XYEdges(15, 20, 15, 20),Bitmap.getBitmapResource( "border_edit.png" )));
this.setBackground(BackgroundFactory.createSolidTransparentBackground(Color.GRAY, 0));
super.onUnfocus();
invalidate();
}
// Overrride this managers add function
public void add(Field imageButton)
{
// Add a button to the evenly spaced manager
buttonManager.add(imageButton);
// Based on how many buttons there are, set the margin of where the manager holding the buttons start [offset from labelField]
if(buttonManager.getFieldCount() == 1)
{
//side = (int)(screenWidth * 0.1388);
side = screenWidth - labelField_width - 32 - 10 - 15;
DisplayDialog.alert("Screen Width = " + screenWidth);
DisplayDialog.alert("labelField_width2 = " + labelField_width); // returns 0
DisplayDialog.alert("Side = " + side);
}
else side = (int)(screenWidth * 0.05);
buttonManager.setMargin(0,0,0,side);
}
public int getLabelWidth()
{
return labelField_width;
}
}
Here's a picture just to be more clear:
Note: when I ran your code, I didn't actually see labelField_width set to 0. You initialize the value to 40 in the code you posted above. So, I do sometimes see it set to 40, or 219 (on a 360 px wide screen).
But, the problem is that I think you're trying to access the value of labelField_width too soon. The only place it's properly assigned is in the layout() method of your anonymous LabelField. Just because you declare and implement the layout() method in line with the instantiation, doesn't mean that it's called when the LabelField is created. This is actually one of the reasons I don't like anonymous classes.
Anyway, this code:
LabelIconCommandManager licm3 = new LabelIconCommandManager("Address blah bklahblah ", 0);
licm3.add(new ImageButtonField(b1, b2, b3, Field.FIELD_LEFT | ImageButtonField.CONSUME_CLICK));
Will first instantiate the LabelField (inside the LabelIconCommandManager constructor). As I said, that does not trigger the layout() method. The second line above (add()) will trigger your overridden method:
// Overrride this managers add function
public void add(Field imageButton)
{
which is where you see the bad value for labelField_width. That method gets called before layout(). That's the problem.
Since it looks like you only use that width to set the buttonManager margin, you could just wait a little longer to do that. If you wait until the LabelIconCommandManager sublayout() method is called, your LabelField will have had its layout() method called, and labelField_width assigned correctly:
protected void sublayout(int maxWidth, int maxHeight) {
// make sure to call superclass method first!
super.sublayout(maxWidth, maxHeight);
// now, we can reliably use the label width:
side = screenWidth - labelField_width - 32 - 10 - 15;
buttonManager.setMargin(0,0,0,side);
}
That method goes in the LabelIconCommandManager class. And then, you can remove the other place you call buttonManager.setMargin().
Some brief summary from Nate post.
When you construct manager and add fields don't expect that it will be layouted correctly. Manager doesn't know the context - where it will be placed. So layout method for field will be called only when you add his manager to the screen (when layout for manager will be also called). And this is correct.
Move the calculation of your side variable to layout method.
If you really need side value before you put manager to screen. You could precalculate it by using Field.getPrefferedWidth() which returns meaningful values for standard fields (getFont().getAdvance(text) for LabelField, probably also with borders please check yourself). But be careful with this values.
Please review code below. It's manager which has label and buttons. And it puts label at the left side and buttons at the right.
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.decor.Border;
import java.util.Vector;
public class TabFieldManager extends Manager {
public TabFieldManager(long style) {
super(style);
}
protected void sublayout(int width, int height) {
LabelField label = null;
Vector tabs = new Vector();
int tabsWidth = 0;
int tabHeight = 0;
int tabPaddingTop = 0;
int tabPaddingLeft = 0;
for (int i=0; i < getFieldCount(); i++) {
Field field = getField(i);
if (field instanceof LabelField) {
label = (LabelField) field;
} else if (field instanceof ButtonField){
tabs.addElement(field);
layoutChild(field, width, height);
int fieldwidth = field.getWidth() > 0 ? field.getWidth() : field.getPreferredWidth() ;
tabsWidth += fieldwidth + getBorderAndPaddingWidth(field);
int fieldHeight = field.getHeight() > 0 ? field.getHeight() : field.getPreferredHeight();
if (fieldHeight > tabHeight) {
tabHeight = getBorderAndPaddingHeight(field) + fieldHeight;
}
int fieldPaddingTop = field.getPaddingTop();
if (fieldPaddingTop > tabPaddingTop) {
tabPaddingTop = fieldPaddingTop;
}
int fieldPaddingLeft = field.getPaddingLeft();
if (fieldPaddingLeft > tabPaddingLeft) {
tabPaddingLeft = fieldPaddingLeft;
}
}
}
if (label != null) {
layoutChild(label, width - tabsWidth, height);
int y = tabHeight - label.getHeight() >> 1;
setPositionChild(label, tabPaddingLeft , y);
}
for (int i = 0; i < tabs.size(); i++) {
Field tabField = (Field) tabs.elementAt(i);
setPositionChild(tabField, width - tabsWidth, getBorderAndPaddingHeight(tabField));
tabsWidth -= tabField.getWidth() + getBorderAndPaddingWidth(tabField);
}
setExtent(width, tabHeight);
}
private int getBorderAndPaddingHeight( Field field ) {
int height = field.getPaddingTop() + field.getPaddingBottom();
Border border = field.getBorder();
if( border != null ) {
height += border.getTop() + border.getBottom();
}
return height;
}
private int getBorderAndPaddingWidth( Field field ){
int width = field.getPaddingLeft() + field.getPaddingRight();
Border border = field.getBorder();
if( border != null ) {
width += border.getLeft() + border.getRight();
}
return width;
}
protected int moveFocus(int amount, int status, int time) {
if ((status & Field.STATUS_MOVE_FOCUS_VERTICALLY) == Field.STATUS_MOVE_FOCUS_VERTICALLY && amount > 0) {
return amount;
} else
return super.moveFocus(amount, status, time);
}
protected int nextFocus(int amount, int axis) {
if (amount > 0 && axis == Field.AXIS_VERTICAL)
return -1;
else
return super.nextFocus(amount, axis);
}
}
In my app i have to show list of items in list field when i click on specific item in the list field the background color for a particular row change to grey color.How to develop this type of custom list field in Blackberrry.Any one please give ideas.
Thank You
you should draw rectangle in listfield row which is selected.. some thing like this. Here i have done it for on focus..
public void drawListRow(ListField list, Graphics g, int index, int y,int w) {
if (g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS))
{
g.setBackgroundColor(0x00572000);
//g.setBackgroundColor();
g.clear();
//g.setColor(Color.BLACK);
// g.fillRect(0,list.getWidth(),list.getWidth(),80);
g.setColor(Color.ORANGE);
g.fillRect(94,y+0,400,30);
//g.setColor(0x000000);
g.setColor(Color.WHITE);
g.drawText(text, 95, y+10, (DrawStyle.LEFT ), w );
}
else
{
g.setColor(0x00906966);
g.fillRect(94,y+0,400,30);
g.setColor(Color.ORANGE);
g.drawText(text, 95, y+10, (DrawStyle.LEFT ), w );
}}
Try this ...
private class MyListField extends ListField{
//0,ListField.MULTI_SELECT
private boolean hasFocus = false;
public void onFocus(int direction){
hasFocus = true;
}
public void onUnfocus()
{
hasFocus = false;
super.onUnfocus();
invalidate();
}
public void paint(Graphics graphics)
{ int width = Display.getWidth();
//Get the current clipping region
XYRect redrawRect = graphics.getClippingRect();
if(redrawRect.y < 0)
{
throw new IllegalStateException("Error with clipping rect.");
}
//Determine the start location of the clipping region and end.
int rowHeight = getRowHeight();
int curSelected;
//If the ListeField has focus determine the selected row.
if (hasFocus)
{
curSelected = getSelectedIndex();
}
else
{
curSelected = -1;
}
int startLine = redrawRect.y / rowHeight;
int endLine = (redrawRect.y + redrawRect.height - 1) / rowHeight;
endLine = Math.min(endLine, getSize() - 1);
int y = startLine * rowHeight;
//Setup the data used for drawing.
int[] yInds = new int[]{y, y, y + rowHeight, y + rowHeight};
int[] xInds = new int[]{0, width, width, 0};
//Set the callback - assuming String values.
ListFieldCallback callBack = this.getCallback();
//Draw each row
for(; startLine <= endLine; ++startLine)
{
//If the line we're drawing is the currentlySelected line then draw the fill path in LIGHTYELLOW and the
//font text in Black.
if(startLine == curSelected){
graphics.setColor(Color.LIGHTYELLOW);
graphics.drawFilledPath(xInds, yInds, null, null);
graphics.setColor(Color.BLACK);
graphics.drawText((String)callBack.get(this, startLine), 0, yInds[0]);
}
else{
//Draw the odd or selected rows.
graphics.setColor(Color.LIGHTGREY);
graphics.drawText((String)callBack.get(this, startLine), 0, yInds[0]);
}
//Assign new values to the y axis moving one row down.
y += rowHeight;
yInds[0] = y;
yInds[1] = yInds[0];
yInds[2] = y + rowHeight;
yInds[3] = yInds[2];
}
//super.paint(graphics);
}
}
.
.
.
refer this [LINK] : http://berrytutorials.blogspot.com/2009/11/create-custom-listfield-change.html
Below email, user will enter email n below password a user will enter password, i m able to make square but upper square should be curve in upper side and lower square in lower side.
Something I made that I think will do what you want. You just have to add them to this Manager. Note that I don't think I have it compensating for things like margin or padding, so you can either figure that in with the paint() method, or just enclose it in another Manager that has the proper padding/margin:
public class GroupFieldManager extends VerticalFieldManager {
private int _rounding;
private int _bgColor;
private int _borderColor;
private boolean _divider;
private int _dividerColor;
public GroupFieldManager(boolean divider, long style) {
super(style);
_rounding = 20;
_bgColor = 0xFFFFFF;
_borderColor = 0xAAAAAA;
_divider = divider;
_dividerColor = 0xAAAAAA;
}
public GroupFieldManager(boolean divider) {
this(divider, 0);
}
public GroupFieldManager() {
this(false, 0);
}
/**
* Sets whether or not to draw a divider
* #param on
*/
public void setDivider(boolean on) {
_divider = on;
}
/**
* Sets the color for the divider (also turns divider on)
* #param color
*/
public void setDividerColor(int color){
_dividerColor = color;
_divider = true;
}
/**
* Sets the background color for the grouping
* #param color
*/
public void setBackgroundColor(int color) {
_bgColor = color;
}
/**
* Sets the border color for the grouping
* #param color
*/
public void setBorderColor(int color) {
_borderColor = color;
}
/**
* Sets the amount of rounding for the border
* #param rounding
*/
public void setRounding(int rounding) {
_rounding = rounding;
}
protected void paint(Graphics graphics) {
int oldColor = graphics.getColor();
//draw the background
graphics.setColor(_bgColor);
graphics.fillRoundRect(0, 0, getWidth(), getHeight(), _rounding, _rounding);
//draw the border
graphics.setColor(_borderColor);
graphics.drawRoundRect(0, 0, getWidth(), getHeight(), _rounding, _rounding);
//draw dividers
if(_divider) {
graphics.setColor(_dividerColor);
int y = 0;
//go through each field, figure it's height, and draw a line under it
for(int i=0;i<getFieldCount();i++) {
if(i != getFieldCount() - 1) {
int height = getField(i).getHeight();
y += height;
graphics.drawLine(0, y, getWidth(), y);
}
}
}
graphics.setColor(oldColor);
super.paint(graphics);
}
}
Since there are only methods available to draw four round corners you can use a clipping rectangle to clip the drawing at a straight line, i.e. you actually paint a larger rounded rect but clip the lower (or upper) part of it.