2014-08-27 24 views
7

Mam problem z szufladą nawigacji, to jest zbyt wolne, rozwiązanie, którego szukam, to najpierw zamknąć szufladę, a następnie pokazać działanie, ale to nie działa, na pewno ja czegoś mi brakowało.Opóźnienie szuflady nawigacji na Androidzie

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

    } 

Odpowiedz

24

Można zrobić to w ten sposób, aby uniknąć szuflady lag, zmień onItemClick:

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

Edit: Zalecany sposób powinny być ustalone DrawerListener na DrawerLayout i ustawiania fragmentu w onDrawerClosed tak:

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; 
      } 
     } 
    }); 
+0

Dziękuję za pomoc, Jest teraz szybszy, ale wciąż ma pewne opóźnienie, nie powinno się dziać. Jak mogę zamknąć szufladę, a następnie pokazać aktywność? Czy możesz mi w tym pomóc? – AND4011002849

+0

Tak, możesz spróbować zmienić opóźnienie z 200 na 250 lub 300. – Yuraj

+0

http://developer.android.com/training/basics/firstapp/starting-activity.html – Yuraj

18

Zamiast zrobić transakcję w onClick, dlaczego nie zrobić go w onDrawerClosed z DrawerLayout.DrawerListener?

+0

Przykro mi, nie zrozumiałem, jestem bardzo nowy w Android Development – AND4011002849

+0

Możesz to zrobić w ten sposób, ale wolę proste rozwiązanie - postDelay. – Yuraj

+0

Myślę, że ten sposób jest właściwym rozwiązaniem. Opóźnienie zależy od wydajności urządzenia. – uDevel

0

Aby uzyskać pozornie poprawną kombinację obu wyżej wymienionych odpowiedzi, patrz this.

0

Spróbuj tego. Szuflada zostanie poinformowana o zakończeniu korzystania z transmisji. Ma to na celu zapewnienie, że czynność lub fragment będący ładunkiem wykonuje się 1, przed zamknięciem szuflady.

Wewnątrz główną działalność

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

działalności lub fragmentu

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

można go zmienić na wcześniejszym procesie z onCreate lub onAttach, ale to zależy od aplikacji środka.

5

Myślę, że znalazłem najlepsze rozwiązanie!

najpierw zrobić transakcję fragment tak:

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

Wiem, że to wygląda na bezużyteczny aby umieścić Runnable ale tę technikę avoid lag na animację Kliknij na szufladzie zwłaszcza gdy używasz android:background="?attr/selectableItemBackground" dla klikalnego elementu .

A potem zamknąć szufladę NA KONIEC onResume() funkcji swojego fragmentu (w tym przykładzie jest to „finalMenuFragment”) tak:

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

      mDrawerLayout.closeDrawer(mFragmentContainerView); 
     } 
    }); 

Ponownie Wiem, że wydaje się głupi, aby umieścić Możliwe do uruchomienia, ale sprawia, że ​​bliskie animacje są płynne.

W ten sposób szuflada zamknie się tak szybko, jak to możliwe, jeśli chcesz płynne animacje i jeśli fragment nie ma wiele widoków w nim, zamknie się szybciej i nadal bez lagów.

Chciałbym otrzymać opinię na ten temat, jeśli ktoś przetestował to rozwiązanie, mam nadzieję, że pomoże!

+2

to zrobiło dla mnie sztuczki. Dzięki. – RameshJaga

+1

FYI: Handler # postDelayed (Runnable, 0) jest odpowiednikiem Handler # post (Runnable) –

0

Uważam, że używanie opóźnień w transakcjach z fragmentami jest rozwiązaniem najbardziej niestabilnym.

Ten, który robi je naDrawerClosed, powoduje niewielkie opóźnienie między zamknięciem a pojawieniem się fragmentu.

Preferuję dokonywanie transakcji bezpośrednio po kliknięciu nawigacji, zamknij szufladę za pomocą postDelayed 200ms (w przypadku testowania działającego w przypadku, gdy nie jest pusta). Fragment otwiera się tuż przed rozpoczęciem zamykania szuflady.

Nie tylko opóźnienie z kranu do zamknięcia szuflady jest krótsze niż po zamknięciu szuflady i pojawieniu się następnego fragmentu, jest to lepsze UX, ponieważ użytkownik usuwa palec z ekranu - opóźnienie jest mniej widoczne.

2

po prostu rozwiązać ten problem w ciągu zaledwie jednolinijkowy

przejdź do Menifest plik w szuflad wystarczy umieścić HardwareAccelerated prawdziwą aby zapobiec opóźnienie otwarcia szufladę

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

Jeśli opóźni się, możesz poprosić o akcelerację sprzętową. jeśli oczywistego dodać do swojej działalności

android:hardwareAccelerated="true" 

jeśli OnCreate metoda dodać ten kod

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

teraz masz akceleracji sprzętowej w swojej działalności. źródło: https://developer.android.com/guide/topics/graphics/hardware-accel.html

Powiązane problemy