android studio Cassetto di navigazione: impostato come sempre aperto sui tablet




toolbar android example (4)

Basandosi sulla risposta di CommonsWare puoi farlo con un paio di aggiustamenti. Il primo è impostare le seguenti tre linee:

drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
drawerLayout.setScrimColor(getResources().getColor(R.color.drawerNoShadow));
isDrawerLocked = true;

Il colore drawerNoShadow può essere solo un colore no-alpha (come 0x00000000). Ti fa un cassetto aperto senza overlay di sfondo.

La seconda cosa che devi fare è regolare il valore padding_left del tuo FrameLayout. A tale scopo è possibile impostare una dimensione per controllarla (0dp per impostazione predefinita) - in questo esempio R.dimen.drawerContentPadding. Avrai anche bisogno di un valore R.dimen.drawerSize che sarà la larghezza del DrawerLayout.

Questo ti permette di controllare il valore padding Left del FrameLayout per chiamare quelle linee.

FrameLayout frameLayout = (FrameLayout)findViewById(R.id.content_frame);
if(frameLayout.getPaddingLeft() == (int)getResources().getDimension(R.dimen.drawerSize) {
    drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
    drawerLayout.setScrimColor(getResources().getColor(R.color.drawerNoShadow));
    isDrawerLocked = true;
}

È quindi possibile includere tutte le funzionalità che non si desidera abilitare in un'istruzione if(!isDrawerLocked) . Questo includerà:

  • drawerLayout.setDrawerListener(drawerToggle);
  • getActionBar().setDisplayHomeAsUpEnabled(true);

Infine, è necessario impostare layout alternativi per le viste con un cassetto statico. Un esempio è:

<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.DrawerLayout

    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- The navigation drawer -->
    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="@dimen/drawerSize"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>

</android.support.v4.widget.DrawerLayout>
<FrameLayout
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="@dimen/drawerContentPadding"/>

La bellezza qui è che puoi controllare tutta la logica impostando file dimen.xml alternativi per i dispositivi che desideri utilizzare come target e l'unica cosa che devi modificare è il valore di drawerContentPadding e offrire i layout modificati.

NOTA: ho finito per usare margin_left invece di padding_left dato che nel nuovo layout si sovrappone al cassetto. Vedi un post più approfondito sulla tecnica su http://derekrwoods.com/2013/09/creating-a-static-navigation-drawer-in-android/

Sto usando il modello del cassetto di navigazione dalla libreria di supporto: http://developer.android.com/training/implementing-navigation/nav-drawer.html

Stavo cercando di impostarlo come sempre aperto sul tablet (come menu laterale)

È possibile qualcosa con l'implementazione attuale o dobbiamo creare un nuovo layout e una nuova struttura con Listview invece di riutilizzare lo stesso codice?


Le risposte precedenti sono buone, ma ho affrontato alcuni problemi mentre li implementavo nel mio progetto, quindi voglio condividere la mia soluzione. Prima di tutto, dobbiamo definire un cassetto personalizzato:

public class MyDrawerLayout extends DrawerLayout {
    private boolean m_disallowIntercept;

    public MyDrawerLayout (Context context) {
        super(context);
    }

    @Override
    public boolean onInterceptTouchEvent(final MotionEvent ev) {
        // as the drawer intercepts all touches when it is opened
        // we need this to let the content beneath the drawer to be touchable
        return !m_disallowIntercept && super.onInterceptTouchEvent(ev);
    }

    @Override
    public void setDrawerLockMode(int lockMode) {
        super.setDrawerLockMode(lockMode);
        // if the drawer is locked, then disallow interception
        m_disallowIntercept = (lockMode == LOCK_MODE_LOCKED_OPEN);
    }
}

Quindi lo inseriamo in un layout di attività di base (senza layout arbitrari da risposte precedenti) come questo:

<MyDrawerLayout 
    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">

    <!--We must define left padding for content-->
    <FrameLayout
        android:id="@+id/content_frame"
        android:paddingStart="@dimen/content_padding"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <android.support.design.widget.NavigationView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:menu="@menu/menu_nav" />

</MyDrawerLayout>

Il riempimento del contenuto qui è 0 dpi con orientamento verticale e circa 300 dpi in orizzontale per Navigatore (calcolato empiricamente). Li definiamo nelle cartelle dei values appropriati:

values/dimens.xml -

<dimen name="content_padding">0dp</dimen>

values-land/dimens.xml -

<dimen name="content_padding">300dp</dimen>

Infine, chiudiamo il cassetto nell'attività:

    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
        mDrawerLayout.setScrimColor(0x00000000); // or Color.TRANSPARENT
        isDrawerLocked = true;
    } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
        mDrawerLayout.setScrimColor(0x99000000); // default shadow
        isDrawerLocked = false;
    }

Non deve essere così complicato dal momento che esiste un metodo pulito e diretto per raggiungerlo.



Passo 1

È sufficiente creare un file di layout alternativo simile a questo per i dispositivi tablet e inserirlo nella layout-w600dp-land .

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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">

    <!--
    NavigationView and the content is placed in a horizontal LinearLayout
    rather than as the direct children of DrawerLayout.
    This makes the NavigationView always visible.
    -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <android.support.design.widget.NavigationView
            android:id="@+id/nav"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:headerLayout="@layout/nav_header_main"
            app:menu="@menu/activity_main_drawer"/>
        <include
            layout="@layout/app_bar_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>

</android.support.v4.widget.DrawerLayout>



Passo 2

Ora non è necessario mostrare il pulsante di attivazione / disattivazione del cassetto quando un elemento fa clic sui dispositivi non tablet.

Passaggio 2.1

Per renderlo possibile, è necessario verificare se il dispositivo è tablet o non tablet in fase di esecuzione.

Aggiungere il seguente contenuto a un nuovo file di risorse valore nella directory dei valori e denominarlo config_ui.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="isDrawerFixed">false</bool>
</resources>

Era per dispositivi non tablet. Per i dispositivi tablet, creane un altro con lo stesso nome e posizionalo in values-w600dp-land .

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="isDrawerFixed">true</bool>
</resources>

Crea un nuovo campo nella classe dell'attività a cui appartiene il cassetto come private boolean isDrawerFixed; e inizializzarlo come isDrawerFixed = getResources().getBoolean(R.bool.isDrawerFixed); .

Passaggio 2.2

Tutto stabilito! Ora possiamo controllare se il dispositivo è un tabled o un non-tablet come if (isDrawerFixed){} .

Ci sarà qualcosa di simile.

ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                    this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
            drawer.addDrawerListener(toggle);
            toggle.syncState();

Per impostare il pulsante di attivazione / disattivazione sulla barra delle azioni. if (!isDrawerFixed) {} un if (!isDrawerFixed) {}

Per chiudere il cassetto quando viene cliccato un oggetto, ci sarà qualcosa di simile.

drawer.closeDrawer(GravityCompat.START);

if (!isDrawerFixed) {} in un if (!isDrawerFixed) {} .





Per riferimento, ho incluso screenshot di un'app in cui ho utilizzato questo metodo.


Sulla base dell'idea che i dispositivi più grandi possano avere file di layout diversi, ho creato il progetto seguente.

https://github.com/jiahaoliuliu/ABSherlockSlides

HighLights :

Poiché il cassetto di un dispositivo di grandi dimensioni è sempre visibile, non è necessario disporre di un cassetto. Invece, un LinearLayout con due elementi con lo stesso nome sarà sufficiente.

<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="horizontal">
     <ListView
             android:id="@+id/listview_drawer"
             android:layout_width="@dimen/drawer_size"
             android:layout_height="match_parent"
             android:layout_gravity="start"
             android:choiceMode="singleChoice"
             android:divider="@android:color/transparent"
             android:dividerHeight="0dp"
             android:background="@color/drawer_background"/>
    <FrameLayout
            android:id="@+id/content_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginLeft="@dimen/drawer_content_padding"
            />
</LinearLayout>

Poiché non abbiamo il cassetto nel file di layout, quando l'app tenta di trovare l'elemento nel layout, restituirà null. Quindi, non è necessario avere un valore booleano extra per vedere quale layout sta usando.

DrawerLayout mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);

if (mDrawerLayout != null) {
    // Set a custom shadow that overlays the main content when the drawer opens
    mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
    // Enable ActionBar app icon to behave as action to toggle nav drawer
    getSupportActionBar().setHomeButtonEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    // ActionBarDrawerToggle ties together the proper interactions
    // between the sliding drawer and the action bar app icon
    mDrawerToggle = new ActionBarDrawerToggle(
            this,
            mDrawerLayout,
            R.drawable.ic_drawer,
            R.string.drawer_open,
            R.string.drawer_close) {

        public void onDrawerClosed(View view) {
            super.onDrawerClosed(view);
        }

        public void onDrawerOpened(View drawerView) {
            // Set the title on the action when drawer open
            getSupportActionBar().setTitle(mDrawerTitle);
            super.onDrawerOpened(drawerView);
        }
    };

    mDrawerLayout.setDrawerListener(mDrawerToggle);
}

Ecco l'esempio per usarlo come booleano.

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    if (mDrawerLayout != null) {
        mDrawerToggle.syncState();
    }
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (mDrawerLayout != null) {
        // Pass any configuration change to the drawer toggles
        mDrawerToggle.onConfigurationChanged(newConfig);
    }
}






navigation-drawer