1

我正在为我的公司开发电子书阅读应用程序;我们使用一个库,该库将屏幕动态回流布局到我提供的自定义视图。

我想要一个让用户通过手指滑动从一个屏幕移动到下一个屏幕的显示器。我正在使用由自定义适配器支持的我自己的 android.widget.Gallery 子类;适配器的 getView() 负责与库对话并为每个请求的页面生成一个视图。

我的问题是 Gallery 期望知道 Views 的总数,并为其在 View 数组中的当前位置建立一个索引,但是我们使用的库使我们无法知道这一点。因为它进行动态重排,所以构成书籍的“屏幕”总数取决于设备的屏幕尺寸、当前字体大小、屏幕方向等——无法提前知道。我们也可以跳转到书中的任意位置;当它这样做时,没有办法知道我们从一开始有多少“屏幕”(返回到开始并一次将页面推进到同一个地方),因此无法获得位置索引进入画廊视图。

我当前的解决方案是在我的适配器的 getView() 调用中将 Gallery 的“结束”作为特殊条件处理:如果它到达 Gallery 的开头但我知道有更多页面可用,我会强制 Gallery 更改其当前位置。以下是 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;
}

以下是它在我的 Gallery 子类中的使用方式:

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 应用程序上的这个项目,但它似乎需要一组静态的、预先分配的视图。

在此先感谢您的任何建议!

4

0 回答 0