I did something very similar to the last project:
Background
As Armimed said in his answer , and as you can read about on the BlackBerry forums here , you cannot have full Field objects within the ListField . The contents of ListField strings ListField simply drawn directly in drawListRow() both text and bitmaps, etc. The content is not Field instances and therefore does not focus.
So, I made a replacement for the ListField subclass of Manager . I originally used the VerticalFieldManager , but ran into this. I also see a lot of problems with stack overflows, where people of the VerticalFieldManager subclass configure only one small behavior, and everything starts to break. It seems to me that the VerticalFieldManager works well if you agree with its normal behavior, and if you need something else, just stretch the Manager directly. Performing a layout for vertically stacked rows is quite simple.
Then I made each line my own Manager and implemented my own layout in sublayout() to place the Field line where I wanted it. Then I could make the line focused, and then the raster / button on the line separately focused (for example, your star). Clicking on a line brings up one action, and clicking on a star brings up another.
However, I should note that in my application, performance was not a problem because I only had 10-20 lines. Also, I had to change my code to fit your example, so consider this code only slightly verified. However, I created it in the application, so it should work fine as long as my assumptions and your description are valid.
Implementation
Firstly, it was not clear to me what your ListRander (you did not show this code). However, in my code, I need a data class to contain information about row one . It looked like you used ListRander , so I used:
public class ListRander { private String _title; private Bitmap _thumb; public ListRander(String title, Bitmap thumb) { _title = title; _thumb = thumb; } public String getTitle() { return _title; } public Bitmap getThumb() { return _thumb; } }
Then I replaced your CustomListField class with my own:
public class CustomListField extends Manager implements FocusChangeListener { private int _MAX_ROW_HEIGHT = 60; private boolean _searchable = false; private Vector _listData; private FieldChangeListener _fieldListener; public CustomListField(Vector data) { super(FOCUSABLE | VERTICAL_SCROLL | VERTICAL_SCROLLBAR); setSearchable(true); setEditable(false); setListData(data); } public void setChangeListener(FieldChangeListener listener) {
Finally, one line is represented by my CustomListRow class:
public class CustomListRow extends Manager implements FieldChangeListener { private static final int _MAX_ROW_HEIGHT = 60; private ListRander _data; private BitmapField _thumb; private LabelField _title; private FocusableBitmapField _star; private static final Bitmap _starImg = Bitmap.getBitmapResource("star.png"); private static final Bitmap _bgImg = Bitmap.getBitmapResource("listing_bg.png"); private SeparatorField _separator; private int _fontColor = Color.BLACK; private boolean _highlighted = false; private int _width;
Using
Here's how you can use the entire list box (possibly in the Screen class):
public class ListScreen extends MainScreen implements FieldChangeListener { public ListScreen() { try { Vector data = new Vector(); Bitmap icon = Bitmap.getBitmapResource("list_icon.png"); for (int i = 0; i < 15; i++) { ListRander lr = new ListRander("Product Name " + i, icon); data.addElement(lr); } CustomListField list = new CustomListField(data); add(list); list.setChangeListener(this); } catch (Exception e) { e.printStackTrace(); } } public void fieldChanged(Field field, int context) { if (field instanceof CustomListRow) { CustomListRow row = (CustomListRow) field; Dialog.alert(row.getData().getTitle() + " was selected!"); } } }
In my CustomListRow app, it made sense to process the equivalent of your star click. However, it did not make sense for me to use this series . So, I will let you set the FieldChangeListener to the CustomListField itself, which is called back when any row is selected. See the example above in my screen class. If you want to process the string, click inside the CustomListRow class too, that's fine. I set out onRowClicked() method there. Locate in the code for where it is commented out, and you can re-activate this method ( onRowClicked() ).
Questions
- My application did not require a list search. I set out an example implementation of this, such as
ListField . But I have not experienced this. This is your job if you need it. I just started by implementing CustomListField (see indexOfList() ). - I did not see what your "navigation bar" was for. Typically, a panel is a full-width element, such as a status bar or toolbar. I do not see anything like this in your screenshot. The nav element can be a small arrow on the right side of each line to display details. But I also did not see this in the screenshot. So, I ignored this code. If you need a navigation bar, you obviously know what it should be, and you can add this to my code above.
- I could not say if you added only a star as the background of the line background, or if you have a separate image for this. I added a separate star.png to represent the star. I would suggest that a flick of a star fills it or makes it stand out or something like that. But you did not describe this problem, therefore I assume that you will cope with it. If you need a custom field to represent a star that may have selected and unselected images, just post it as a new question.
- You got a code that looked like trying to set the line width to 3 times the line height, but that didn't match your screenshot. In any case, most lists have a screen width. So, I delete this code. My
CustomListRow class implements getPreferredWidth() and requests the full screen width. Change if you want.