如何移动到新片段并自动将"汉堡包"菜单更改为<-
按钮,从而将用户带回上一个菜单?
这似乎是一门晦涩难懂的艺术,无论我读了多少堆积的问题,我尝试了多少"汉堡包"菜单总是打开抽屉。我对某些使用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
。