Виджет чтения книг для Android - PullRequest
1 голос
/ 10 марта 2011

Я работаю над приложением для чтения электронных книг для моей компании; мы используем библиотеку, которая динамически перекомпоновывает макет экранов в пользовательский вид, который я предоставляю.

Мне нужен дисплей, который позволяет пользователю перемещаться от одного экрана к другому, проводя пальцем. Я использую свой собственный подкласс android.widget.Gallery с пользовательским адаптером; getView () адаптера отвечает за обращение к библиотеке и генерацию View для каждой запрашиваемой страницы.

Моя проблема в том, что Gallery ожидает знать общее количество просмотров и иметь индекс для своей текущей позиции в массиве View, но используемая нами библиотека делает невозможным узнать это. Поскольку он выполняет динамическое перекомпонование, общее количество «экранов», составляющих книгу, зависит от размера экрана устройства, текущего размера шрифта, ориентации экрана и т. Д. - заранее узнать это невозможно. Мы также можем перейти к любому месту в книге; когда это происходит, нет способа узнать, сколько «экранов» с самого начала мы находимся (если не считать возврата к началу и продвижения страницы за раз в одно и то же место), и, таким образом, невозможно получить индекс позиции. в галерею.

Мое текущее решение - обрабатывать «концы» Галереи как особые условия в вызове getView () моего адаптера: если он попадает в начало Галереи, но я знаю, что доступно больше страниц, я вынуждаю Галерею изменить ее текущая позиция. Вот пример PageAdapter.getView ():

public View getView(int position, View convertView, ViewGroup parent)
{
    ...
    if( 0 == position ) {
        // The adapter thinks we're at screen 0; verify that we really are
        int i = 0;

        // previousScreen() returns true as long as it could move
        // to another screen; after this loop, i will equal the
        // number of additional screens before our current position
        while( m_book.previousScreen() ) {
            i++;
        }

        PageFlipper pf = (PageFlipper) parent;

        // Remember the last REAL position we dealt with.
        // The +1 to mActualPosition is a hack--for some reason,
        // PageFlipper.leftResync() needs it to work correctly.
        m_lastRequestedPosition = i;
        pf.mActualPosition = i + 1;
        pf.mNeedsLeftResync = true;

        // Do a fixup so we're on the right screen
        while( i-- > 0 ) {
            m_book.nextScreen();
        }
    }
    ...
    m_view = new PageView(m_book);
    return m_view;
}

А вот как это используется в моем подклассе галереи:

public class PageFlipper extends Gallery {
    ...
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        // Triggers a call to PageAdapter.getView()
        super.onScroll(e1, e2, distanceX, distanceY);
        // Adapter getView() may have marked us out of sync
        this.checkLeftResync();
        return true;
    }
    ...
    private void checkLeftResync() {
        if( mNeedsLeftResync ) {
            setSelection(mActualPosition, false);
            mActualPosition = 0;
            mNeedsLeftResync = false;
        }
    }
}

Однако мое решение ненадежно и кажется интуитивно неправильным. Что я действительно хочу, так это то, что выглядит и ощущается как виджет Галерея, но никогда не отслеживает какую-либо позицию; вместо этого он всегда спрашивал бы адаптер, доступно ли новое представление и ведет себя ли он соответствующим образом. Кто-нибудь видел решение такой проблемы?

Кстати, самое близкое, что я видел, это этот проект в приложениях Google , но, похоже, ожидается статический, предварительно выделенный набор представлений.

Заранее спасибо за любые предложения!

...