English 中文(简体)
黑莓——清单布局问题
原标题:Blackberry - Listfield layout question

在黑莓模拟器上显示一个清单时,我有意思的异常情况:

The top item is the height of a single line of text (about 12 pixels) while the rest are fine. Does anyone know why only the top item is being drawn this way? Also, when I add an empty venue in position 0, it still displays the first actual venue this way (item in position 1).

Not sure what to do. Thanks for any help.

具体做法如下:

-----------------------------------
| *part of image* | title         |
-----------------------------------
|                 | title         |
| * full image *  | address       |
|                 | city, zip     |
-----------------------------------

标的如下:

listField = new ListField( venueList.size() );
listField.setCallback( this );
listField.setSelectedIndex(-1);
_middle.add( listField );

这里是牙医 代码:

public void drawListRow( ListField listField, Graphics graphics, 
    int index, int y, int width ) 
{

    listField.setRowHeight(90);
    Hashtable item = (Hashtable) venueList.elementAt( index );
    String venue_name = (String) item.get("name");
    String image_url = (String) item.get("image_url");
    String address = (String) item.get("address");
    String city = (String) item.get("city");
    String zip = (String) item.get("zip");
    EncodedImage img = null;

try 
    {
        String filename = image_url.substring(image_url.indexOf("crop/") 
            + 5, image_url.length() );
        FileConnection fconn = (FileConnection)Connector.open( 
            "file:///SDCard/Blackberry/project1/" + filename, 
            Connector.READ);            
        if ( !fconn.exists() )
        {

        }
        else
        {
            InputStream input = fconn.openInputStream();

            byte[] data = new byte[(int)fconn.fileSize()];
            input.read(data);
            input.close();
            if(data.length > 0)
            {
                EncodedImage rawimg = EncodedImage.createEncodedImage(
                    data, 0, data.length);                  
                int dw = Fixed32.toFP(Display.getWidth());
                int iw = Fixed32.toFP(rawimg.getWidth());
                int sf = Fixed32.div(iw, dw);
                img = rawimg.scaleImage32(sf * 4, sf * 4);
            }
            else
            {

            }
        }
}
catch(IOException ef)
{                

} 

   graphics.drawText( venue_name, 140, y, 0, width );
   graphics.drawText( address, 140, y + 15, 0, width );
   graphics.drawText( city + ", " + zip, 140, y + 30, 0, width );
   if(img != null)
   {
       graphics.drawImage(0, y, img.getWidth(), img.getHeight(), 
           img, 0, 0, 0);
   }    
}
最佳回答
问题回答

Aman, Hopefully you can use this for something. You should be able to extract the list field data from this wildly out of control class. Remember, this is a work in progress, so you will have to strip out the things that are quite clearly custom to my app. Like the image handling that relies on a substring for a file name. It works fine for me, but it will totally not work for anyone htat just copies and pastes, so good luck...

 package venue;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;

import net.rim.device.api.math.Fixed32;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.system.EncodedImage;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.FocusChangeListener;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.Screen;
import net.rim.device.api.ui.Ui;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.ListField;
import net.rim.device.api.ui.component.ListFieldCallback;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.component.RichTextField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;

public class categoryView extends MainScreen implements FieldChangeListener, ListFieldCallback, FocusChangeListener  {

    private HorizontalFieldManager _top;
    private HorizontalFieldManager _nav;
    private VerticalFieldManager _middle;
    private int horizontalOffset;
    private final static long animationTime = 300;
    private long animationStart = 0;
    private int venue_id;
    private int category_id;
    private CustomButtonField rectangle;
    private Vector venueList = new Vector();
    private Hashtable venue_index = new Hashtable();
    private Vector image_index = new Vector();
    private ListField listField;
    private int last_menu_item = 2;
    private int last_nav = 2;
    private int before_last = 1;
    private int location_count = 0;
    private int img_width = 120;
    private int img_height = 80;
    private Field f;

    public categoryView(int id) {
        super();

        category_id = id;

        horizontalOffset = Display.getWidth();

        _top = new HorizontalFieldManager(Manager.USE_ALL_WIDTH | Field.FIELD_HCENTER)
        {
            public void paint(Graphics gr)
            {
                Bitmap bg = Bitmap.getBitmapResource("bg.png");
                gr.drawBitmap(0, 0, Display.getWidth(), Display.getHeight(), bg, 0, 0);
                subpaint(gr);
            }           
        };
        _nav = new HorizontalFieldManager(Field.USE_ALL_WIDTH);
        _middle = new VerticalFieldManager();

        add(_top);
        add(_nav);
        add(_middle);

        Bitmap lol = Bitmap.getBitmapResource("logo.png");
        BitmapField lolfield = new BitmapField(lol);
        _top.add(lolfield);

        HorizontalFieldManager nav = new HorizontalFieldManager(Field.USE_ALL_WIDTH | Manager.HORIZONTAL_SCROLL);

        Vector locs = getLocations();
        Hashtable locations = (Hashtable) locs.elementAt(0);
        Enumeration ne  = locations.keys();
        Enumeration nv = locations.elements();

        int counter = 1;
        if(locations.size() > 1)
        {
            counter = locations.size() - 1;
        }

        int count = 1;
        while(ne.hasMoreElements())
        {
            final String location_id = ne.nextElement().toString();
            String location = nv.nextElement().toString();
            last_nav = Integer.parseInt(location_id);

            rectangle = new CustomButtonField(location_id, location, 25, Field.FOCUSABLE);
            rectangle.setFocusListener(this);
            nav.add(rectangle);

            if(count == counter)
            {
                before_last = Integer.parseInt(location_id);
            }
            count ++;
        }   

        _nav.add(nav);

    }

    public void setDefaultLocation()
    {
        Vector locs = getLocations();
        Hashtable loc1 = (Hashtable) locs.elementAt(0);
        Enumeration er  = loc1.keys();
        Enumeration vr = loc1.elements();

        int i = 0;
        while(er.hasMoreElements())
        {
            final String location_id = er.nextElement().toString();

            if(i == 0)
            {
                last_menu_item = Integer.parseInt(location_id);
            }
            i ++;
        }

    }

    public void drawMiddle()
    {
        Vector venues = getVenues(category_id);
        Hashtable venue_list = (Hashtable) venues.elementAt(0);
        Enumeration e  = venue_list.keys();
        Enumeration v = venue_list.elements();

        int count = 0;
        while(e.hasMoreElements())
        {

            String vid = e.nextElement().toString();
            Hashtable elm = (Hashtable)v.nextElement();
            venueList.addElement(elm);
            venue_index.put(Integer.toString(count), (String) elm.get("venue_id"));

            EncodedImage img = null;
            String image_url = (String) elm.get("image_url");
            try 
            {
                String filename;
                    if(image_url.length() > 5)
                    {
                        filename = image_url.substring( image_url.indexOf("crop/") + 5, image_url.length() );
                    }
                    else
                    {
                        filename = "1.png";
                    }
                    FileConnection fconn = (FileConnection) Connector.open( "file:///SDCard/Blackberry/venue/" + filename, Connector.READ);

                    if ( !fconn.exists() )
                    {

                    }
                    else
                    {
                        InputStream input = fconn.openInputStream();

                        byte[] data = new byte[(int)fconn.fileSize()];
                        input.read(data);
                        input.close();
                        if(data.length > 0)
                        {
                            EncodedImage rawimg = EncodedImage.createEncodedImage(data, 0, data.length);

                            int dw = Fixed32.toFP(Display.getWidth());
                            int iw = Fixed32.toFP(rawimg.getWidth());
                            int sf = Fixed32.div(iw, dw);
                            img = rawimg.scaleImage32(sf * 4, sf * 4);
                            img_width = (int) Math.ceil(Display.getWidth() / 4);
                            img_height = (int) Math.ceil(Display.getWidth() / 6);
                        }
                        else
                        {

                        }
                    }
            }
            catch(IOException ef)
            {                

            } 

            image_index.addElement(img);

            count ++;
        }
        final int count_results = count;

        _middle = new VerticalFieldManager( Manager.VERTICAL_SCROLLBAR )
        {
            public void paint(Graphics graphics)
            {
                graphics.setBackgroundColor(0xFFFFFF);
                graphics.setColor(Color.BLACK);
                graphics.clear();
                super.paint(graphics);

            }
            protected void sublayout(int maxWidth, int maxHeight)
            {
                int displayWidth = Display.getWidth();
                //int displayHeight = Display.getHeight();
                int displayHeight = count_results * img_height;

                super.sublayout( displayWidth, displayHeight);
                setExtent( displayWidth, displayHeight);
            }

        };
        add(_middle);

        listField = new ListField( venueList.size() );
        listField.setCallback( this );
        listField.setSelectedIndex(-1);
        listField.setRowHeight(img_height);
        _middle.add( listField );

        _middle.add(new RichTextField(Field.NON_FOCUSABLE));
    }

    public boolean navigationClick(int status, int time) {

        Field focus = UiApplication.getUiApplication().getActiveScreen() .getLeafFieldWithFocus();

             if (focus instanceof ListField) {
                 int selected = listField.getSelectedIndex();
                 String venue_id = (String) venue_index.get(Integer.toString(selected));
                 moveScreens(venue_id);

        }
             return true;

 }

    void setListSize() 
    {
        listField.setSize( venueList.size() );
    }

    public void drawListRow( ListField listField, Graphics graphics, int index, int y, int width ) 
    {
        Hashtable item = (Hashtable) venueList.elementAt( index );

        String venue_name = (String) item.get("name");
        String address = (String) item.get("address");
        String city = (String) item.get("city");
        String zip = (String) item.get("zip");

        EncodedImage img = (EncodedImage) image_index.elementAt(index);

       graphics.drawText( venue_name, img_width + 10, y, 0, width );
       graphics.drawText( address, img_width + 10, y + 15, 0, width );
       graphics.drawText( city + ", " + zip, img_width + 10, y + 30, 0, width );
       if(img != null)
       {
           graphics.drawImage(0, y + 3, img.getWidth(), img.getHeight(), img, 0, 0, 0);
       }


    }

    public Object get( ListField listField, int index ) 
    {
        return venueList.elementAt( index );
    }

    public Vector getCategories()
    {
        Vector results = new Vector();

        database db = new database();
        Vector categories = db.getCategories();
        if(categories.size() > 0)
            results = categories;

        return results;
    }

    public Vector getLocations()
    {
        Vector results = new Vector();

        database db = new database();
        Vector subcats = db.getCategoryLocations(category_id);
        Hashtable subs = (Hashtable) subcats.elementAt(0);
        if(subs.size() > 0)
        {
            location_count = subs.size();
            results = subcats;
        }

        return results;
    }

    public Vector getVenues(int category_id)
    {
        Vector results = new Vector();

        database db = new database();
        Vector venues = db.getLocationVenues(category_id, last_menu_item);
        if(venues.size() > 0)
            results = venues;

        return results;
    }

    protected void makeMenu(Menu menu, int instance)
    {
        super.makeMenu(menu, instance);
        menu.add(new MenuItem("Home", 10, 20){
            public void run()
            {
                moveScreens("main");
            }
        });
        menu.add(new MenuItem("Search", 10, 20){
            public void run()
            {
                Dialog.inform("Search was clicked.");
            }
        });

        Vector locs = getLocations();
        Hashtable locations = (Hashtable) locs.elementAt(0);
        Enumeration e  = locations.keys();
        Enumeration v = locations.elements();

        while(e.hasMoreElements())
        {
            final String location_id = e.nextElement().toString();
            String location = v.nextElement().toString();

            menu.add(new MenuItem(location, 10, 20){
                public void run()
                {
                    Dialog.inform("Location " + location_id + " was clicked");
                }
            });
        }


    }

    public void moveScreens(String type)
    {
        if(type == "main")
        {
            UiApplication.getUiApplication().popScreen(this);
        }
        else
        {
            int venue_id = Integer.parseInt(type);

            Screen newScreen = new ViewVenue(venue_id);
            UiApplication.getUiApplication().pushScreen(newScreen);
        }
    }

    protected void sublayout(int width, int height)
    {
        super.sublayout(width, height);

        if(horizontalOffset > 0)
        {
            if(animationStart == 0)
            {
                animationStart = System.currentTimeMillis();
            }
            else
            {
                long timeElapsed = System.currentTimeMillis() - animationStart;
                if(timeElapsed >= animationTime)
                {
                    horizontalOffset = 0;
                }
                else
                {
                    float percentDone = (float)timeElapsed / (float)animationTime;
                    horizontalOffset = Display.getWidth() - (int)(percentDone * Display.getWidth());
                }
            }
        }
        setPosition(horizontalOffset, 0);

        if(horizontalOffset > 0)
        {
            UiApplication.getUiApplication().invokeLater(new Runnable(){
                public void run()
                {
                    updateLayout();
                }
            });
        }
    }

    public void fieldChanged(Field field, int context) 
    {

        int id = 0;

        if (field instanceof CustomButtonField) {
           id = ((CustomButtonField)field).getId();
        }        

        venue_id = id;
        Dialog.inform(Integer.toString(venue_id));
        //moveScreens("venue");

    }

    public void focusChanged(Field field, int eventType) {

        if((eventType == FocusChangeListener.FOCUS_GAINED)) {

            if (field instanceof CustomButtonField) {
              final int id = ((CustomButtonField)field).getId();

              if(id == last_nav && before_last != last_menu_item && last_nav != before_last)
              {
                  //updateContent(id);
                  f.setFocus();
              }
              else
              {
                  updateContent(id);
                  f = field;
              }



           } 
        }
    }

    public void updateContent(final int id)
    {
        UiApplication.getUiApplication().invokeLater(new Runnable(){
            public void run()
            {   
                delete(_middle);
                venueList.removeAllElements();
                image_index.removeAllElements();
                last_menu_item = id;

                drawMiddle();
            }
        });
    }

    public boolean onSavePrompt()
    {
        // do nothing
        return true;
    }

    public int getPreferredWidth(ListField listField) {
        // TODO Auto-generated method stub
        return 0;
    }

    public int indexOfList(ListField listField, String prefix, int start) {
        // TODO Auto-generated method stub
        return 0;
    }
}




相关问题
How to start to create an application GUI using C#?

HI! I am new to C# and plan to use it for my application GUI. I am trying to make my GUI similar to SPSS:http://www.spss.com/images/08/statistics_screens/ez_rfm-big.jpg Is this easy in C#? Is there ...

Automatic height of edit box

My shoes application has three items stacked on top of each other (with a stack, of course), in order: A banner An edit box Two buttons in a flow What I want to do is have the banner stay at it s ...

Search by using the keyboard in a list/grid - algorithm

I need to implement a custom search in a grid and I would like to find some user interface guidelines that explain the standard way to implement it. I mean this kind of search that is initiated by ...

UI And TcpClient Issue in vb.net

I m having some problems with a small ircbot i m writing. Basically I connect to the server using a tcpclient in a seperate class, which also runs on its own thread. I want to display the server text ...

UI Convention: Shortcut key for application exit? [closed]

Is there a convention for the shortcut keys for application exit? Some applications uses Alt+X some others use Ctrl+ X and Ctrl+Q. Applications like FF and IE doesnot assign a shortcut at all. So is ...

热门标签