簡體   English   中英

導航抽屜在打開和關閉時滯后 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_widthandroid: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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM