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 или расширяя его, или что-то подобное), пожалуйста, поместите рабочее решение.
Ответы
Ответ 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, и вы можете создать на нем свое приложение.