2

私のアプリケーションは、サポート パッケージを利用Fragmentして 2.2 以上の s を実装しています。

ピンチスケーリングイベントを検出するために利用するViewサブクラス(と呼びましょう)があります。これはおなじみの方法で行われます。つまり、 内で、 はを使用して検出器に渡されます。Aは、スケール イベントを受信するために使用されます。ZoomableViewScaleGestureDetectoronTouchEvent()MotionEventmScaleDetector.onTouchEvent(event)SimpleOnScaleGestureListener

このクラスは常にa 内ZoomableViewの唯一のものとして表示されます(それを と呼びましょう)。アプリケーション内での使用例は 2 つあります。ある使用例では、レイアウトは のみで構成され、 を含みます。2 番目の使用例では、別の Fragment と一緒に表示されます。この otherはたまたま を格納していますが、 の使用は問題とは関係ありません (その秒に通常の が含まれているだけでも問題は発生します)。ViewFragmentZoomableFragmentZoomableFragmentZoomableViewZoomableFragmentFragmentMapViewMapViewFragmentView

実際の問題は、Jellybean 以前のデバイス (具体的には Froyo 電話) でテストする場合、ツインレイアウトActivityを示すを使用すると、が機能しないことです。「機能しない」と言うと、デバッガーでs を処理していることがわかりますが、 のメソッドはどれも呼び出されていません。ただし、のみを含むを使用する と、スケール検出は機能します。JellyBean デバイスでアプリケーションを試してみると、ツインの状況はまったく問題なく動作します。つまり、スケール ジェスチャが受信されます。FragmentZoomableFragmentZoomableView ScaleGestureDetectorMotionEventSimpleOnScaleGestureListenerActivityZoomableFragmentFragment

私は周りを検索しましたが、見つけることができる唯一の問題は、人々が実装OnScaleGestureListenerし、 false から false を返すことで動作を妨げている場所onScaleBegin()です。それはここでは私の問題ではありません。

要約すると、 Froyo (Android 2.2)の複数サポートレイアウトScaleGestureDetector内で使用する場合、リスナーを呼び出す必要はありません。ICS までを想定しています。ただし、画面上に 1 つしかない場合、検出器は正常に動作します。さらに、私の 4.1 以降の Jellybean デバイスでは、この問題はまったく存在しません。ViewFragmentFragment

EDIT 1私のツインフラグメントレイアウトでは、ZoomableFragment向きに応じて常に右または下に配置されています。私が行った興味深い観察は、レイアウトを反転してZoomableFragment、縦向きの場合は (下のフラグメントではなく) 上に、横向きの場合は左側にあるようにすると、スケール検出器が機能することです! MotionEvent getRawX()したがって、これは、フラグメントが使用されている場合の/ getX()(および Y の場合も同様) メソッドの結果間の関係と関係があると思われます。しかし、このようにレイアウトを反転すると、ピンチズームが隣接する では機能しませんMapView Fragment! つまり、要約すると、Froyo では、画面の 0,0 にコーナーがあるaに含まれる aScaleGestureDetectorに対してのみ機能しているようです。ViewFragment

EDIT 2ScaleGestureDetector grepcodeのソースを調べた後にたどり着いた簡単な解決策で、この質問に自分で答えました。ICS がgetRawX()/getRawY()を使用している限り、この質問を更新して、最初に考えた Froyo だけでなく、ICS が影響を受けている (と私は信じています) まで述べました。

編集 3Fragmentアプリケーションで s やその他のものと関係があるものを完全に排除する簡単なテストを行いました。私は単純な Google のMapViewサンプル プロジェクトを使用し、レイアウトを単純に変更して、画面の大部分がTextView(重み 0.9) で占められ、小さなMapViewものが下部にわずか 0.1 の重みで収まるようにしました。私のFroyoデバイスでは、ズームをピンチしなくなりました。私のJBデバイスでは、そうです。だから私は気が狂っていないようGestureScaleDetectorで、答えが修正を与えるオンICS以下の問題に遭遇しました(とにかく、確かにFroyoだと思います)。

4

1 に答える 1

3

ScaleGestureDetectorgrepcodeのソースコードを調べると、のJellybeanバージョンはのメソッドを使用しScaleGestureDetectorていないことがわかります。ただし、以前のバージョン(Froyo、ICSなど)、スロップ計算を使用し、その目的で使用します。これは、ターゲットの左上が0,0の近くにない場合、スケール検出器が機能しないことを意味するため、問題が発生する場所です。getRawX()getRawY()MotionEventgetRawX()getRawY()View

右または下に配置されている場合でも、次の範囲内でこれを行うだけでScaleGestureDetector、カスタムで作業できるようになりました。ZoomViewonTouchEvent()

event.setLocation(event.getRawX(), event.getRawY());    
mScaleDetector.onTouchEvent(event);

これにより、とメソッドがまったく同じ値を返すMotionEventように、の内部オフセット変数が調整されます。これにより、スロップ計算が失敗するのを防ぎます。もちろん、スケール検出器は相対値で機能するため、X / Yの絶対値は関係ありません。絶対値に依存するコードがさらにある場合は、次のように復元するために私が行ったことを実行できます。getX/YgetRawX/Y

    float originalY = event.getY();
    float originalX = event.getX();     
    event.setLocation(event.getRawX(), event.getRawY());
    mScaleDetector.onTouchEvent(event);
    event.setLocation(originalX, originalY);

Fragmentさらに、を含むをMapView下または右に配置したい場合は、MapViewとにかくカスタムサブクラスをすでに使用しているので、これを追加しました。

public boolean onTouchEvent(MotionEvent event) {

    // Work around required for ScaleGestureDetector.
    // Before calling the scale detector, perform a work-around that is needed for earlier APIs (I suspect
    // ICS and below, judging from inspection of ScaleGestureDetector) to make the MotionEvent give the 
    // same values for getY / getRawY and getX / getRawX. Wildly different values, caused by the View
    // being nowhere near the screen origin (i.e. the View is on the right or the bottom) means the 
    // detector doesn't work. 

    event.setLocation(event.getRawX() - getLeft(), event.getRawY() - getTop());
    return super.onTouchEvent(event);
}

これで、MapViewどこにFragment配置しても、スケールを適切にピンチします。(ちなみに、この質問には完全にOTですが、誰かが疑問に思っている場合に備えて、StackOverflowで提供されているソリューションをうまく使用することMapViewにしました)。編集:実際には、何かが100%正しくありません:マップはピンチジェスチャの中心を中心にズームしません。ActionBar/通知バーの高さがで補正されていないことに関係していると思います。FragmentLocalActivityManagergetTop()

于 2012-12-10T19:23:58.300 に答える