HorizontalScrollView重新layout之后自动滑动初始位置问题解决

HorizontalScrollView在重新layout时,有时候会自动滑动到其他位置,这是由于他的后代view获取到焦点导致的,来让我们从代码层面看清这个问题:

 @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childWidth = 0;
        int childMargins = 0;

        if (getChildCount() > 0) {
            childWidth = getChildAt(0).getMeasuredWidth();
            LayoutParams childParams = (LayoutParams) getChildAt(0).getLayoutParams();
            childMargins = childParams.leftMargin + childParams.rightMargin;
        }

        final int available = r - l - getPaddingLeftWithForeground() -
                getPaddingRightWithForeground() - childMargins;

        final boolean forceLeftGravity = (childWidth > available);

        layoutChildren(l, t, r, b, forceLeftGravity);

        mIsLayoutDirty = false;
        // Give a child focus if it needs it
        //就是在这一行,scrollView自动滑动到那个有焦点的view的位置
        if (mChildToScrollTo != null && isViewDescendantOf(mChildToScrollTo, this)) {
            scrollToChild(mChildToScrollTo);
        }
        mChildToScrollTo = null;

        if (!isLaidOut()) {
            final int scrollRange = Math.max(0,
                    childWidth - (r - l - mPaddingLeft - mPaddingRight));
            if (mSavedState != null) {
                mScrollX = isLayoutRtl()
                        ? scrollRange - mSavedState.scrollOffsetFromStart
                        : mSavedState.scrollOffsetFromStart;
                mSavedState = null;
            } else {
                if (isLayoutRtl()) {
                    mScrollX = scrollRange - mScrollX;
                } // mScrollX default value is "0" for LTR
            }
            // Don't forget to clamp
            if (mScrollX > scrollRange) {
                mScrollX = scrollRange;
            } else if (mScrollX < 0) {
                mScrollX = 0;
            }
        }

        // Calling this with the present values causes it to re-claim them
        scrollTo(mScrollX, mScrollY);
    }


而mChildToScrollTo这个view是在requestChildFocus中赋值的,

  @Override
    public void requestChildFocus(View child, View focused) {
        if (!mIsLayoutDirty) {
            scrollToChild(focused);
        } else {
            // The child may not be laid out yet, we can't compute the scroll yet
            mChildToScrollTo = focused;
        }
        super.requestChildFocus(child, focused);
    }


解决办法 :

覆写父类方法onLayout,就可以解决这个问题

  @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int tempScrollX = getScrollX();
        super.onLayout(changed, l, t, r, b);
        final int scrollX = getScrollX();

       
            if (tempScrollX != scrollX) {
                this.scrollTo(tempScrollX, 0);
            }
        
    }





要在 MPAndroidChart 的 HorizontalBarChart 中实现滑动效果,可以通过以下步骤进行: 1. 在 xml 中添加 HorizontalScrollView,将 HorizontalBarChart 放在其中。 ```xml <HorizontalScrollView android:id="@+id/horizontal_scroll_view" android:layout_width="match_parent" android:layout_height="match_parent"> <com.github.mikephil.charting.charts.HorizontalBarChart android:id="@+id/chart" android:layout_width="wrap_content" android:layout_height="match_parent"/> </HorizontalScrollView> ``` 2. 在代码中对 HorizontalBarChart 进行初始化和设置属性,同时设置 HorizontalBarChart 的 X 轴和 Y 轴可以滑动。 ```java HorizontalBarChart chart = (HorizontalBarChart) findViewById(R.id.chart); chart.setTouchEnabled(true); chart.setDragEnabled(true); chart.setScaleEnabled(false); chart.getXAxis().setDrawGridLines(false); chart.getXAxis().setDrawAxisLine(false); chart.getXAxis().setDrawLabels(false); chart.getAxisLeft().setDrawGridLines(false); chart.getAxisLeft().setDrawAxisLine(false); chart.getAxisLeft().setDrawLabels(false); chart.getAxisRight().setDrawGridLines(false); chart.getAxisRight().setDrawAxisLine(false); chart.getAxisRight().setDrawLabels(false); ``` 3. 创建 BarDataSet 对象,并设置其相关属性。 ```java BarDataSet set = new BarDataSet(entries, "Label"); set.setColors(ColorTemplate.VORDIPLOM_COLORS); set.setDrawValues(true); set.setValueTextSize(12f); set.setValueTextColor(Color.BLACK); ``` 4. 创建 BarData 对象,并将 BarDataSet 对象添加到其中。 ```java BarData data = new BarData(set); data.setBarWidth(0.9f); ``` 5. 将 BarData 对象设置到 HorizontalBarChart 中并刷新显示。 ```java chart.setData(data); chart.invalidate(); ``` 通过以上步骤,您可以实现 HorizontalBarChart 的滑动效果。如果您需要对图表进行更多的样式和属性的设置,可以参考 MPAndroidChart 的官方文档进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值