【问题标题】:Manage scroll position in scrollview during orientation change在方向更改期间管理滚动视图中的滚动位置
【发布时间】:2014-09-03 15:43:16
【问题描述】:

我有一个实现如下的书架:

我有一个 ScrollView,其中包含一个嵌套的 TableLayout,它充当动态生成的 TableRows 的容器。

   <com.test.bookshelf.CustomScrollView
        android:id="@+id/scrollview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/newHeader"
        android:overScrollMode="never"
        android:fadingEdge="none" >

        <TableLayout
            android:id="@+id/tblLayout"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:padding="0dp" >
        </TableLayout>
    </com.test.bookshelf.CustomScrollView>

自定义 ScrollView 代码:

public class CustomScrollView extends ScrollView {

    private boolean enableScrolling = true;
    private ScrollViewListener scrollViewListener = null;

    public interface OnEndScrollListener {
        public void onEndScroll();
    }

    private OnEndScrollListener mOnEndScrollListener;

    public boolean isEnableScrolling() {
        return enableScrolling;
    }

    public void setEnableScrolling(boolean enableScrolling) {
        this.enableScrolling = enableScrolling;
    }

    public CustomScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public CustomScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomScrollView(Context context) {
        super(context);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        if (isEnableScrolling()) {
            return super.onInterceptTouchEvent(ev);
        } else {
            return false;
        }
    }

    public void setScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    @Override
    protected void onScrollChanged(int x, int y, int oldx, int oldy) {
        super.onScrollChanged(x, y, oldx, oldy);
        if(scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
        }
    }

    public OnEndScrollListener getOnEndScrollListener() {
        return mOnEndScrollListener;
    }

    public void setOnEndScrollListener(OnEndScrollListener mOnEndScrollListener) {
        this.mOnEndScrollListener = mOnEndScrollListener;
    }
}

每个表格行由固定数量的列组成,这些列是根据书籍总数动态计算的。在方向更改时,会重新创建整个布局。

生成书架时,我将总行数存储在一个静态变量中。

当用户点击任何一本书时,它会将他们带到详细信息页面。 我在点击事件期间存储当前滚动位置:

public static currentScrollPosition = 0;

imageviewobj.setOnClickListener(new View.OnClickListener() 
{
   @Override
   public void onClick(View v) 
   {
      currentScrollPosition = scrollviewObj.getScrollY();

....

当用户返回此屏幕时,我使用此值恢复滚动位置。

scrollviewObj.post(new Runnable() {
        @Override
        public void run() {
            scrollviewObj.scrollTo(0, currentScrollPosition);
        } 
    });

但是如何计算方向变化期间的等效滚动位置? 由于行数和列数不同,Book 在纵向模式下的垂直偏移(滚动位置)与横向模式不同。

对此有什么想法吗?

【问题讨论】:

    标签: android scrollview android-tablelayout android-scrollview android-orientation


    【解决方案1】:

    您应该只保留在您的案例中看到(或点击)的行的索引,并通过onSaveInstanceState/onCreate 保留此信息。

    之后,当旋转发生时,在您的新实例onCreate 中,计算您必须滚动的垂直偏移量。

    为此,您需要将全局树布局观察器添加到列表单元格以获取它们的高度(如果它不固定)。然后你可以要求滚动。

    此方法允许您通过跟踪列表中的索引来独立于您的视图。然后它将以纵向到横向以及横向到纵向的方式工作。

    【讨论】:

    • 如何获取“被看到”的行的索引。 ListView 有一个 getFirstVisiblePosition() 方法。 ScrollView有类似的吗?
    • getScrollY() 将返回垂直偏移量。但是如何获取对应的行索引/索引呢?
    • 你需要能够得到一行的高度,然后除。要获得高度,请阅读我的答案并使用 GlobalTreeObserver
    • 只有一条评论...这种方法效果很好,但它会使方向变化变慢,在 Nexus 5 上效果很好,但在其他智能手机上效果不佳。有什么建议可以微调吗?
    • 取决于你如何实现它。它应该很快。你有没有想过在得到高度后移除布局观察者?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-12
    • 2020-12-21
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多