我的所有片段都通过ActionBarActivity
(mainActivity)进行控制,在mainActivity中实现DrawerLayout
,所有子片段都通过drawerLayout的列表项单击进行推送。我面临的问题是在通过抽屉推送片段之后我想将抽屉图标更改为ToolBar
的后退图标,以便用户可以导航到上一个片段并处理{{1}的回调无论是在同一片段内还是在mainActivity内。
我使用的代码是:
MainActivity.java
android.R.id.home
FirstFragment.java
public class MainActivity extends ActionBarActivity {
private DrawerLayout layoutDrawer;
private ActionBarDrawerToggle drawerToggler;
private Stack<Fragment> stack;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
stack = new Stack<Fragment>();
layoutDrawer = (DrawerLayout) findViewById(R.id.layout_drawer);
drawerToggler = new ActionBarDrawerToggle(this, layoutDrawer, toolbar,
R.string.app_name, R.string.app_name);
layoutDrawer.setDrawerListener(drawerToggler);
setUpDrawerList();
pushFragment(new FirstFragment(), true);
Session.setContext(getApplicationContext());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggler.isDrawerIndicatorEnabled()
&& drawerToggler.onOptionsItemSelected(item))
return true;
switch (item.getItemId()) {
case android.R.id.home:
Toast.makeText(this, "Back from activity", Toast.LENGTH_SHORT)
.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggler.syncState();
}
@Override
public void onBackPressed() {
popFragment();
}
private void setUpDrawerList() {
ListView listView = (ListView) findViewById(R.id.list_drawer);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
Arrays.asList(new String[] { "First Fragment",
"Second Fragment" }));
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
layoutDrawer.closeDrawers();
drawerToggler.setDrawerIndicatorEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
pushFragment(getFragment(position), true);
}
});
}
private Fragment getFragment(int pos) {
switch (pos) {
case 0:
return new FirstFragment();
case 1:
return new SecondFragment();
}
return null;
}
public void pushFragment(Fragment fragment, boolean add) {
FragmentTransaction transation = getSupportFragmentManager()
.beginTransaction();
if (add)
stack.push(fragment);
transation.replace(R.id.layout_content, fragment);
transation.commit();
}
public void popFragment() {
if (!stack.isEmpty()) {
Fragment fragment = stack.elementAt(stack.size() - 2);
stack.pop();
pushFragment(fragment, false);
} else
super.onBackPressed();
drawerToggler.setDrawerIndicatorEnabled(stack.size() == 1);
}
public void clearBackStack() {
stack.clear();
}
}
从上面的代码中我无法获得public class FirstFragment extends Fragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_first, container, false);
}
@Override
public void onResume() {
super.onResume();
ActionBar actionBar = ((ActionBarActivity)getActivity()).getSupportActionBar();
actionBar.setTitle("First Fragment");
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.fragment_menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
Toast.makeText(getActivity(), "Back from fragment", Toast.LENGTH_SHORT).show();
getActivity().onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
}
的回调,并且每次设置主页按钮都不起作用android.R.id.home
actionBar.setDisplayHomeAsUpEnabled(true);
任何帮助都将非常感激。
由于
答案 0 :(得分:32)
在xml中添加工具栏
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment title"/>
</android.support.v7.widget.Toolbar>
然后在Fragment中的onCreateView方法中:
Toolbar toolbar = view.findViewById(R.id.toolbar);
toolbar.setNavigationIcon(R.drawable.ic_back_button);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getActivity().onBackPressed();
}
});
答案 1 :(得分:31)
您必须在主Activity上管理后退按钮操作,因为您的主Activity是您的片段的容器。
首先,将您的所有片段添加到 transaction.addToBackStack(null),现在导航后退按钮调用将进入主要活动。我希望以下代码可以帮助你...
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
您也可以使用
Fragment fragment =fragmentManager.findFragmentByTag(Constant.TAG);
if(fragment!=null) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.remove(fragment).commit();
}
要根据片段中的片段名称更改标题,您可以使用以下代码:
activity.getSupportActionBar().setTitle("Keyword Report Detail");
答案 2 :(得分:23)
我已经掌握了许多解决方案,但没有一个能够完美运行。我使用了项目中可用解决方案的变体,如下所示。请在初始化工具栏和抽屉布局的类中使用此代码。
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
drawerFragment.mDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);// show back button
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
} else {
//show hamburger
drawerFragment.mDrawerToggle.setDrawerIndicatorEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
drawerFragment.mDrawerToggle.syncState();
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
drawerFragment.mDrawerLayout.openDrawer(GravityCompat.START);
}
});
}
}
});
答案 3 :(得分:7)
您可以在片段中使用工具栏,它很容易处理。首先将工具栏添加到片段的布局
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:background="?attr/colorPrimaryDark">
</android.support.v7.widget.Toolbar>
在片段中的onCreateView方法中,您可以像这样处理工具栏。
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
toolbar.setTitle("Title");
toolbar.setNavigationIcon(R.drawable.ic_arrow_back);
IT会将工具栏,标题和后退箭头导航设置为工具栏。您可以将任何图标设置为setNavigationIcon方法。
如果您需要在单击工具栏导航图标时触发任何事件,您可以使用此功能。
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//handle any click event
});
如果您的活动有导航抽屉,则可能需要在单击导航后退按钮时打开它。你可以像这样打开那个抽屉。
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
drawer.openDrawer(Gravity.START);
}
});
完整代码在这里
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//inflate the layout to the fragement
view = inflater.inflate(R.layout.layout_user,container,false);
//initialize the toolbar
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
toolbar.setTitle("Title");
toolbar.setNavigationIcon(R.drawable.ic_arrow_back);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//open navigation drawer when click navigation back button
DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
drawer.openDrawer(Gravity.START);
}
});
return view;
}
答案 4 :(得分:6)
可能是最干净的解决方案:
abstract class NavigationChildFragment : Fragment() {
abstract fun onCreateChildView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View?
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val activity = activity as? MainActivity
activity?.supportActionBar?.setDisplayHomeAsUpEnabled(true)
setHasOptionsMenu(true)
return onCreateChildView(inflater, container, savedInstanceState)
}
override fun onDestroyView() {
val activity = activity as? MainActivity
activity?.supportActionBar?.setDisplayHomeAsUpEnabled(false)
setHasOptionsMenu(false)
super.onDestroyView()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val activity = activity as? MainActivity
return when (item.itemId) {
android.R.id.home -> {
activity?.onBackPressed()
true
}
else -> super.onOptionsItemSelected(item)
}
}
}
只需将此类用作应支持导航的所有片段的父级。
答案 5 :(得分:1)
如果您使用的是 androidx fragment 并且想在单击返回主页按钮时返回 MainActivity,请使用以下代码。
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
....
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
requireActivity().onBackPressed();
}
return super.onOptionsItemSelected(item);
}
答案 6 :(得分:0)
OnToolBar左侧有一个导航图标
Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
toolbar.setTitle(getResources().getString(R.string.title_activity_select_event));
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
通过在左侧使用此导航图标出现并在导航图标上单击它调用父活动。
在清单中我们可以通知系统有关父活动的信息。
<activity
android:name=".CategoryCloudSelectActivity"
android:parentActivityName=".EventSelectionActivity"
android:screenOrientation="portrait" />
答案 7 :(得分:0)
首先,您添加导航后退按钮
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
然后,在您的HostActivity中添加方法。
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()==android.R.id.home)
{
super.onBackPressed();
Toast.makeText(this, "OnBAckPressed Works", Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
尝试一下,绝对可以。
答案 8 :(得分:0)
我发现最简单的解决方案是将其简单地放入片段中:
androidx.appcompat.widget.Toolbar toolbar = getActivity().findViewById(R.id.toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
NavController navController = Navigation.findNavController(getActivity(),
R.id.nav_host_fragment);
navController.navigate(R.id.action_position_to_destination);
}
});
过时了,我想转到另一页,但是您当然可以用您要执行的操作替换onClick方法中的两行。
答案 9 :(得分:0)
(科特琳) 在托管片段的活动中:
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
onBackPressed()
return true
}
}
return super.onOptionsItemSelected(item)
}
我发现,当我向项目添加片段时,它们默认显示操作栏主按钮,要删除/禁用它,请将其放在onViewCreated()中(如果未显示,请使用true启用它):< / p>
val actionBar = this.requireActivity().actionBar
actionBar?.setDisplayHomeAsUpEnabled(false)