Android 如何创建平滑的导航抽屉
我正在使用导航抽屉的示例。单击左侧抽屉列表视图中的项目时,会显示一些图像,但抽屉布局关闭不顺畅Android 如何创建平滑的导航抽屉,android,navigation-drawer,Android,Navigation Drawer,我正在使用导航抽屉的示例。单击左侧抽屉列表视图中的项目时,会显示一些图像,但抽屉布局关闭不顺畅 单击listview项后,要顺利关闭左侧抽屉布局,我应该在此处执行什么操作 不确定这是否是最佳路径,但我解决这一问题的方法是创建一个挂起的Runnable,它在onDrawerClosed中运行。例如: private void selectItem(final int position) { mPendingRunnable = new Runnable() { @Overr
单击listview项后,要顺利关闭左侧抽屉布局,我应该在此处执行什么操作 不确定这是否是最佳路径,但我解决这一问题的方法是创建一个挂起的Runnable,它在
onDrawerClosed
中运行。例如:
private void selectItem(final int position) {
mPendingRunnable = new Runnable() {
@Override
public void run() {
// update the main content by replacing fragments
Fragment fragment = new PlanetFragment();
Bundle args = new Bundle();
args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
fragment.setArguments(args);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
}
});
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mPlanetTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
@Override
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu();
// If mPendingRunnable is not null, then add to the message queue
if (mPendingRunnable != null) {
mHandler.post(mPendingRunnable);
mPendingRunnable = null;
}
}
完美
private class DrawerItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
mDrawerLayout.closeDrawer(mDrawerList);
mDrawerLayout.postDelayed(new Runnable() {
@Override
public void run() {
selectItem(position);
}
}, 300);
}
}
私有类DrawerItemClickListener实现ListView.OnItemClickListener{
@凌驾
public void onItemClick(AdapterView父对象、视图、最终整型位置、长id){
mDrawerLayout.closeDrawer(mDrawerList);
mDrawerLayout.postDelayed(新的Runnable(){
@凌驾
公开募捐{
选择项目(位置);
}
}, 300);
}
}
我不使用线程,因为我需要在关闭导航菜单后更新UI
下面的代码适合我
我使用fragment作为类的成员变量来更新ui
setFragment()函数用于将片段分配给片段变量
在onDrawerClosed()事件中,我更新ui
mDrawerList.setOnItemClickListener(new ListView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
setFragment(position);
}
});
// for getting fragment
protected void setFragment(int p)
{
fragment = null;
switch (position)
{
case 1:
fragment = new DashboardFragment();
break;
}
if (fragment != null)
{
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(p);
mDrawerLayout.closeDrawer(mDrawerList);
}
}
// on close draw , fragment is loaded on screen
public void onDrawerClosed(View view)
{
getSupportActionBar().setTitle(mTitle);
invalidateOptionsMenu();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame_container, fragment).commit();
}
mDrawerList.setOnItemClickListener(新的ListView.OnItemClickListener()
{
@凌驾
public void onItemClick(AdapterView父对象、视图、整型位置、长id)
{
setFragment(位置);
}
});
//为了得到碎片
受保护的void setFragment(int p)
{
片段=空;
开关(位置)
{
案例1:
fragment=新的仪表板fragment();
打破
}
if(片段!=null)
{
mDrawerList.setItemChecked(位置,true);
mDrawerList.setSelection(p);
mDrawerLayout.closeDrawer(mDrawerList);
}
}
//在接近绘制时,碎片加载到屏幕上
公共无效onDrawerClosed(视图)
{
getSupportActionBar().setTitle(mTitle);
无效操作菜单();
FragmentManager FragmentManager=getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame_容器,fragment.commit();
}
只需使用处理程序在消息队列上发布drawerLayout.closeDrawer(),以最小的延迟解决了我的问题。这里的键是Handler.postdayed()
public void selectItem(int position)
{
switch (position)
{
case 0:
DashboardFragment dashboardFragment = new DashboardFragment();
Bundle args = new Bundle();
args.putInt(dashboardFragment.ARG_SCREEN_NUMBER, position);
dashboardFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragmentLayout, dashboardFragment, TAG_DASHBOARD);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
getSupportFragmentManager().executePendingTransactions();
break;
default:
break;
}
// Highlight the selected item, update the title, and close the drawer
drawerList.setItemChecked(position, true);
setTitle(mScreenTitles[position]);
mPendingRunnable = new Runnable()
{
@Override
public void run()
{
drawerLayout.closeDrawer(GravityCompat.START);
}
};
mHandler.postDelayed(mPendingRunnable,50);
}
请查看我的主要活动,以使用自定义顶栏布局使抽屉布局(打开/关闭)平滑
public class MainActivity extends BaseActivity
implements NavigationView.OnNavigationItemSelectedListener {
Fragment fragment = null;
Class fragmentClass = null;
FrameLayout frameLayout;
TextView topTilte;
DrawerLayout drawer;
NavigationView navigationView;
private boolean isDrawerOpen = false;
@Override
protected void onCreateFinished() {
setContentView(R.layout.activity_main);
drawer = findViewById(R.id.drawer_layout);
navigationView = findViewById(R.id.nav_view);
topTilte = findViewById(R.id.toolbar_title);
fragmentClass = HomeFragment.class;
topTilte.setText(R.string.menu_home);
setFragment();
drawer.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(@NonNull View view, float slideOffset) {
if(slideOffset > .55 && !isDrawerOpen){
onDrawerOpened(view);
isDrawerOpen = true;
} else if(slideOffset < .45 && isDrawerOpen) {
onDrawerClosed(view);
isDrawerOpen = false;
}
}
@Override
public void onDrawerOpened(@NonNull View view) {
}
@Override
public void onDrawerClosed(@NonNull View view) {
}
@Override
public void onDrawerStateChanged(int i) {
}
});
navigationView.setNavigationItemSelectedListener(this);
}
@Override
protected void afterInjection() {
}
public void openMenu(View v) {
drawer.openDrawer(Gravity.LEFT);
}
@Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_home) {
topTilte.setText(R.string.menu_home);
fragmentClass = HomeFragment.class;
setFragment();
} else if (id == R.id.nav_profile) {
}
return true;
}
private void setFragment() {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.container, fragment).commit();
drawer.closeDrawer(GravityCompat.START);
}
}, 200);
}
}
public类MainActivity扩展了BaseActivity
实现NavigationView.OnNavigationItemSelectedListener{
片段=空;
类fragmentClass=null;
框架布局框架布局;
TextView TopTilt;
抽屉式抽屉;
导航视图导航视图;
私有布尔值isDrawerOpen=false;
@凌驾
受保护的void onCreateFinished(){
setContentView(R.layout.activity_main);
抽屉=findViewById(R.id.抽屉布局);
navigationView=findViewById(R.id.nav_视图);
topTilte=findViewById(R.id.toolbar\U标题);
fragmentClass=HomeFragment.class;
toptile.setText(R.string.menu\u home);
setFragment();
drawer.addDrawerListener(新的DrawerLayout.DrawerListener(){
@凌驾
公共void onDrawerSlide(@NonNull视图,float slideOffset){
如果(滑动偏移>0.55&!isDrawerOpen){
onDrawerOpened(视图);
isDrawerOpen=true;
}else if(滑动偏移<.45&&isDrawerOpen){
onDrawerClosed(视图);
isDrawerOpen=false;
}
}
@凌驾
公共无效onDrawerOpened(@NonNull视图){
}
@凌驾
公共无效onDrawerClosed(@NonNull视图){
}
@凌驾
绘图状态更改后的公共无效(int i){
}
});
navigationView.setNavigationItemSelectedListener(此);
}
@凌驾
保护空隙后注(){
}
公共菜单(视图v){
抽屉。打开抽屉(重力。左);
}
@凌驾
public void onBackPressed(){
抽屉布局抽屉=findViewById(R.id.抽屉布局);
if(抽屉isDrawerOpen(重力压缩机启动)){
抽屉。关闭抽屉(重力压缩机启动);
}否则{
super.onBackPressed();
}
}
@SuppressWarnings(“StatementWithEmptyBody”)
@凌驾
公共布尔值onNavigationItemSelected(MenuItem项){
//处理导航视图项单击此处。
int id=item.getItemId();
if(id==R.id.nav_home){
toptile.setText(R.string.menu\u home);
fragmentClass=HomeFragment.class;
setFragment();
}else if(id==R.id.nav_profile){
}
返回true;
}
私有void setFragment(){
最终处理程序=新处理程序();
handler.postDelayed(新的Runnable(){
@凌驾
公开募捐{
试一试{
fragment=(fragment)fragmentClass.newInstance();
}捕获(例外e){
e、 printStackTrace();
}
FragmentManager FragmentManager=getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.container,fragment.commit();
抽屉。关闭抽屉(重力压缩机启动);
}
}, 200);
}
}
@commonware谢谢你的回答,但我在这里应该找到什么?你会找到Romain Guy的一篇博文,其中描述了在你的应用程序中识别jank来源的工具和技术。提问前搜索:@agamov谢谢你的支持,但我不是说如何创建导航抽屉,我是说平滑导航抽屉。我能问一下,你从哪里得到汉德勒?我试图在C#中实现这一点,但我对它的来源感到困惑。@ChaseFlorell只需创建一个成员变量。例如,Handler mHandler=newhandler()代码>我想补充:由于启动应用程序时不会调用onDrawerClosed()
,因此您还应该在onCreate()
末尾将mPendingRunnable
发布到mHandler
。您可以从