1

ビューを拡張するカスタム ビューがあります。描画された形状を表示し、onDraw を介して View にタッチ イベントを描画することで、ユーザーがこれらの描画に追加できるようにします。

ScaleGestureDetector を有効にして、ユーザーが特定のセクションにズームインして描画できるようにしましたが、シングルタッチを使用して描画しているため、ズームインされたビューを指でパンすることはできません。

ビューのスクロールバーを有効にして、ズームインするとスクロールバーが表示され、ユーザーがパンに使用できるようにしようとしましたが、スクロールバーを表示できません。

基本的に、私がやっていることは、ユーザーがズームインしたときにawakenScrollBars()ScaleListener のメソッドで View のメソッドを呼び出すことです。XML とプログラムの両方でスクロールバーを有効にしましたが、スクロールバーを表示するようにトリガーできません。ここに私のXMLがあります:onScale()invalidate()onCreate()

<?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() があります:

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

onDraw では、 と を介してスクロールバーが有効になっていることを確認できます。inはisHorizontalScrollBarEnabled()trueを返しますが、スクロール バーは表示されません。isVerticalScrollBarEnabled()awakenScrollBars()onScale()

続行する方法について何か提案はありますか? ScrollView レイアウトにカスタム ビューを含めることは、垂直スクロールのみをサポートするため、オプションではないようです。

ありがとう、

ポール

4

4 に答える 4

11

カスタム ビューをプログラムで作成している場合、答えは次のとおりです。カスタム ビュー クラスでスクロールバーを表示するには、初期化中にメソッド「initializeScrollbars」を呼び出す必要があります (コンストラクターなどで)。

このメソッドは、TypedArray 型の非常にあいまいなパラメーターを 1 つ受け取ります。適切な TypedArray インスタンスを取得するには、スタイル設定可能なカスタム エントリを作成する必要があります。「res\values」ディレクトリに次の内容のファイル「attrs.xml」を作成するだけです。

<?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>

また、完全なスクロールバーの初期化コードは次のとおりです (カスタム ビュー コンストラクターに配置します)。

setHorizontalScrollBarEnabled(true);
setVerticalScrollBarEnabled(true);

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

PSソリューションはAndroid 2.0でテストされました

追加するのを忘れていました。「computeVerticalScrollRange」および「computeHorizo​​ntalScrollRange」メソッドもオーバーライドする必要があります。キャンバスの虚数の幅と高さを返すだけです。

于 2011-06-01T09:56:38.360 に答える
3

ViewGroupカスタム(ではなくView)またはそのサブクラスの1つにスクロールバーを追加しようとしている人はsetWillNotDraw(false);、Ruslan Yanchyshynが上記の回答で言ったことを実行することに加えて、コンストラクターに追加してください。

詳細については、この質問と私の回答を参照してください。

于 2011-12-20T22:52:00.613 に答える
3

ご存じのとおり、Android ビューにはスクロール機能があります。

スクロール バーを表示するには、2 つのことを行う必要があります。

  1. ビューのxml宣言に android:scrollbars="horizo​​ntal|vertical" を追加します
  2. View クラスの computeHorizo​​ntalScrollRange/computeVerticalScrollRange メソッドをオーバーライドして、戻り値を computeHorizo​​ntalScrollExtent/computeVerticalScrollExtent メソッドの戻り値よりも大きくします。

その後、scrollTo または scrollBy メソッドを呼び出すと、スクロールバーが自動的に表示されます。

スペルや文法の間違いがあれば、私の下手な英語で申し訳ありません。これを試すことができます:
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 はカスタム ビューであり、次のように実装できます。

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();
    }
}

「pp」という名前の大きなpngを指定し、画像をスクロールするだけで、スクロールバーが表示されます。

于 2013-06-03T02:54:22.050 に答える