2017-12-27 11 views
3

トピック「アクセシビリティサービス」の新機能です。ボタンをクリックするとスクロールでき、電話やその他多くのものをオフにできます。 私のレイアウト(action_bar.xml)は、可動 ので、 は誰がどのようにしてください。ここ可動「アクセシビリティサービス」でActionBar Movableを作成する方法

action_barようにすることです私に言うことができ、私の

action_bar.xml ::

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="horizontal" 
android:layout_width="match_parent" 
android:layout_height="wrap_content"> 

<Button 
    android:id="@+id/power" 
    android:layout_weight="1" 
    android:text="@string/power" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"/> 
<Button 
    android:id="@+id/volume_up" 
    android:text="@string/volume" 
    android:layout_weight="1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"/> 
<Button 
    android:layout_weight="1" 
    android:id="@+id/scroll" 
    android:text="@string/scroll" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"/> 
<Button 
    android:id="@+id/swipe" 
    android:text="@string/swipe" 
    android:layout_weight="1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"/> 

と私はそれを使用しているActionBarService.Java、:ActivityまたはFragmentにいつもViewと同じ規則によって

@Override 
protected void onServiceConnected() { 
    // Create an overlay and display the action bar 
    WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); 
    mLayout = new FrameLayout(this); 
    WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 
    lp.type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; 
    lp.format = PixelFormat.TRANSLUCENT; 
    lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 
    lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 
    lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 
    lp.gravity = Gravity.TOP; 
    LayoutInflater inflater = LayoutInflater.from(this); 
    inflater.inflate(R.layout.action_bar, mLayout); 
    wm.addView(mLayout, lp); 
} 

答えて

0

オーバーレイ作品。オーバーレイを動かすことができるようなandroid:movable="true"のような魔法のプロパティはありません。あなたは自分でそれを作るべきです。ここ は可動Viewの私の例である:

action_bar.xml(ここで私はカスタムDraggableLayoutLinearLayoutを置き換える)

<?xml version="1.0" encoding="utf-8"?> 
<your.package.name.DraggableLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="horizontal" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

    <Button 
     android:id="@+id/power" 
     android:layout_weight="1" 
     android:text="Power" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"/> 
    <Button 
     android:id="@+id/volume_up" 
     android:text="Volume" 
     android:layout_weight="1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"/> 
    <Button 
     android:layout_weight="1" 
     android:id="@+id/scroll" 
     android:text="Scroll" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"/> 
    <Button 
     android:id="@+id/swipe" 
     android:text="Swipe" 
     android:layout_weight="1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"/> 

</your.package.name.DraggableLayout> 

DraggableLayout.class

public class DraggableLayout extends LinearLayout implements View.OnDragListener { 

    GestureDetector mLongClickDetector; 
    Point mPickPoint; 

    public DraggableLayout(Context context) { 
     this(context, null, 0); 
    } 

    public DraggableLayout(Context context, @Nullable AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public DraggableLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
     // When user performs a long press, we begin dragging 
     mLongClickDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { 
      public void onLongPress(MotionEvent e) { 
       mPickPoint = new Point((int) e.getX(), (int) e.getY()); 
       View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(DraggableLayout.this) { 
        @Override 
        public void onProvideShadowMetrics(Point outShadowSize, Point outShadowTouchPoint) { 
         outShadowSize.set(getWidth(), getHeight()); 
         outShadowTouchPoint.set(mPickPoint.x, mPickPoint.y); 
        } 
       }; 
       startDrag(null, shadowBuilder, null, 0); 
      } 
     }); 
    } 

    @Override 
    protected void onAttachedToWindow() { 
     // We should register this class as OnDragListener to parent view to catch DROP events from it 
     ((ViewGroup) getParent()).setOnDragListener(this); 
     super.onAttachedToWindow(); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     //This is also an important point: we must intercept touch events before the child elements (Buttons and so on) 
     return mLongClickDetector.onTouchEvent(ev); 
    } 

    @Override 
    public boolean onDragEvent(DragEvent event) { 
     if (event.getAction() == DragEvent.ACTION_DROP) { 
      // And when user performs drop we change position of view 
      setX(event.getX() - mPickPoint.x); 
      setY(event.getY() - mPickPoint.y); 
      return true; 
     } 
     return false; 
    } 

    @Override 
    public boolean onDrag(View v, DragEvent event) { 
     return onDragEvent(event); 
    } 
} 

ActionBarService。 Java

@Override 
protected void onServiceConnected() { 
    // Create an overlay and display the action bar 
    WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); 
    mLayout = new FrameLayout(this); 
    WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
     WindowManager.LayoutParams.MATCH_PARENT, // Overlay must be full screen otherwise my trick will not work 
     WindowManager.LayoutParams.MATCH_PARENT, 
     WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY, 
     WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, // Allow another windows to receive touch events 
     PixelFormat.TRANSLUCENT); 
    LayoutInflater inflater = LayoutInflater.from(this); 
    inflater.inflate(R.layout.action_bar, mLayout); 
    wm.addView(mLayout, lp); 
} 

これは私には分かりません。

+1

ありがとうございました。 でもまだ問題が起きています。つまり、オーバーレイをフルスクリーンにすると、別のウィンドウがタッチイベントを受信しません。 これをチェックしてこの問題を解決してください –

+1

この回答は非常に良いですが、基本的な問題は無視しています。アクセシビリティサービス内でこれが行われていることは特別な考慮が必要です。 – ChrisCM

+0

@SanjuBaghla:申し訳ありませんが、私はこの瞬間を見逃しました。 @ChrisCMは正しいです、これを実現するのは難しいでしょう。 'Accessibility Serivice'トピック以外のオーバーレイがあるので、別の質問を投稿するか、存在する解決策を探すべきだと思います。 – fishbone

1

@fishboneの回答はほとんどの場合、アクセシビリティサービスのオーバーレイが同じでない小さな部分を除いて正しかったです。確かに、この前提を作ることは物事を単純化しますが、最終的には間違いです。アクセシビリティサービスに固有の重要な考慮事項があり、ほとんどの場合、アクティビティとまったく同じように動作しますが、アクセシビリティサービスがオーバーレイを起動する方法は非常に重要であり、ほとんどのビューが動作する方法、特にタッチイベントを傍受する方法とは異なります。あなたはタッチイベントに非常に注意する必要があります。最終的には、ウィンドウ全体を占有しながらビューに触れることができます。このため、あなたがで遊ぶことができる2つの種類は次のようになります。

TYPE_ACCESSIBILITY_OVERLAY

または

TYPE_APPLICATION_OVERLAY

これら二つは同じように動作しますが、ありません。後者は、実際の視野でタッチイベントを受け取っている場合に役立ちます。

重要な問題は、WindowManagerで使用できるレイアウトパラメータは、タッチイベントを完全に傍受するか、まったく行わないことだけです。ビューのこの部分ではそうすることはできません。他の部分ではできません。あなたのウィンドウを通過したイベントを、あなたが所有していないウィンドウに通過させようとするロジックは、そこには行かないでください。

このように、あなたがしなければならないのは、完全なレイアウトビューではありません。あなたのビューをTouchableとして追加する必要がありますが、実際にオーバーレイする必要がある画面の部分だけを表示するようにしてください。これは明らかに最小限に抑える必要があります(これはタッチイベントがこのビューに向かないためです)。次に、カスタムホールドタッチリスナーを実行し、タッチとドラッグロジックを使用して手動で視点を移動させる必要があります。

タッチ/ドラッグビューは置換のためにのみ使用できます。のように、 "ドラッグモード"を置き換えるボタンがあります。レイアウトをウィンドウに追加する唯一の方法は、レイアウトを削除して、レイアウト以外の小さなバージョン(ツールバーのビューのみ)を追加することです。

ここでは簡単な答えはありません。これは、アクセシビリティAPIが意図するものではありません。 Googleが注目しているアクセシビリティサービスに対する新たな期待は、Google Playストアで削除/許可されていないようなことを行うアクセシビリティサービスをほぼ確実にもたらすことになると警告する義務があります。

関連する問題