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

Недостаток ящика навигации на Android

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

private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int posicao, long id) {
            setLastPosition(posicao);
            setFragmentList(lastPosition);
            layoutDrawer.closeDrawer(linearDrawer);
        }
    }

    private OnClickListener userOnClick = new OnClickListener() {
        @Override
        public void onClick(View v) {
            layoutDrawer.closeDrawer(linearDrawer);
        }
    };

    private void setFragmentList(int posicao) {

        FragmentManager fragmentManager = getSupportFragmentManager();
        Fragment fragment = new FragmentViagens();

        switch (posicao) {

            case 0:
                fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
                break;
            case 1:
                fragmentManager.beginTransaction().replace(R.id.content_frame, new FragmentPedidos()).commit();
                break;
            case 2:
                fragmentManager.beginTransaction().replace(R.id.content_frame, new FragmentClientes()).commit();
                break;

        }

        navigationAdapter.setChecked(posicao, true);
        setTitleFragments(lastPosition);
        navigationAdapter.resetarCheck();
        layoutDrawer.closeDrawer(linearDrawer);

    }
4b9b3361

Ответ 1

Вы можете сделать это так, чтобы избежать отставания ящика, измените onItemClick:

layoutDrawer.closeDrawer(linearDrawer);
setLastPosition(posicao);
new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            setFragmentList(lastPosition);
        }
    }, 200);

Изменить: предпочтительный способ должен быть установлен DrawerListener на DrawerLayout и установить ваш фрагмент в onDrawerClosed например:

Fragment mFragmentToSet = null;

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    // Handle navigation view item clicks here.
    switch (item.getItemId()) {
        case R.id.nav_home:
            mFragmentToSet = HomeFragment.newInstance(); 
            break;
    }

    mDrawerLayout.closeDrawer(GravityCompat.START);
    return true;
}

mDrawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
        @Override public void onDrawerSlide(View drawerView, float slideOffset) {}
        @Override public void onDrawerOpened(View drawerView) {}
        @Override public void onDrawerStateChanged(int newState) {}

        @Override
        public void onDrawerClosed(View drawerView) {
          //Set your new fragment here
          if (mFragmentToSet != null) {
            getSupportFragmentManager()
                  .beginTransaction()
                  .replace(FRAGMENT_CONTAINER_ID, mFragmentToSet)
                  .commit();
            mFragmentToSet = null;
          }
        }
    });

Ответ 2

Вместо транзакции в onClick, почему бы не сделать это в onDrawerClosed из DrawerLayout.DrawerListener?

Ответ 3

Я думаю, что нашел лучшее решение для этого!

Сначала выполните транзакцию фрагмента следующим образом:

new Handler().post(new Runnable() {
                @Override
                public void run() {
                    getSupportFragmentManager()
                            .beginTransaction()
                            .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
                            .replace(R.id.container, finalMenuFragment)
                            .commit();
                }
            });

Я знаю, что публиковать Runnable выглядит бесполезно, но этот хак позволяет избежать задержки анимации щелчков в ящике, особенно при использовании android:background="?attr/selectableItemBackground" для кликабельного элемента.

И затем вы закрываете ящик в конце функции onResume() вашего фрагмента (в данном примере это "finalMenuFragment") примерно так:

 new Handler().post(new Runnable() {
        public void run() {

            mDrawerLayout.closeDrawer(mFragmentContainerView);
        }
    });

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

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

Я хотел бы получить отзыв об этом, если кто-нибудь протестировал это решение, надеюсь, оно поможет!

Ответ 4

Я просто решил эту проблему только в One-Line

перейдите в свой файл Menifest. В своем ящике Activity просто поставьте HardwareAccelerated true, чтобы предотвратить задержку выдвижного ящика.

<activity
        android:name=".activity.YourDrawerActivity"
        android:configChanges="keyboardHidden|orientation"
        android:screenOrientation="portrait"
        android:hardwareAccelerated="true"  //important 
        android:theme="@style/AppTheme.NoActionBar"
        android:windowSoftInputMode="stateHidden" />

Ответ 5

Если он запаздывает, вы можете запросить аппаратное ускорение. если это необходимо, добавьте это в свою деятельность

 android:hardwareAccelerated="true"

если ваш метод oncreate добавляет этот код

getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

теперь у вас есть аппаратное ускорение в вашей деятельности. источник: https://developer.android.com/guide/topics/graphics/hardware-accel.html

Ответ 6

Попробуйте это. Ящику будет предложено закрыть, используя широковещательную передачу. Это делается для обеспечения того, чтобы активность или фрагмент были загружены 1-м, прежде чем закрывать ящик.

Внутри MainActivity

private BroadcastReceiver xBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Drawer.isDrawerOpen(GravityCompat.START)){
            Drawer.closeDrawers();
        }
    }
};

@Override
protected void onStart() {
    super.onStart();
    IntentFilter filter = new IntentFilter();
    filter.addAction("my.drawer.listener");
    this.registerReceiver(xBroadcastReceiver, filter);
}

@Override
public void onDestroy() {
    super.onDestroy();
    this.unregisterReceiver(xBroadcastReceiver);
}

Внутренняя активность или фрагмент

@Override
public void onStart() {
    super.onStart();
    Intent intent = new Intent();
    intent.setAction("my.drawer.listener");
    getActivity().sendBroadcast(intent);
}

вы можете изменить его на предыдущий процесс из onCreate или onAttach, но это зависит от вашего приложения.

Ответ 7

Смотрите этот для кажущейся правильной комбинации обоих вышеупомянутых ответов.

Ответ 8

Я думаю, что использование задержек для транзакций фрагментов является самым неустойчивым решением.

Тот, кто делает их onDrawerClosed, дает вам небольшую задержку между закрытием и появлением фрагмента.

Я предпочитаю делать транзакции сразу после перехода по ссылке, закрывать ящик с помощью postDelayed 200ms (в runnable check на случай, если он не является нулевым). Фрагмент открывается перед тем, как ящик начнет закрываться.

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

Ответ 9

ну, вы можете задержать на несколько секунд, прежде чем закрыть ящик!

'new Handler().postDelayed(new Runnable() {
       @Override
          public void run() {

               mDrawerLayout.closeDrawer(containerView)
          }
   }, 300)'

работал на меня!