Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java ME (J2ME) > Как нормально доработать листалку? canvas список!


Автор: Цербер 7.8.2009, 11:52
Доброго времени суток уважаемые форумчане!
Сделал листалку списка с помощью Canvas, но есть небольшая загвостка, решение которой никак не могу додумать.
Когда листалка доходит до нижней точки экрана она листает список дальше, но если поднимать вверх, то листалка остаётся на месте пропуская список через себя.
Надеюсь Вы поможете разобраться, пробовал по разному переделать циклы, но результат не стал лучше.
Вот класс списка:
Код

package tcity;

import javax.microedition.lcdui.*;

public class DrawList extends Canvas implements CommandListener{
    private Command exitCommand = new Command("Выход", Command.EXIT, 0);
    private Command backCommand = new Command("Назад", Command.BACK, 0);
    private int index = 0;
    private int width;
    private int height;
    private int hStr = 20;
    private int yPosStr;
    private int yPosRect;
    private int oneStep;
    private int allStep;
    private int hScroll;
    private int stepNow;
    private int yPosScroll;
    private int beginCount;
    private int endCount;
    Display display;
    String str[] = {
        "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
        "11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
        "21", "22", "23", "24", "25", "26", "27", "28", "29", "30",
        "31", "32", "33", "34", "35", "36", "37", "38", "39"
    };
    public void paint(Graphics g) {
        width = g.getClipWidth();
        height = g.getClipHeight();
        oneStep = height/hStr;
        allStep = str.length/oneStep;
        if(allStep * oneStep < str.length) {
            allStep++;
        }
        hScroll = height/allStep;
        beginCount = 0;
        stepNow = 1;
        if(beginCount + oneStep - 1 < str.length) {
            endCount = beginCount + oneStep - 1;
        }
        else endCount = str.length;
        g.setColor(255, 255 , 255);
        g.fillRect(0, 0, width, height);
        g.setColor(55, 60, 62);
        int i=0;
        while(beginCount < endCount+1) {
            if(i==0) {
                yPosStr = 3;
                yPosRect = 0;
            }
            else {
                yPosStr = ((hStr * (i+1))-hStr)+3;
                yPosRect = ((hStr * (i+1))-hStr);
            }
            g.setColor(0x373c3e);
            g.drawString(str[beginCount], 5, yPosStr, g.TOP | g.LEFT);
            if(beginCount==index) {
                drawLabel(g, 0x8ec736, 0x373c3e, str[index], 5, yPosStr, yPosRect, hStr, width);
            }
            if(index > endCount && index<str.length) {
                if(endCount<str.length-1) endCount++;
               // else endCount=str.length-1;
                if(beginCount < str.length) {
                   beginCount++;
                    //if(beginCount+oneStep<str.length-1) beginCount+=oneStep;
                   //else beginCount++;
                   g.setColor(255, 255 , 255);
                   g.fillRect(0, 0, width, height);
                   g.setColor(0x373c3e);
                   g.drawString(str[beginCount], 5, yPosStr, g.TOP | g.LEFT);
                }
                i=0;
            }
            else {
                beginCount++;
                i++;
            }
            if(index>beginCount) {
                
            }
            
            if(stepNow==1) {
                yPosScroll = 0;
            }
            if(stepNow>1) {
                yPosScroll = (stepNow-1) * hScroll;
            }
            if(index > (oneStep * stepNow) + 1) {
                stepNow++;
                g.setColor(255, 255 , 255);
                g.fillRect(width-8, 0, width, height);
                drawScroll(g, 0xffffff, 0x373c3e, 0x8ec736, yPosScroll);
            }
            
            drawScroll(g, 0xffffff, 0x373c3e, 0x8ec736, yPosScroll);
        }
    }

    private void drawLabel(Graphics g, int bgColor, int strColor, String title, int xPosStr, int yPosStr, int yPosRect, int columnH, int widthScreen) {
        g.setColor(bgColor);
        g.fillRect(0, yPosRect, widthScreen-8, columnH); //Заливаем прямоугольник №3
        g.setColor(strColor);
        g.drawString(title, xPosStr, yPosStr, g.TOP | g.LEFT);
    }

    public void drawScroll(Graphics g, int borderClr, int barCrl, int scrollClr, int yPosScrl) {
        g.setColor(borderClr);
        g.drawRect(width-8, 0, width, height);
        g.setColor(barCrl);
        g.fillRect(width-7, 0, width, height);
        g.setColor(scrollClr);
        g.fillRect(width-7, yPosScroll, width, hScroll);
    }

    public void keyPressed(int KeyCode) {
      int press = getGameAction(KeyCode); //Заносим в переменную код нажатой кнопки
      switch(press) {
          case Canvas.DOWN:
              if (index > str.length-2) {
                index = 0;
              }
              else {
                  index++;
              }
              repaint();
          break;
          case Canvas.UP:
              if (index < 1) {
                index = str.length-1;
              }
              else {
                index--; // Перемещаем прямоугольники вверх
              }
              repaint();
          break;
          case Canvas.FIRE:
                //Tcity.getInstance().showKey(index);
          break;
      }
    }
    public void commandAction(Command c, Displayable d) {
        if(c==backCommand) {
            repaint();
            Tcity.getInstance().startApp();
        }
        if(c==exitCommand) {
            Tcity.getInstance().destroyApp(false);
        }
    }

}


Автор: Цербер 26.8.2009, 09:40
Так никто и не ответил smile и я никак въехать не могу как доделать управление списком.

Автор: hamsterKSU 26.8.2009, 18:54
не понял проблемы. вроде все нормально работает. с первого на последний прыгает. с последнего на превый

Добавлено через 1 минуту и 22 секунды
а все, понял что хотишь сделать. счас попробуем, но и так вроде нормально

Автор: Цербер 28.8.2009, 12:41
hamsterKSU буду очень признателен, голову изломал никак не смог добиться иного результат =( надеюсь покажите как надо, новичку =)

Автор: hamsterKSU 29.8.2009, 10:12
все очень просто...
P.S. честно признаюсь прорисовку скрола взял из библиотеки J4ME. можешь на нее посмотреть - открытый код, нормальная лицензия

Код

    import javax.microedition.lcdui.*;

public class DrawList extends Canvas implements CommandListener {

    private Command exitCommand = new Command("Выход", Command.EXIT, 0);
    private Command backCommand = new Command("Назад", Command.BACK, 0);
    private int index = 0;
    private int hStr = 20;
    private int indexOff = 0;
    private int displayCount = 0;
    private int topPadding = 0;

    private String str[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16",
            "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34",
            "35", "36", "37", "38", "39" };

    public DrawList() {
        displayCount = getHeight() / hStr;

        topPadding = (getHeight() % hStr) / 2;
    }

    public void paint(Graphics g) {
        drawBackground(g);
        int yPosStr = topPadding;
        for (int i = indexOff; i < indexOff + displayCount && i < str.length; i++) {
            if (i == index) {
                drawSelectedLabel(g, 0, yPosStr, str[i], 5, 5);
            } else {
                drawLabel(g, 0, yPosStr, str[i], 5, 5);
            }
            yPosStr += hStr;
        }
        if(isScroolNeed())
            VerticalScrollBar.paintVerticalScrollbar(g, 0, topPadding, g.getClipWidth(), g.getClipHeight() - 2 * topPadding, indexOff * hStr, str.length * hStr);
    }

    private void drawBackground(Graphics g) {
        int width = g.getClipWidth();
        int height = g.getClipHeight();
        g.setColor(255, 255, 255);
        g.fillRect(0, 0, width, height);
    }

    /**
     * 
     * @param g
     * @param x
     * @param y
     * @param label
     * @param padding -
     *            отступ текста
     * @param margin -
     *            отступ от края экрана
     */
    private void drawSelectedLabel(Graphics g, int x, int y, String label, int padding, int margin) {
        x += margin;
        g.setColor(0, 255, 0);
        int width = g.getClipWidth();
        if(isScroolNeed()){
            width -= VerticalScrollBar.SCROLL_WIDTH;
        }
        g.fillRect(x, y,  width - x - margin, hStr);
        g.setColor(255, 255, 255);
        g.drawString(label, x + padding, y, Graphics.TOP | Graphics.LEFT);
    }

    private void drawLabel(Graphics g, int x, int y, String label, int padding, int margin) {
        g.setColor(0x373c3e);
        g.drawString(label, x + margin + padding, y, Graphics.TOP | Graphics.LEFT);
    }

    /*
     * public void drawScroll(Graphics g, int borderClr, int barCrl, int
     * scrollClr, int yPosScrl) { g.setColor(borderClr); g.drawRect(width - 8,
     * 0, width, height); g.setColor(barCrl); g.fillRect(width - 7, 0, width,
     * height); g.setColor(scrollClr); g.fillRect(width - 7, yPosScroll, width,
     * hScroll); }
     */

    public void keyPressed(int keyCode) {
        int action = getGameAction(keyCode); // Заносим в переменную код
        // нажатой
        // кнопки
        switch (action) {
        case Canvas.DOWN:
            moveDown();
            break;
        case Canvas.UP:
            moveUp();
            break;
        case Canvas.FIRE:
            // Tcity.getInstance().showKey(index);
            break;
        }
    }

    protected void keyRepeated(int keyCode) {// если держат нажатой кнопку.
        int action = getGameAction(keyCode);
        switch (action) {
        case Canvas.DOWN:
            moveDown();
            break;
        case Canvas.UP:
            moveUp();
            break;
        }
    }

    public void commandAction(Command c, Displayable d) {

    }

    private void moveUp() {
        if (index == 0) {
            indexOff = str.length - displayCount;
            index = str.length - 1;
        } else {
            if (index == indexOff) {
                indexOff--;
            }
            index--;
        }
        repaint();
    }

    private void moveDown() {
        if (index == str.length - 1) {
            indexOff = 0;
            index = 0;
        } else {
            if (index == indexOff + displayCount - 1) {
                indexOff++;
            }
            index++;
        }
        repaint();
    }

    private boolean isScroolNeed(){
        return str.length > displayCount;
    }
    
    private static class VerticalScrollBar {

        public static final int SCROLL_WIDTH = 6;

        private static final int SCROLL_BORDER_COLOR = 0xff0000;

        private static final int SCROLL_BG_COLOR = 0x0000ff;
        
        private static final int SCROLL_TRACKBAR_COLOR = 0x00ff00;

        public static void paintVerticalScrollbar(Graphics g, int x, int y, int width, int height, int offset, int formHeight) {
            // Make the scrollbar as wide as the rounding diameter.
            int left = x + width - SCROLL_WIDTH;

            // Draw the scrollbar background.
            paintScrollbarBackground(g, left, y, SCROLL_WIDTH, height);

            // Draw an edge to the scrollbar.
            g.setColor(SCROLL_BORDER_COLOR);
            g.drawLine(left, y, left, y + height);

            // Calculate the height of the trackbar.
            int scrollableHeight = formHeight - height;
            double trackbarPercentage = (double) height / (double) formHeight;
            int trackbarHeight = round(height * trackbarPercentage);
            trackbarHeight = Math.max(trackbarHeight, 2 * SCROLL_WIDTH);

            // Calculate the range and location of the trackbar.
            // The scrollbar doesn't actually go from 0% to 100%. The top
            // is actually 1/2 the height of the trackbar from the top of
            // the screen. The bottom is 1/2 the height from the bottom.
            int rangeStart = trackbarHeight / 2;
            int range = height - 2 * rangeStart;

            double offsetPercentage = (double) offset / (double) scrollableHeight;
            int center = y + rangeStart + round(offsetPercentage * range);

            // Draw the trackbar.
            paintTrackbar(g, left, center - rangeStart, SCROLL_WIDTH, trackbarHeight);
        }

        protected static void paintTrackbar(Graphics g, int x, int y, int width, int height) {
            // This code would paint the scrollbar a solid background.
            g.setColor(SCROLL_TRACKBAR_COLOR);
            g.fillRect(x, y, width, height);
        }

        protected static void paintScrollbarBackground(Graphics g, int x, int y, int width, int height) {
            g.setColor(SCROLL_BG_COLOR);
            g.fillRect(x, y, width, height);
        }

        public static int round(double a) {
            return (int) Math.floor(a + 0.5);
        }
    }
}

Автор: Цербер 29.8.2009, 11:32
hamsterKSU  smile  спасибо огромнейшее. имено то что нужно было. в коде пока не разобрался, как время будет буду разбирать всё детально!!!  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)