+-
android-在TextView上调用setText会调用requestLayout()来重置父视图的offsetTopAndBottom位置
我制作了一个布局,其中有两个RelativeLayout,它们充当两个滑块(例如状态栏上的Notification),用户可以上下拖动它们,因此,我必须更改顶部和底部的文本值.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black" >

<RelativeLayout
    android:id="@+id/handle1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white" >

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="40dp"
        android:layout_marginLeft="95dp" >

        <TextView
            android:id="@+id/top_price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="Top text"
            android:textColor="@color/black"
            android:textSize="18sp" />
    </FrameLayout>
</RelativeLayout>

<RelativeLayout
    android:id="@+id/handle2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white" >

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="95dp"
        android:layout_marginTop="40dp" >

        <TextView
            android:id="@+id/bottom_price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="Bottom text"
            android:textColor="@color/black"
            android:textSize="18sp" />
    </FrameLayout>
</RelativeLayout>

在布局期间,两个RelativeLayout彼此叠置,我使用offsetTopAndBottom(int offset)将它们偏移到所示的初始位置

现在,我在两个RelativeLayout上都跟踪MotionEvents,并在ACTION_MOVE事件上调用此方法.

private void offsetHandle(View view, int distanceY) {
    switch(view.getId()) {
    case R.id.handle1:
        mTopHandle.offsetTopAndBottom(distanceY);
        mTopSliderPosition = mTopHandle.getBottom();
        break;

    case R.id.handle2:
        mBottomHandle.offsetTopAndBottom(distanceY);
        mBottomSliderPosition = mBottomHandle.getTop();
        break;
    }
}

这里的mTopHandle和mBottomHandle是两个白色的RelativeLayouts.

注意:我在这里不使用LayoutParams并分别更改顶部和底部边距,因为这会反复调用requestLayout且一点都不平滑.

现在,当父级RelativeLayout在移动事件上发生偏移时,我必须更改顶部文本值(它是top RelativeLayout的子级).但是,当我调用setText时,它将隐式调用requestLayout(),这将重置在两个句柄上完成的所有偏移量.

现在,这是一个大问题,因为到目前为止我已经制作了这些滑块.我尝试覆盖requestLayout()在TextView上不执行任何操作,但是文本没有正确设置,也就是显示随机行为.

即使我从RelativeLayouts中删除了两个文本视图,对requestLayout()的调用也将强制父FrameLayout重传其所有子视图.

有什么建议么 ?

最佳答案
我只是遇到了一个类似的问题,即我偏移了一个View,每次我对周围的RelativeLayout中的其他元素进行更改时,offset都会重置.
我可以通过将 OnGlobalLayoutListener设置为根RelativeLayout的ViewTreeObserver来解决我的问题.然后,在其onGlobalLayout()方法中,为视图重置正确的偏移量.因此,每次布局重新绘制自身时,都会恢复正确的偏移量.

为此,您必须在每次更改视图时保存其总偏移量.因此,在您的情况下,您需要在类中使用一个字段(例如int mTotalOffset),然后将其设置为offsetHandle()中的总偏移量:

private void offsetHandle(View view, int distanceY) {
    mTotalOffset = mTotalOffset + distanceY;
    switch(view.getId()) {
    ...
}

然后,无论您在哪里布局,请添加

rootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {         
    @Override
    public void onGlobalLayout() {
        mHandle1.offsetTopAndBottom(mTotalOffset);
        mHandle2.offsetTopAndBottom(mTotalOffset);
        ...     
    }
});

希望这可以帮助.

干杯!

点击查看更多相关文章

转载注明原文:android-在TextView上调用setText会调用requestLayout()来重置父视图的offsetTopAndBottom位置 - 乐贴网