如何在使用片段时正确实现""hamburger"到后退"按钮功能



如何移动到新片段并自动将"汉堡包"菜单更改为<-按钮,从而将用户带回上一个菜单?

这似乎是一门晦涩难懂的艺术,无论我读了多少堆积的问题,我尝试了多少"汉堡包"菜单总是打开抽屉。我对某些使用backstacklisteners更改图标的帖子感到困惑,其他帖子使用onoptionselected,而另一些则直接附加单击侦听器。

活动

    public class MainActivity extends AppCompatActivity {
        private ActionBarDrawerToggle drawerToggle;
        private ActionBar actionBar;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            setToolbar();
            // show first fragment here
        }
        private void setToolbar() {
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
            actionBar = getSupportActionBar();
            if (actionBar != null) {
                actionBar.setDisplayHomeAsUpEnabled(true);
                DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer);
                drawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.open, R.string.close);
                drawerToggle.setDrawerIndicatorEnabled(true);
                drawerToggle.syncState();
            }
        }
        @Override
        protected void onPostCreate(Bundle savedInstanceState) {
            super.onPostCreate(savedInstanceState);
            drawerToggle.syncState();
        }
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            drawerToggle.onConfigurationChanged(newConfig);
        }
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.toolbar_menu, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.mnuSettings:
                showSettingsFragment();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
    private void showSettingsFragment() {
        getFragmentManager()
                .beginTransaction()
                .replace(R.id.fragHolder, new SettingsFragment())
                .addToBackStack(null)
                .commit();
    }
}

活动布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
                                        xmlns:app="http://schemas.android.com/apk/res-auto"
                                        xmlns:tools="http://schemas.android.com/tools"
                                        android:id="@+id/drawer"
                                        android:layout_width="match_parent"
                                        android:layout_height="match_parent"
                                        android:fitsSystemWindows="true">
    <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical">
        <android.support.design.widget.AppBarLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content">
            <android.support.v7.widget.Toolbar
                 android:id="@+id/toolbar"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:background="@color/primary"
                 android:minHeight="?attr/actionBarSize"
                 app:popupTheme="@style/Theme.AppCompat.Light"
                 app:theme="@style/Theme.AppCompat">
            </android.support.v7.widget.Toolbar>
            <FrameLayout
                 android:id="@+id/pnlSearch"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_margin="8dp">
                <EditText
                     android:id="@+id/txtSearch"
                     android:layout_width="match_parent"
                     android:layout_height="44dp"
                     android:background="#FAFAFA"
                     android:gravity="center"
                     android:hint="@string/search_hint"
                     android:imeOptions="flagNoExtractUi|actionDone"
                     android:inputType="textNoSuggestions"
                     android:maxLines="1"
                     android:textSize="16sp"/>
                <ImageView
                     android:layout_width="24dp"
                     android:layout_height="24dp"
                     android:layout_gravity="start|center_vertical"
                     android:layout_marginLeft="15dp"
                     android:layout_marginStart="15dp"
                     android:alpha="0.2"
                     android:contentDescription="@string/magnifying_glass_icon"
                     android:src="@drawable/ic_search_black_24dp"/>
                <Button
                     android:id="@+id/btnClear"
                     android:layout_width="24dp"
                     android:layout_height="24dp"
                     android:layout_gravity="end|center_vertical"
                     android:layout_marginEnd="15dp"
                     android:layout_marginRight="15dp"
                     android:alpha="0.5"
                     android:background="@drawable/ic_clear_black_24dp"
                     android:visibility="gone"/>
            </FrameLayout>
        </android.support.design.widget.AppBarLayout>
        <FrameLayout
             android:id="@+id/fragHolder"
             android:layout_width="match_parent"
             android:layout_height="match_parent"/>
    </LinearLayout>
    <android.support.design.widget.NavigationView
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:layout_gravity="start"
         app:headerLayout="@layout/nav_header"
         app:menu="@menu/toolbar_menu"/>
</android.support.v4.widget.DrawerLayout>

设置片段:

public class SettingsFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        addPreferencesFromResource(R.xml.preferences);
    }
    @Override
    public void onResume() {
        super.onResume();
        setToolbarTitle();
    }
    private void setToolbarTitle() {
        ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
        if (actionBar != null) {
            actionBar.setTitle(R.string.settings);
        }
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                getFragmentManager().popBackStack();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}

我正在寻找的是实现这一目标的标准方法,而不是在不了解其真正含义的情况下开始添加点击/后退堆栈侦听器。

在你的活动中写这个函数:

public static void setUpIndicator(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
            getSupportActionBar().setHomeAsUpIndicator(appCompatActivity.getResources().getDrawable(R.drawable.abc_ic_ab_back_mtrl_am_alpha, null));
        else
            getSupportActionBar().setHomeAsUpIndicator(appCompatActivity.getResources().getDrawable(R.drawable.abc_ic_ab_back_mtrl_am_alpha));
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDefaultDisplayHomeAsUpEnabled(true);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
    }

在片段的 onCreate 中调用此函数。

你应该为汉堡包制作动画

调用方法类似

对于动画汉堡包到后退箭头

下面应该在你打电话之前调用添加或替换fragment

animateBurgerToArrow(mDrawerLayout, 1, 0);

在您的活动中

从您的评论中

onOptionsItemSelected永远不会从片段中调用

解决方案!! :在活动的Home onOptionsItemSelected onclick中返回 false

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
             return false; 
        case R.id.mnuSettings:
            animateBurgerToArrow(mDrawerLayout, 1, 0);
            showSettingsFragment();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

将后退箭头动画化为汉堡包

下面应该在你调用popBackStack之前调用

animateBurgerToArrow(mDrawerLayout, 0, 1);

在您的设置片段中

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            animateBurgerToArrow(mDrawerLayout, 0, 1);
            getFragmentManager().popBackStack();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }

方法

private void animateBurgerToArrow(final View drawerView,int start,int end){
    ValueAnimator anim = ValueAnimator.ofFloat(start,end);
    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            float slideOffset = (Float) valueAnimator.getAnimatedValue();
            mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
        }
    });
    anim.setInterpolator(new DecelerateInterpolator());
    // You can change this duration to more closely match that of the default animation.
    anim.setDuration(500);
    anim.start();
}

Mike M.的回答对我帮助很大。一旦我让它工作,我就会慢慢删除代码,直到包装器的大小减半,然后我意识到整个事情都在工作,因为一行:

toggle.setDrawerIndicatorEnabled(false);

此时,我认为最好完全删除包装器并使用以下代码来实现相同的功能。我觉得这是最好的方法。

public class MainActivity extends AppCompatActivity implements FragmentManager.OnBackStackChangedListener
...
private void setToolbar() {
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
        actionBar.setDisplayHomeAsUpEnabled(true);
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer);
        drawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.open, R.string.close);
        drawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
        drawerToggle.syncState();
    }
}
@Override
public void onBackStackChanged() {
    boolean onHomeScreen = getFragmentManager().getBackStackEntryCount() == 0;
    drawerToggle.setDrawerIndicatorEnabled(onHomeScreen);
}

如果我想摆脱细节片段中的标题设置代码,或者添加到后退堆栈的任何片段,我可以这样做:

if (!onHomeScreen) {
    String fragmentTitle = getFragmentManager()
            .findFragmentById(R.id.fragHolder)
            .getClass()
            .getSimpleName()
            .replaceAll("(\p{Ll})(\p{Lu})", "$1 $2")
            .replace("Fragment", "");
    actionBar.setTitle(fragmentTitle);
}

这将使SettingsFragment拥有Settings的头衔,UserDetailsFragment User Details

相关内容

  • 没有找到相关文章

最新更新