Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
495 views
in Technique[技术] by (71.8m points)

scroll - Android: Enable Scrollbars on Canvas-Based View

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.

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.

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>

And here is my onCreate():

// set scrollbars
setHorizontalScrollBarEnabled(true);
setVerticalScrollBarEnabled(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.

Thanks,

Paul

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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).

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 "resvalues" 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>

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. the solution was tested on Android 2.0

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...