![](/img/trans.png)
[英]Navigation drawer lags in Android when opening or closing fragment in Android
[英]Navigation drawer lags when opening and closing android
我試圖讓我的導航抽屜順利運行,因為在打開和關閉抽屜時過渡時會出現卡頓/延遲。 我希望它能完美運行。 有什么幫助嗎?
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final MediaPlayer mp = MediaPlayer.create(this, R.raw.firsteps);
mp.start();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setItemIconTintList(null);
navigationView.setNavigationItemSelectedListener(this);
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.content_frame, new MainFragment()).commit();
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// 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.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
startActivity(new Intent(getApplicationContext(),Testing.class));
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
//final MediaPlayer mp = MediaPlayer.create(this, R.raw.xlophone);
FragmentManager fm = getSupportFragmentManager();
int id = item.getItemId();
if (id == R.id.car_stories) {
fm.beginTransaction().replace(R.id.content_frame,new ChildrensList()).commit();
//mp.start();
} else if (id == R.id.car_places) {
fm.beginTransaction().replace(R.id.content_frame,new ImportFragment()).commit();
//mp.start();
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
文檔: 點擊
嘗試這個:
//使用Handler()。postDelayed
@Override
public boolean onNavigationItemSelected(MenuItem item) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
switch (item.getItemId()) {
case: R.id.example1:
// do something
break;
case: R.id.example2:
// do something
break;
default: // do something
}
}, 200);
drawer.closeDrawer(GravityCompat.START);
return true;
}
以我的拙見,您需要避免每次點擊都稱為“新”。
為了解決這個問題,您可以使用常量值來導航抽屜的android:layout_width
和android:layout_height
屬性,即。
android:layout_width="@dimen/navigation_drawer_width"
android:layout_height="match_parent"
您可能還想對AndroidManifest.xml
活動啟用硬件加速
<activity
android:name=".ui.SomeActivity"
android:hardwareAccelerated="true" />
滯后是由於在同一線程(主線程或UI線程)中發生兩次繁重的操作(片段替換和抽屜動畫)引起的。
解決此問題的一種方法是在抽屜完全關閉后調用碎片更換。 這樣,這兩個操作將不會同時發生。
另外,將片段容器與進度條交叉淡入淡出是一個不錯的設計實現。
在您的Activity
您應該具有以下內容:
override fun onNavigationItemSelected(item: MenuItem): Boolean {
// Show progress bar and hide content container
crossfade(progressBar, container, false)
drawerLayout?.addDrawerListener(object : DrawerLayout.DrawerListener {
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
override fun onDrawerOpened(drawerView: View) {}
override fun onDrawerStateChanged(newState: Int) {}
override fun onDrawerClosed(drawerView: View) {
// This method will be called after drawer animation finishes
// Perform the fragment replacement
when (item.itemId) {
R.id.drawer_item_1 -> {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MyFragmentOne.newInstance())
.addToBackStack(null)
.commit()
}
R.id.drawer_item_2 -> {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MyFragmentTwo.newInstance())
.addToBackStack(null)
.commit()
}
}
// Cross fade back the content container and hide progress bar
crossfade(container, progressBar, false)
// Remove this listener so close by, for example, swiping do not call it again
drawerLayout.removeDrawerListener(this)
}
})
// Closes the drawer, triggering the listener above
drawerLayout.closeDrawer(GravityCompat.START)
return true
}
private fun crossfade(viewIn: View, viewOut: View, animateViewOut: Boolean = true) {
val crossfadeDuration = 200L
// Set the content view to 0% opacity but visible, so that it is visible
// (but fully transparent) during the animation.
viewIn.alpha = 0f
viewIn.visibility = View.VISIBLE
viewIn.bringToFront()
// Animate the in view to 100% opacity, and clear any animation
// listener set on the view.
viewIn.animate()
.alpha(1f)
.setDuration(crossfadeDuration)
.setListener(null)
// Animate the out view to 0% opacity. After the animation ends,
// set its visibility to GONE as an optimization step (it won't
// participate in layout passes, etc.)
viewOut.animate()
.alpha(0f)
.setDuration(if (animateViewOut) crossfadeDuration else 0)
.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
viewOut.visibility = GONE
}
})
}
在您的xml中,您應該具有以下內容:
...
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:openDrawer="start">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/drawer" />
</android.support.v4.widget.DrawerLayout>
....
只需延遲關閉抽屜,即可順利關閉 animation
navigation.setNavigationItemSelectedListener { menuItem ->
// make closing side-menu smooth
Completable.timer(100, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
.subscribe {
drawer.closeDrawer(GravityCompat.START)
}.addTo(disposable)
when(menuItem.itemId){
R.id.sideMenuDashboard ->
navController.navigate(R.id.fragment1)
R.id.sideMenuProfile ->
navController.navigate(R.id.fragment2)
}
true
}
調用抽屜布局.closeDrawers()之后,創建一個新線程
new Thread(new Runnable() {
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(300);
//Here call you fragmentManager
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
當然,您可以根據需要改變MILISECONDS。 對不起我的英語
滯后是由於在同一線程(主線程或UI線程)中發生兩次繁重的操作(片段替換和抽屜動畫)引起的。
在我的情況下,導航標題背景圖片的尺寸很大,因此它可以在高性能設備上使用,但在低性能設備上卻無法使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.