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\'v
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 "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>
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.
The method "initializeScrollbars" has been removed from API level 21 onwards.
final TypedArray a = context.obtainStyledAttributes(R.styleable.View);
initializeScrollbars(a);//removed method in Lollipop.
a.recycle();
See. https://developer.android.com/sdk/api_diff/21/changes/android.view.View.html. initializeScrollbars is undefined?
FYI. We cannot use the method initializeScrollbars(a) anymore in Lollipop.
For those of you trying to add scrollbars to a custom ViewGroup (rather than View) or one of its subclasses, make sure you add setWillNotDraw(false); to your constructor in addition to doing what Ruslan Yanchyshyn said in their answer above.
More info can be seen in this question and my answer.
As we all known, the Android view has the ability to scroll.
There are two things to do in order to show the scroll bars.
After that the scrollbars should automatically show when you invoke the scrollTo or scrollBy method.
Sorry for my poor English, if there is any spell or grammar mistakes.
you can try this out:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
tools:context=".MainActivity" >
<com.netease.test.testscroll.ScrollImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFCCCCCC"
android:scrollbars="horizontal|vertical"
android:src="@drawable/pp" />
</LinearLayout>
ScrollImageView is a custom view, you can implement like this:
public class ScrollImageView extends ImageView {
static final String TAG = "ScrollImageView";
private Rect mContentRect = new Rect();
GestureDetector mDetector;
OnGestureListener mListener = new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
Log.i("onScroll", "before:distanceX = " + distanceX
+ ", distanceY = " + distanceY);
scrollBy((int)distanceX, (int)distanceY);
// boolean value = awakenScrollBars();
Log.i("onScroll", "after:current ScrollX=" + getScrollX()
+ ", ScrollY=" + getScrollY());
return true;
}
};
public ScrollImageView(Context context) {
this(context, null);
}
public ScrollImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ScrollImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setScaleType(ScaleType.MATRIX);
mDetector = new GestureDetector(getContext(), mListener);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mDetector.onTouchEvent(event);
return true;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mContentRect.set(getPaddingLeft(), getPaddingTop(), getWidth()
- getPaddingRight(), getHeight() - getPaddingBottom());
}
@Override
protected int computeHorizontalScrollRange() {
return getDrawable().getIntrinsicWidth();
}
@Override
protected int computeHorizontalScrollExtent() {
return mContentRect.width();
}
@Override
protected int computeHorizontalScrollOffset() {
return Math.max(0, getScrollX());
}
private int getScrollRangeX() {
return computeHorizontalScrollRange() - computeHorizontalScrollExtent();
}
@Override
protected int computeVerticalScrollRange() {
return getDrawable().getIntrinsicHeight();
}
@Override
protected int computeVerticalScrollExtent() {
return mContentRect.height();
}
@Override
protected int computeVerticalScrollOffset() {
return Math.max(0, getScrollY());
}
private int getScrollRangeY() {
return computeVerticalScrollRange() - computeVerticalScrollExtent();
}
}
specify a large png named "pp", and just scroll the image, you should see the scrollbars.