2

ウィンドウの位置を制御するにはどうすればよいですか?

SurfaceViewwithWindowManager.LayoutParamWindowManager;に追加しました。xそして、 のandyを;に変更しようとしWindowManager.LayoutParamsました。Threadしかし、私は間違っているだけThread Exceptionです。

SurfaceViewDemoActivity .java

public class SurfaceViewDemoActivity extends Activity {
    private MySurfaceView mySurfaceView;
    private FloatingWindow floatingWindow;
    private int x = 0;
    private Thread t;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);           
        int imgId = R.drawable.bubble;
        mySurfaceView = new MySurfaceView(this, imgId);
        floatingWindow = new FloatingWindow(this, mySurfaceView, 0, 0);        

        t = new Thread(new Runnable(){
                public void run() {
                    while (true) {
                        if (x > 150) x = 0;
                        //The problem is here.
                        floatingWindow.update(mySurfaceView, x, x);
                        x++;
                    }   
                }
        });     
         t.start();
    }
}

FloatingWindow .java

public class FloatingWindow {
    private WindowManager windowManager;  
    private WindowManager.LayoutParams layoutParams; 
    private boolean hasViewAdded = false;

    public final void update (View view, int coordX, int coordY) {
        update(coordX, coordY);
        update(view);
    }    

    public final void update (View view) {
        if ( isViewAdded() == true ) {
            windowManager.updateViewLayout(view, layoutParams);
        } else {    
            windowManager.addView(view, layoutParams);
            setViewAdded(true); 
        }
    }

    private final void update (int coordX, int coordY) {
        this.layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
        this.layoutParams.x = coordX;
        this.layoutParams.y = coordY;       
    }

    private void updateSize (View view) {
        int width = view.getWidth();
        int height = view.getHeight();
        this.layoutParams.width = width;  
        this.layoutParams.height = height;
    } 

    public FloatingWindow (Context context, View view, int coordX, int coordY) {
        init(context);
        updateSize(view);
        update(view, coordX, coordY);
    }   

    private void init(Context context) {
        this.windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        this.layoutParams = new WindowManager.LayoutParams();
        this.layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;  
        this.layoutParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE;
        this.layoutParams.format = PixelFormat.TRANSPARENT;
    }   

    protected boolean isViewAdded () {
        return this.hasViewAdded;
    }

    protected void setViewAdded (boolean hasViewAdded) {
        this.hasViewAdded = hasViewAdded;
    }
}

AndroidManifest.xml

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

ログ.txt

E/Trace(5041):      error opening trace file: No such file or directory (2)
W/Trace(5041):      Unexpected value from nativeGetEnabledTags: 0

I/Choreographer(5041):  Skipped 128 frames!  The application may be doing too much work on its main thread.

W/Trace(5041):      Unexpected value from nativeGetEnabledTags: 0
W/dalvikvm(5041):   threadid=11: thread exiting with uncaught exception (group=0xb5cff908)

E/AndroidRuntime(5041): FATAL EXCEPTION: Thread-252
E/AndroidRuntime(5041): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

E/AndroidRuntime(5041):     at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4746)
E/AndroidRuntime(5041):     at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:823)

E/AndroidRuntime(5041):     at android.view.View.requestLayout(View.java:15468)
E/AndroidRuntime(5041):     at android.view.View.setLayoutParams(View.java:10022)
E/AndroidRuntime(5041):     at android.view.WindowManagerGlobal.updateViewLayout(WindowManagerGlobal.java:269)

E/AndroidRuntime(5041):     at android.view.WindowManagerImpl.updateViewLayout(WindowManagerImpl.java:74)
E/AndroidRuntime(5041):     at com.givemepass.surfaceview.FloatingWindow.update(FloatingWindow.java:27)
E/AndroidRuntime(5041):     at com.givemepass.surfaceview.FloatingWindow.update(FloatingWindow.java:18)

E/AndroidRuntime(5041):     at com.givemepass.surfaceview.SurfaceViewDemoActivity$1.run(SurfaceViewDemoActivity.java:33)
E/AndroidRuntime(5041):     at java.lang.Thread.run(Thread.java:856)

W/Trace(5041):      Unexpected value from nativeGetEnabledTags: 0
D/gralloc_goldfish(5041): Emulator without GPU emulation detected.
W/Trace(5041):      Unexpected value from nativeGetEnabledTags: 0

I/Choreographer(5041):  Skipped 671 frames!  The application may be doing too much work on its main thread.
W/Trace(5041):      Unexpected value from nativeGetEnabledTags: 0

W/Trace(5041):      Unexpected value from nativeGetEnabledTags: 0
A/libc(5041):       Fatal signal 11 (SIGSEGV) at 0xae3e1000 (code=1), thread 5057 (Thread-253)
I/Process(5041):    Sending signal. PID: 5041 SIG: 9

4

2 に答える 2

0

「SurfaceView」を「WindowManager」に追加した後、WindowManager.LayoutParams の「x」と「y」を変更するだけです。

私のように「スレッド例外」とメッセージ (「ビュー階層を作成した元のスレッドのみがそのビューにアクセスできます」) を持っている場合は、「Android 開発者ブログ」で痛みのないスレッド化を読むことができます。

Thread t = new Thread(new Runnable(){
        public void run() {
            while (true) {
                if ( x > 150 ) x = 0;
                runOnUiThread(new Runnable() {
                    public void run() {
                        //Update the UI here.
                        floatingWindow.update(mySurfaceView, x, x);
                    }
                });
                x++; 
            }   
        }
    });

于 2013-02-24T08:14:59.223 に答える
0

Activity.runOnUiThread(Runnable action) を使用するか、UI スレッドで Handler を作成し、メッセージを介して座標を渡す必要があります。Android では、GUI フレームワークはスレッドセーフではありません。そのため、Android の開発者は、誰かが別のスレッドから UI を操作しようとした場合に、間違いについて全員に通知することにしました。

于 2013-07-02T18:29:15.237 に答える