studio ejemplo desde crear cero android navigation-drawer androidx

ejemplo - navigation view android



DrawerLayout se queda atascado en el golpe (5)

Estoy jugando con DrawerLayout y tengo un problema. Básicamente, a veces cuando deslizo desde el borde de la pantalla, DrawerLayout se atascará hasta que levante mi dedo de la pantalla (vea la captura de pantalla a continuación)

No estoy seguro de lo que está pasando, seguí exactamente el ejemplo de código de Google SDK. ¿Algunas ideas?

Y aquí es lo único que tengo en mi FragmentActivity:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final String[] names = getResources().getStringArray(R.array.nav_names); ArrayAdapter<String> adapter = new ArrayAdapter<String>( getActionBar().getThemedContext(), android.R.layout.simple_list_item_1, names); final DrawerLayout drawer = (DrawerLayout)findViewById(R.id.drawer_layout); final ListView navList = (ListView) findViewById(R.id.drawer); navList.setAdapter(adapter); navList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, final int pos, long id) { drawer.setDrawerListener( new DrawerLayout.SimpleDrawerListener() { @Override public void onDrawerClosed(View drawerView) { super.onDrawerClosed(drawerView); } }); drawer.closeDrawer(navList); } }); }

EDITAR: Estoy agregando una recompensa por esto, ya que este es un problema muy antiguo que existe incluso hoy en día con el último Android-X (muestra disponible here ). Así es como se ve:

Lo he informado a Google ( here y luego otra vez here ), pero no sirvió de nada.

He intentado todas las soluciones existentes aquí en este hilo, y ninguna funcionó. Si alguien tiene una buena solución para esto (mientras aún usa DrawerLayout o lo extiende, o algo similar), ponga una solución que funcione.


Esta característica de 20dp Peek se puede lograr cuando el usuario arrastra el cajón a 20dp y 20dp lo abre. Aquí está el código funcionando bien para mí.

class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener { lateinit var mToggle: ActionBarDrawerToggle lateinit var mDrawerLayout: DrawerLayout override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val toolbar: Toolbar = findViewById(R.id.toolbar) setSupportActionBar(toolbar) val fab: FloatingActionButton = findViewById(R.id.fab) fab.setOnClickListener { view -> Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show() } mDrawerLayout = findViewById(R.id.drawer_layout) val navView: NavigationView = findViewById(R.id.nav_view) mToggle = ActionBarDrawerToggle( this, mDrawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close ) mDrawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener { override fun onDrawerStateChanged(newState: Int) { Log.d("onDrawerStateChanged", "$newState") mToggle.onDrawerStateChanged(newState) } override fun onDrawerSlide(drawerView: View, slideOffset: Float) { if ((slideOffset >= (dpToPx(19.9f)/drawerView.width)) && (slideOffset <= (dpToPx(20.1f)/drawerView.width))){ Log.d("onDrawerSlide", "true") mDrawerLayout.openDrawer(GravityCompat.START) } Log.d("onDrawerSlide", "$slideOffset") mToggle.onDrawerSlide(drawerView,slideOffset) } override fun onDrawerClosed(drawerView: View) { mToggle.onDrawerClosed(drawerView) } override fun onDrawerOpened(drawerView: View) { mToggle.onDrawerOpened(drawerView) } }) mToggle.syncState() navView.setNavigationItemSelectedListener(this) } override fun onBackPressed() { val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout) if (drawerLayout.isDrawerOpen(GravityCompat.START)) { drawerLayout.closeDrawer(GravityCompat.START) } else { super.onBackPressed() } } override fun onCreateOptionsMenu(menu: Menu): Boolean { // Inflate the menu; this adds items to the action bar if it is present. menuInflater.inflate(R.menu.main, menu) return true } override fun onOptionsItemSelected(item: MenuItem): Boolean { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. return when (item.itemId) { R.id.action_settings -> true else -> super.onOptionsItemSelected(item) } } override fun onNavigationItemSelected(item: MenuItem): Boolean { // Handle navigation view item clicks here. when (item.itemId) { R.id.nav_home -> { // Handle the camera action } R.id.nav_gallery -> { } R.id.nav_slideshow -> { } R.id.nav_tools -> { } R.id.nav_share -> { } R.id.nav_send -> { } } val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout) drawerLayout.closeDrawer(GravityCompat.START) return true } fun dpToPx(dps : Float) : Float{ return (dps * Resources.getSystem().displayMetrics.density) }

}


Me las arreglé para solucionar esto implementando este DrawerListener:

drawerLayout.addDrawerListener(new DrawerLayout.SimpleDrawerListener() { @Override public void onDrawerStateChanged(int newState) { super.onDrawerStateChanged(newState); if (drawerLayout.isDrawerVisible(Gravity.LEFT) && !drawerLayout.isDrawerOpen(Gravity.LEFT)) { drawerLayout.closeDrawer(Gravity.LEFT); } } });

Cuando el estado cambia, si el cajón está visible pero no está abierto, significa que está "asomando", así que lo cierro.


Si nos hubiera mostrado su diseño xml, podríamos ver si tiene DrawerLayout como elemento ROOT. Y si los dos niños interiores son el diseño principal y el cajón de navegación.

De acuerdo con Crear un diseño de cajón :

Para agregar un cajón de navegación, declare su interfaz de usuario con un objeto DrawerLayout como la vista raíz de su diseño. Dentro de DrawerLayout, agregue una vista que contenga el contenido principal de la pantalla (su diseño principal cuando el cajón esté oculto) y otra vista que contenga el contenido del cajón de navegación.


Tenga en cuenta que puede sortear esta característica de 20dp peek configurando el atributo seleccionable como verdadero en el FrameLayout dentro del DrawerLayout.

android: clickable = "true"

por ejemplo: http://developer.android.com/training/implementing-navigation/nav-drawer.html

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- The main content view --> <FrameLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" /> <!-- The navigation drawer --> <ListView android:id="@+id/left_drawer" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:background="#111" android:choiceMode="singleChoice" android:divider="@android:color/darker_gray" android:dividerHeight="1dp" /> </android.support.v4.widget.DrawerLayout>


Actualizar

El github está alojado en github .

Para usarlo simplemente necesitas importarlo en graddle. (no funcionó en algún momento antes, supongo que porque jitpack puede necesitar algo de tiempo)

dependencies { implementation ''com.github.mayank1513:SP_DrawerLayout:master-SNAPSHOT''

Asegúrese de agregar también maven {url '' https://jitpack.io ''} en su archivo de nivel de proyecto.

El paso final y ya está listo para añadir su cajón.

añadir xmlns personalizados. Puedes hacerlo agregando esta línea a tu vista de raíz

xmlns:custom="http://schemas.android.com/apk/res-auto"

Ahora crea tu cajón - tienes el control completo de lo que quieres poner dentro

<com.mayank.drawerlayout.Drawer android:id="@+id/drawer" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorPrimary" custom:drawerBackground="@color/colorAccent" custom:drawerWidth="250dp" custom:onRightEdge="false"> <!--Create what you want to put inside your drawer here--> </com.mayank.drawerlayout.Drawer>

Nota:

  • Se resuelve la preocupación planteada en los comentarios que se abre ante un ligero toque.
  • Reducción de la tolerancia al arrastre para cerrar el cajón.

Respuesta original

Puedes usar la clase personalizada DrawerLayout. Por favor encuentre el código fuente y los detalles here .

Esta clase presenta DrawerLayout tanto a la izquierda como a la derecha y, si bien es bastante fácil de usar y personalizar, sin cambios significativos en el código Java.

He usado esto en mis aplicaciones this , this y this . Por si acaso quieres probarlo antes de usarlo.

Los mejores deseos.

Editar He puesto el código en formato de aplicación y módulo aquí: github .

Ahora los atributos personalizados se utilizan para configurar el borde izquierdo o derecho, el fondo y el ancho del cajón. Puede simplemente agregar esto dentro de su diseño XML. Puede crear un cajón dentro de un diseño de marco dedicado y establecer el alfa inicial en 0 o agregar una línea para agregar fondo de sombreado; puede encontrar esto en la aplicación de demostración.

Puede crear listas, scrollView, etc. dentro de este drawerLayout.