Подтвердить что ты не робот

DrawerLayout застрял в салфетки

Я играю с DrawerLayout и столкнулся с проблемой. Обычно, когда я провожу пальцем по краю экрана, DrawerLayout застревает, пока я не уберу палец с экрана (см. Скриншот ниже).

Я не уверен, что случилось, я точно следовал примеру кода из Google SDK. Есть идеи?

Screenshot bug

И вот единственное, что у меня есть в моей 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);
            }
        });

    }

РЕДАКТИРОВАТЬ: я добавляю награду за это, так как это очень старая проблема, которая существует даже сегодня с последним Android-X (образец доступен здесь). Вот как это выглядит:

enter image description here

Я сообщил об этом в Google ( здесь и позже здесь), но это не помогло.

Я перепробовал все существующие решения в этой теме, но ни одно из них не сработало. Если у кого-то есть хороший обходной путь для этого (все еще используя DrawerLayout или расширяя его, или что-то подобное), пожалуйста, поместите рабочее решение.

4b9b3361

Ответ 1

Обратите внимание, что вы можете обойти эту функцию 20dp peek, установив атрибут clickable в true в FrameLayout в DrawerLayout.

Android: кликабельны = "истина"

например: 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>

Ответ 2

Обновить

Хостинг с открытым исходным кодом на GitHub.

Для использования вам просто нужно импортировать его в Graddle. (раньше это не работало, наверное, потому что jitpack может понадобиться некоторое время)

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

Убедитесь, что вы также добавили maven {url ' https://jitpack.io '} в ваш файл проекта уровня graddle.

Последний шаг и вы готовы добавить свой ящик

добавить пользовательские xmlns. Вы можете сделать это, добавив эту строку в ваше корневое представление

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

Теперь создайте свой ящик - вы полностью контролируете, что хотите положить внутрь

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

Замечания:

  • Обеспокоенность, высказанная в комментариях о том, что она открывается при легком прикосновении, решена.
  • уменьшенный допуск сопротивления для закрытия ящика.

Оригинальный ответ

Вы можете использовать Custom DrawerLayout Class. Пожалуйста, найдите исходный код и подробности здесь.

Этот класс имеет как левую, так и правую сторону DrawerLayout, и, если он довольно прост в использовании и настройке без значительных изменений в коде Java.

Я использовал это в моих приложениях это, это и это. На всякий случай, если вы хотите попробовать его перед использованием.

С наилучшими пожеланиями.

Изменить Я поместил код в формате приложения и модуля здесь - https://github.com/mayank1513/SP_DrawerLayout.

Теперь пользовательские атрибуты используются для установки левого или правого края, фона и ширины ящика. Вы можете просто добавить это в свой макет XML. Вы можете создать ящик внутри выделенного фрейма и установить начальную альфа на 0 или добавить строку для добавления теневого фона - вы можете найти это в демонстрационном приложении.

Вы можете создавать списки, scrollView и т.д. Внутри этого BoxLayout.

Ответ 3

Если вы показали нам свой макет xml, мы увидим, есть ли DrawerLayout как элемент ROOT. И являются ли внутренние двое детей основным макетом и навигационным ящиком.

В соответствии с Создать макет ящика:

Чтобы добавить ящик навигации, объявите свой пользовательский интерфейс с объектом DrawerLayout в качестве корневого представления вашего макета. Внутри DrawerLayout добавьте одно представление, содержащее основное содержимое экрана (ваш основной макет, когда ящик скрыт), и другое представление, содержащее содержимое ящика навигации.

Ответ 4

Мне удалось обойти это, выполнив этот 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);
                }
            }
        });

Всякий раз, когда состояние изменяется, если ящик видимый, но не открытый, это означает, что он "подглядывает", поэтому я закрываю его.

Ответ 5

Эта 20dp Peek может быть достигнута, когда пользователь перетаскивает ящик на 20dp чем открывает ящик. Вот код работает нормально для меня.

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)
}

}

Ответ 6

Проверьте этот макет ящика. https://github.com/mayank1513/SP_DrawerLayout

Хотя описания о том, как его использовать, нет, приложение можно загрузить из github, и вы можете создать на нем свое приложение.