DrawerLayout配合WindowManager在service中使用

1.原理理解

抽屉组件依附在WindowManager上,WindowManager大于DrawerLayout,因此DrawerLayout抽出和放回是基于WindowManager已经展示出来的情况。

2.布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <FrameLayout
        android:id="@+id/sliding_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#00000000"
        android:clickable="false"></FrameLayout>

    <com.test.drawerlayouttest.MyDrawLayout
        android:id="@+id/sliding"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <RelativeLayout
            android:id="@+id/sliding_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="left">

            <ImageView
                android:layout_width="736px"
                android:layout_height="776px"
                android:layout_marginTop="152px"
                android:background="#2D3035" />
            
        </RelativeLayout>

    </com.test.drawerlayouttest.MyDrawLayout>

</RelativeLayout>



3.DrawerLayout类

public class MyDrawLayout extends DrawerLayout {
    private int mGravity;

    public MyDrawLayout(@NonNull Context context) {
        super(context);
    }

    public MyDrawLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mGravity = Gravity.LEFT;
    }

    public MyDrawLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mGravity = Gravity.LEFT;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public synchronized void openDrawer() {
        this.openDrawer(mGravity, true);
    }

    public synchronized void closeDrawer(boolean animate) {
        this.closeDrawer(mGravity, animate);
    }

    public boolean isDrawerOpened() {
        return this.isDrawerOpen(mGravity);
    }

}

4.MyWindow类

public class MyWindow {
    private final String TAG = getClass().getSimpleName();
    private Context mContext;
    public static WindowManager mWindowManager;
    public static WindowManager.LayoutParams lp;
    public static MyWindow mWindow;
    public static View mView;
    public static boolean hasMainView;
    public static MyDrawLayout mSliding;

    public synchronized static MyWindow getInstance(Context context) {
        if (mWindow == null) {
            mWindow = new MyWindow(context);
        }
        return mWindow;
    }

    private MyWindow(Context context) {
        Log.d(TAG, "MyWindow init:begin ");
        mContext = context;
        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mView = inflater.inflate(R.layout.windowlayout, null);
        mSliding = (MyDrawLayout) mView.findViewById(R.id.sliding);
        //默认抽屉打开
        mSliding.openDrawer();
        if (mSliding != null) {
            mSliding.setEnabled(true);
            mSliding.addDrawerListener(new DrawerLayout.DrawerListener() {
                @Override
                public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
                }

                @Override
                public void onDrawerOpened(@NonNull View drawerView) {

                }

                @Override
                public void onDrawerClosed(View drawerView) {
                    Log.d(TAG, "onDrawerClosed");
                    //抽屉销毁后,同时关闭mView
                    mWindowManager.removeViewImmediate(mView);
                    hasMainView = false;
                }

                @Override
                public void onDrawerStateChanged(int newState) {

                }
            });
        }
        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        lp = new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                | WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
        lp.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_FULLSCREEN;
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        lp.height = WindowManager.LayoutParams.MATCH_PARENT;
        lp.format = PixelFormat.RGBA_8888;
        Log.d(TAG, "MyWindow init:finish ");
    }


}

5.APP类

public class MyApp extends Application {

    private static Context mAppContext;

    @Override
    public void onCreate() {
        super.onCreate();
        mAppContext = getApplicationContext();
        MyWindow.getInstance(mAppContext);
        Log.d("AvmApp","AvmApp onCreated");
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
    }
}

6.Service类

public class MyService extends Service {

    public MyService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        //显示MyWindow窗口,窗口上包含抽屉组件
        MyWindow.mWindowManager.addView(MyWindow.mView, MyWindow.lp);
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

可能会遇到的错误

img

posted @ 2023-05-16 14:10  阿寳同學Zybao  阅读(46)  评论(0)    收藏  举报