安卓:启用基于canvas的视图滚动条视图、滚动条、canvas

2023-09-12 22:54:18 作者:日光之城

我有一个扩展视图自定义视图。它显示绘制的形状,并且允许用户通过绘制触摸事件通过的OnDraw视图添加到这些附图

I have a custom view that extends View. It displays drawn shapes, and allows the user to add to those drawings via drawing touch events to the View via onDraw.

我已经启用了ScaleGestureDetector,以便用户可以放大一个特定部分和借鉴,但我使用单点触摸画画,他们不能用自己的手指来平移放大视图。

I've enabled the ScaleGestureDetector so that the user can zoom in on a particular section and draw, but as I am using single-touch to draw, they cannot use their finger to pan around the zoomed in View.

我试图使滚动条的显示,这样当它们被放大,滚动条的显示,并可以由用户进行平移...但我根本无法获取要显示滚动条。

I've tried to enable scrollbars for the View such that when they are zoomed in, the scrollbars are displayed and can be used by the user to pan... but I simply can't get the scrollbars to be displayed.

从本质上讲,我做的是调用视图的 awakenScrollBars()方法在我ScaleListener的 onScale()方法,当用户被放大,从而引发无效()。我启用了滚动条通过了XML和编程方式在的onCreate(),但我不能触发滚动条可见。这里是我的XML:

Essentially, what I am doing is to call the View's awakenScrollBars() method in my ScaleListener's onScale() method when the user is zoomed in, which triggers invalidate(). I enabled the scrollbars via both the XML, and programatically in onCreate(), but I can't trigger the scrollbars to be visible. Here is my XML:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.package.name.Canvas
    android:id="@+id/canvas"
    android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:focusable="true"
        android:scrollbars="horizontal|vertical" />
</FrameLayout>

这里是我的onCreate():

And here is my onCreate():

// set scrollbars
setHorizontalScrollBarEnabled(true);
setVerticalScrollBarEnabled(true);

在OnDraw中,我可以验证滚动条通过 isHorizo​​ntalScrollBarEnabled() isVerticalScrollBarEnabled(),并启用 awakenScrollBars() onScale()返回true,但滚动条只是不可见。

In onDraw, I can verify that the scrollbars are enabled via isHorizontalScrollBarEnabled() and isVerticalScrollBarEnabled(), and awakenScrollBars() in onScale() returns true, but the scroll bars are just not visible.

如何进行任何建议?包含在滚动型布局自定义视图似乎不是一个选项,因为这仅支持垂直滚动。

Any suggestions on how to proceed? Containing the custom View in a ScrollView layout doesn't seem to be an option, as that only supports vertical scrolling.

谢谢

推荐答案

如果您正在创建自定义视图编程,那么答案如下: 为了显示自定义视图类滚动条,方法initializeScrollbars应该初始化(在构造函数为例)时被调用。

If you are creating your custom view programatically, then the answer is the following: in order to show scrollbars on custom view class, the method "initializeScrollbars" should be called during initialization (in constructor for example).

该方法采用类型TypedArray的一个很不起眼的参数。为了得到合适的TypedArray情况下,你需要创建自定义设置样式项 - 只是在你的资源\值目录包含以下内容创建文件attrs.xml:

This method takes one very obscure parameter of type TypedArray. To get suitable TypedArray instance you need to create custom styleable entry - just create file "attrs.xml" in your "res\values" directory with the following content:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="View">
    <attr name="android:background"/>
    <attr name="android:clickable"/>
    <attr name="android:contentDescription"/>
    <attr name="android:drawingCacheQuality"/>
    <attr name="android:duplicateParentState"/>
    <attr name="android:fadeScrollbars"/>
    <attr name="android:fadingEdge"/>
    <attr name="android:fadingEdgeLength"/>
    <attr name="android:fitsSystemWindows"/>
    <attr name="android:focusable"/>
    <attr name="android:focusableInTouchMode"/>
    <attr name="android:hapticFeedbackEnabled"/>
    <attr name="android:id"/>
    <attr name="android:isScrollContainer"/>
    <attr name="android:keepScreenOn"/>
    <attr name="android:longClickable"/>
    <attr name="android:minHeight"/>
    <attr name="android:minWidth"/>
    <attr name="android:nextFocusDown"/>
    <attr name="android:nextFocusLeft"/>
    <attr name="android:nextFocusRight"/>
    <attr name="android:nextFocusUp"/>
    <attr name="android:onClick"/>
    <attr name="android:padding"/>
    <attr name="android:paddingBottom"/>
    <attr name="android:paddingLeft"/>
    <attr name="android:paddingRight"/>
    <attr name="android:paddingTop"/>
    <attr name="android:saveEnabled"/>
    <attr name="android:scrollX"/>
    <attr name="android:scrollY"/>
    <attr name="android:scrollbarAlwaysDrawHorizontalTrack"/>
    <attr name="android:scrollbarAlwaysDrawVerticalTrack"/>
    <attr name="android:scrollbarDefaultDelayBeforeFade"/>
    <attr name="android:scrollbarFadeDuration"/>
    <attr name="android:scrollbarSize"/>
    <attr name="android:scrollbarStyle"/>
    <attr name="android:scrollbarThumbHorizontal"/>
    <attr name="android:scrollbarThumbVertical"/>
    <attr name="android:scrollbarTrackHorizontal"/>
    <attr name="android:scrollbarTrackVertical"/>
    <attr name="android:scrollbars"/>
    <attr name="android:soundEffectsEnabled"/>
    <attr name="android:tag"/>
    <attr name="android:visibility"/>
</declare-styleable>
</resources>

另外,完整的滚动条的初始化code是(把它放在你的自定义视图的构造函数):

Also the complete scrollbars initialization code is (place it on your custom view constructor):

setHorizontalScrollBarEnabled(true);
setVerticalScrollBarEnabled(true);

TypedArray a = context.obtainStyledAttributes(R.styleable.View);
initializeScrollbars(a);
a.recycle();

P.S。该解决方案是在Android 2.0测试

P.S. the solution was tested on Android 2.0

我已经忘了补充: 也是computeVerticalScrollRange和computeHorizo​​ntalScrollRange方法应该覆盖。他们应该只返回画布虚宽度和高度。

I have forgot to add: also "computeVerticalScrollRange" and "computeHorizontalScrollRange" methods should be overridden. They should just return imaginary width and height of the canvas.