菜单位于NavigationView的标题下

时间:2019-02-27 05:19:42

标签: android android-drawable navigationview

我将NavigationView的标题从包含文件移到了NavigationView的内容(因为我需要使用合成工具访问小部件),但是菜单项跳到标题下方,如何解决?我尝试禁用fitsSystemWindows,但无法正常工作:

import tkinter as tk
import tkinter.ttk as ttk
import tkinter.messagebox as tkMessageBox

import time
import asyncio

INTERVAL = 0.05 #seconds

class App(ttk.Frame):


    def __init__( self, master, loop, interval=0.05, *args, **kw ):
        super().__init__( master,style='App.TFrame')
        self.master = master
        self.loop = loop
        self._set_style()
        self._create_widgets()


    def _set_style( self ):
        print( '\ndef _set_style( self ):' )
        self.style = ttk.Style()
        self.style.configure( 'App.TFrame',  background='pink')
        self.style.configure( 'sp.TFrame',  background='light green')


    def _create_widgets( self ):
        print( '\ndef _create_widgets( self ):' )
        self.sp_frame = ttk.Frame( self, style='sp.TFrame' )
        self.sp_frame.grid(row=0, column=0)

        #sp_frame widgets
        self.sp_label1 = ttk.Label( self.sp_frame, text='SP(s):')
        self.sp_combox = ttk.Combobox(
            self.sp_frame, state="readonly", values=['a','b','c']  )
        self.sp_combox.bind('<<ComboboxSelected>>', self._connect_esp)
        self.sp_pbar = ttk.Progressbar( self.sp_frame, length=200,
                                        mode='indeterminate',
                                        orient=tk.HORIZONTAL, )
        self.sp_label1.grid( row=0, column=0 )
        self.sp_combox.grid( row=0, column=1, padx=[10,0] )
        self.sp_pbar.grid(   row=1, column=0, columnspan=2, sticky='ew' )


    def _connect_esp( self, event):
        print( '\ndef connect_esp( self, event ):' )

        async def dojob( loop, start_time, duration=1 ):
            print( '\nasync def dojob( loop, end_time):' )
            while True:
                duration = 5 #seconds
                t = loop.time()
                delta = t - start_time
                print( 'wait time = {}'.format( delta ) )
                if delta >= duration:
                    break
                await asyncio.sleep( 1 )
            return True

        async def trackjob( loop ):
            print( '\nasync def trackjob( loop ):' )
            print( 'Job: STARTED' ) 
            start_time = loop.time()
            self.sp_pbar.start( 50 )
            self.sp_pbar.update_idletasks()

            result = await dojob( loop, start_time )
            print( 'result = ', result, type(result) )

            if result:
                self.sp_pbar.stop()
                self.sp_pbar.update_idletasks()
                print( 'Job: ENDED' ) 
                return True
            return False

        try:
            future = self.loop.create_task( trackjob( self.loop ) )
            print( 'future = ', future, type(future))
        except syncio.CancelledError as err:
            print( '_connect_esp(): future is cancelled.' )
            raise
        except asyncio.InvalidStateError as err:
            print( '_connect_esp(): The operation is not allowed in this state..' )
            raise
        except asyncio.TimeoutError as err:
            print( '_connect_esp(): The operation exceeded the given deadline..' )
            raise
        except Exception:
            raise


async def tk_update( root, interval=INTERVAL ):
    print( '\nasync def tk_update( interval ):' )
    try:
        while True:
            root.update() #tk update 
            await asyncio.sleep( interval )
    except tk.TclError as err:
        print( '\nasync def tk_update( self, interval ):' )
        if "application has been destroyed" not in err.args[0]:
            raise
    except asyncio.CancelledError as err:
        print( '\nasync def tk_update( self, interval ):' )
        print('Request to cancel tk_update_task received but may not be done.')
        await asyncio.sleep( interval )
    print( '\nasync def tk_update( interval ):' )
    print( '0 Cancelled = ', root.update_task.cancelled() )
    print('END of def tk_update')


def ask_quit( root, interval=INTERVAL ):
    '''Confirmation to quit application.'''
    print( '\ndef ask_quit( self ):' )
    task=root.update_task
    if tkMessageBox.askokcancel( "Quit","Quit?" ):
        task.cancel()
        print( '1 Cancelled = ', task.cancelled() )
        root.destroy() #Destroy the Tk Window instance.
    print( '2 Cancelled = ', task.cancelled() )


def main():
    loop = asyncio.get_event_loop()

    root = tk.Tk()
    root.geometry('300x100+0+24')
    root.rowconfigure(0, weight=1)
    root.columnconfigure(0, weight=1)
    root.update_task = loop.create_task( tk_update( root ) ) 

    app = App( root, loop )
    app.grid(row=0, column=0, sticky='nsew')
    #root.mainloop() #DO NOT IMPLEMENT; this is replaced by running
                     # tk's update() method in a asyncio loop called loop.
                     # See tk_update() method and root.update_task.

    #Tell Tk window instance what to do before it is destroyed.
    root.protocol("WM_DELETE_WINDOW",
                  lambda :ask_quit( root ) ) 

    try:
        loop.run_forever()
        print('after loop.run_forever()')
    finally:
        loop.run_until_complete( loop.shutdown_asyncgens() )
        loop.close()
    print( 'Is Loop closed = ', loop.isclosed() )


if __name__ == '__main__':
    main()

enter image description here

2 个答案:

答案 0 :(得分:1)

将您的相对布局(标题设计)移动到其他布局文件: header.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".CreateActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginTop="15dp">

        <TextView
            android:id="@+id/lblTitle"
            android:layout_width="fill_parent"
            android:layout_height="match_parent"
            android:layout_gravity="end"
            android:layout_weight="0.9"
            android:text="Title:"
            android:textAlignment="textEnd"
            android:textSize="24sp"
            android:textColor="#000000"/>

        <EditText
            android:id="@+id/lblTitleEdit"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_marginLeft="10dp"
            android:hint="Enter your title here"
            android:layout_weight="0.4"
            android:inputType="text"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginTop="15dp">

        <TextView
            android:id="@+id/lblVenue"
            android:layout_width="fill_parent"
            android:layout_height="match_parent"
            android:layout_gravity="end"
            android:layout_weight="0.9"
            android:text="Venue:"
            android:textAlignment="textEnd"
            android:textSize="24sp"
            android:textColor="#000000"/>

        <EditText
            android:id="@+id/lblVenueEdit"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_marginLeft="10dp"
            android:hint="Enter your venue here"
            android:layout_weight="0.4"
            android:inputType="text"/>

    </LinearLayout>
</LinearLayout>

在抽屉屏幕中:

        <ImageView
            android:id="@+id/profile_image"
            android:visibility="invisible"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_alignParentRight="true"
            android:contentDescription="@string/nav_header_desc"
            app:srcCompat="@mipmap/ic_launcher_round" />

        <TextView
            android:id="@+id/user_email"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@id/profile_image"
            android:layout_toLeftOf="@id/profile_image"
            android:gravity="center"
            android:text="@string/nav_header_subtitle" />

        <TextView
            android:id="@+id/user_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_above="@id/user_email"
            android:layout_alignParentLeft="true"
            android:layout_toLeftOf="@id/profile_image"
            android:fontFamily="@font/uifont"
            android:gravity="center"
            android:paddingTop="@dimen/nav_header_vertical_spacing"
            android:text="@string/nav_header_title"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1" />


    </RelativeLayout>

在您的Java文件中,访问位于标题布局内的标题视图:

<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">


  <include
        layout="@layout/app_bar_home"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/header"
        app:menu="@menu/activity_home_drawer" >


    </com.google.android.material.navigation.NavigationView>

</androidx.drawerlayout.widget.DrawerLayout>

答案 1 :(得分:0)

这是我的布局,可以完美地工作:activity_main:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- AppBarLayout should be here -->
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    </android.support.design.widget.AppBarLayout>

    <!-- add app:layout_behavior="@string/appbar_scrolling_view_behavior" -->

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:openDrawer="start">

        <include
            layout="@layout/app_bar_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <android.support.design.widget.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:fitsSystemWindows="true"
            app:headerLayout="@layout/nav_header_main"
            app:menu="@menu/activity_main_drawer" />
    </android.support.v4.widget.DrawerLayout>
</android.support.design.widget.CoordinatorLayout>

app_bar_main.xml:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".activty.MainActivity">
    <include layout="@layout/content_main"/>
</FrameLayout>