[英]onOptionsItemSelected() method not get called on Fragment
I have an AppCompatActivity and some Fragments. 我有一个AppCompatActivity和一些片段。 The back button on the action bar not works on in
AboutFragment
. 操作栏上的后退按钮在
AboutFragment
中AboutFragment
。
The Activity has no menu inflated, while the Fragment only has a back button in the action bar. 活动没有菜单膨胀,而片段只在操作栏中有一个后退按钮。
Fragment menu is visible, but the back button doesn't react at all when tapped. 片段菜单可见,但后退按钮在点击时根本不作出反应。
The AboutFragment
is getting showed on clicking the info icon from the actionbar. 点击操作
AboutFragment
上的信息图标即可显示AboutFragment。
While clicking on the i
icon, the bellow method works inside MainActivity
. 单击
i
图标时,波纹管方法在MainActivity
。
@Override
public void onInfoSelected() {
abf = (AboutFragment) getSupportFragmentManager().findFragmentByTag(ABOUT_FRAGMENT_TAG);
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right,
android.R.anim.slide_in_left, android.R.anim.slide_out_right);
// ft.hide(pf);
//ft.hide(cf);
ft.hide(tlf);
ft.show(abf);
ft.addToBackStack(null);
ft.commit();
}
then the back button inside AboutFragment doesn't call onOptionsItemSelected()
method inside the Fragment. 那么AboutFragment里面的后退按钮不会调用Fragment中的
onOptionsItemSelected()
方法。
When debugging, I can see that both onCreateOptionsMenu()
for Fragment and Activity get called, but when tapping buttons no onOptionsItemSelected()
gets called, neither from Activity nor from Fragment. 在调试时,我可以看到调用Fragment和Activity的
onCreateOptionsMenu()
,但是当点击按钮时,不会调用onOptionsItemSelected()
,也不会调用来自Fragment的onOptionsItemSelected()
。
its been two days I am searching and googling, nothing worked for me. 我正在搜索和谷歌搜索两天,没有任何对我有用。 any help would be appriciated.
任何帮助都会得到满足。
Activity Java code 活动Java代码
package me.declangao.jiasazsales.app;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import me.declangao.jiasazsales.R;
import me.declangao.jiasazsales.model.Post;
public class MainActivity extends AppCompatActivity implements
RecyclerViewFragment.PostListListener, PostFragment.PostListener,
TabLayoutFragment.TabLayoutListener, SearchResultFragment.SearchResultListener,
CommentFragment.CommentListener,AboutFragment.AboutListener {
private static final String TAG = MainActivity.class.getSimpleName();
public static final String TAB_LAYOUT_FRAGMENT_TAG = "TabLayoutFragment";
public static final String POST_FRAGMENT_TAG = "PostFragment";
public static final String COMMENT_FRAGMENT_TAG = "CommentFragment";
public static final String ABOUT_FRAGMENT_TAG = "AboutFragment";
private FragmentManager fm = null;
private TabLayoutFragment tlf;
private PostFragment pf;
private CommentFragment cf;
private SearchResultFragment srf;
private AboutFragment abf;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
fm = getSupportFragmentManager();
// Setup fragments
tlf = new TabLayoutFragment();
pf = new PostFragment();
cf = new CommentFragment();
srf = new SearchResultFragment();
abf=new AboutFragment();
FragmentTransaction ft = fm.beginTransaction();
ft.add(android.R.id.content, abf, ABOUT_FRAGMENT_TAG);
ft.add(android.R.id.content, pf, POST_FRAGMENT_TAG);
ft.add(android.R.id.content, cf, COMMENT_FRAGMENT_TAG);
ft.add(android.R.id.content, tlf, TAB_LAYOUT_FRAGMENT_TAG);
ft.hide(pf);
ft.hide(cf);
ft.hide(abf);
ft.show(tlf);
ft.commit();
}
/**
* Invoked when a post in the list is selected
*
* @param post Selected Post object
*/
@Override
public void onPostSelected(Post post, boolean isSearch) {
// Find the fragment in order to set it up later
pf = (PostFragment) getSupportFragmentManager().findFragmentByTag(POST_FRAGMENT_TAG);
// Set necessary arguments
Bundle args = new Bundle();
args.putInt("id", post.getId());
args.putString("title", post.getTitle());
args.putString("date", post.getDate());
args.putString("author", post.getAuthor());
args.putString("content", post.getContent());
args.putString("url", post.getUrl());
//args.putString("thumbnailUrl", post.getThumbnailUrl());
args.putString("featuredImage", post.getFeaturedImageUrl());
// Configure PostFragment to display the right post
pf.setUIArguments(args);
// Show the fragment
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right,
android.R.anim.slide_in_left, android.R.anim.slide_out_right);
if (!isSearch) { // Hide TabLayoutFragment if this is not search result
ft.hide(tlf);
} else { // Otherwise, hide the search result, ie. SearchResultFragment.
ft.hide(srf);
}
ft.show(pf);
ft.addToBackStack(null);
ft.commit();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
//do something here like
Log.e("menu Test","rom Main activity");
int backStackEntryCount
=getSupportFragmentManager().getBackStackEntryCount();
if (backStackEntryCount > 0) {
getSupportFragmentManager().popBackStack();
}
return true;
}
return false;
}
/**
* Invoked when a search query is submitted
*
* @param query Selected Post object
*/
@Override
public void onSearchSubmitted(String query) {
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right,
android.R.anim.slide_in_left, android.R.anim.slide_out_right);
// Send query to fragment using factory method
srf = SearchResultFragment.newInstance(query);
ft.add(android.R.id.content, srf);
ft.hide(tlf);
ft.addToBackStack(null);
ft.commit();
}
@Override
public void onInfoSelected() {
abf = (AboutFragment) getSupportFragmentManager().findFragmentByTag(ABOUT_FRAGMENT_TAG);
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right,
android.R.anim.slide_in_left, android.R.anim.slide_out_right);
// ft.hide(pf);
//ft.hide(cf);
ft.hide(tlf);
ft.show(abf);
ft.addToBackStack(null);
ft.commit();
}
/**
* Invoked when comment menu is selected
*
* @param id ID of the article, assigned by WordPress
*/
@Override
public void onCommentSelected(int id) {
cf = (CommentFragment) getSupportFragmentManager().findFragmentByTag(COMMENT_FRAGMENT_TAG);
Bundle args = new Bundle();
args.putInt("id", id);
// Setup CommentFragment to display the right comments page
cf.setUIArguments(args);
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right,
android.R.anim.slide_in_left, android.R.anim.slide_out_right);
ft.hide(pf);
//ft.hide(abf);
ft.show(cf);
ft.addToBackStack(null);
ft.commit();
}
/**
* Intercept back button event, reset ActionBar if necessary
*/
@Override
public void onBackPressed() {
resetActionBarIfApplicable();
super.onBackPressed();
}
/**
* Simulate a back button press when home is selected
*/
@Override
public void onHomePressed() {
resetActionBarIfApplicable();
fm.popBackStack();
}
/**
* Reset TabLayoutFragment's ActionBar if necessary
*/
private void resetActionBarIfApplicable() {
Log.d(TAG, "SearchResultFragment is visible: " + srf.isHidden());
if (srf.isVisible()) {
tlf.resetActionBar();
}
}
// Commented out coz we will let fragments handle their own Options Menus
/*
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
//Log.e("Erroraaa","aaaaa");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.e("menu","activity: action home has clicked");
switch (item.getItemId()){
case android.R.id.home:
onBackPressed();
return false;
}
return super.onOptionsItemSelected(item);
}
*/
}
AboutFragment AboutFragment
package me.declangao.jiasazsales.app;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import me.declangao.jiasazsales.R;
/**
* Fragment to display a Info about Jiasaz company.
* Activities that contain this fragment must implement the
* {@link AboutFragment.AboutListener} interface
* to handle interaction events.
*/
public class AboutFragment extends Fragment {
private AboutListener mListener;
private Toolbar toolbar;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRetainInstance(true);
this.setHasOptionsMenu(true);
}
// @Override
// public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Log.e("Menu:created","Menu");
//
//// super.onCreateOptionsMenu(menu, inflater);
//// menu.clear();
// inflater.inflate(R.menu.menu_post, menu);
// super.onCreateOptionsMenu(menu, inflater);
// }
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.e("Menu:selected","Menu");
if (item.getItemId() == android.R.id.home) {
mListener.onHomePressed();
}
return false;
}
public AboutFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.about_layout, container, false);
toolbar = (Toolbar) rootView.findViewById(R.id.toolbar);
((MainActivity) getActivity()).setSupportActionBar(toolbar);
((MainActivity) getActivity()).getSupportActionBar().setHomeButtonEnabled(true);
((MainActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
((MainActivity) getActivity()).getSupportActionBar().setTitle( "www.Jiasaz.com");
Log.e("Menu: fragment created","onCreaate()");
return rootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (AboutListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement AboutListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface AboutListener {
void onHomePressed();
//void onInfoSelected();
}
}
and this is my AboutFragment xml code 这是我的AboutFragment xml代码
<FrameLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorAccent"
android:layoutDirection="rtl"
android:textDirection="rtl"
tools:context="me.declangao.jiasazsales.app.AboutFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutDirection="rtl"
android:textDirection="rtl"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark"
android:layoutDirection="rtl"
android:textDirection="rtl"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutDirection="rtl"
android:textDirection="rtl"
android:padding="15dp"
android:orientation="vertical">
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp"
android:text="ئهم ئاپه لهلایهن كۆمپانیای جیاساز دروست كراوه"
android:textAppearance="@style/TextAppearance.AppCompat.Light.SearchResult.Title" />
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="214dp"
android:src="@drawable/jiasazlogo" />
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp"
android:text="كۆمپانیای جیاساز بۆ خزمهتگوزاری و چارهسهری تهكنهلۆجی، دروستكردنی وێبسایت و ئاپی مۆبایل و سیستهمی دام و دهزگاكان و ماركێتهكان"
android:textAppearance="@style/TextAppearance.AppCompat.Light.SearchResult.Title" />
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="all"
android:clickable="true"
android:text="@string/link"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
You can set an instance of OnMenuItemClickListener
directly on the Toolbar
. 您可以直接在
Toolbar
上设置OnMenuItemClickListener
的实例。 Remember that you should not use Activity.setSupportActionBar(Toolbar)
. 请记住,您不应该使用
Activity.setSupportActionBar(Toolbar)
。
public class AboutFragment extends Fragment {
// ...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.about_layout, container, false);
toolbar = (Toolbar) rootView.findViewById(R.id.toolbar);
toolbar.inflateMenu(R.menu.menu_about_fragment);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.some_menu) {
// do sth...
return true; // event is handled.
}
return false;
}
});
// ...
}
// ...
}
. 。
To enable back button for a stand alone Toolbar
, set its default icon in xml
file using app:navigationIcon="?attr/homeAsUpIndicator"
: 要为独立
Toolbar
启用后退按钮,请使用app:navigationIcon="?attr/homeAsUpIndicator"
在xml
文件中设置其默认图标:
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark"
android:layoutDirection="rtl"
android:textDirection="rtl"
app:navigationIcon="?attr/homeAsUpIndicator" />
Then set a listener for it 然后为它设置一个监听器
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// back button is pressed
mListener.onHomePressed();
}
});
You described everything properly, those are limitations of the platform. 您正确描述了所有内容,这些都是平台的限制。 To workaround it you need to use onOptionsItemSelected() in MainActivity, insert there code that you already use in another method:
要解决此问题,您需要在MainActivity中使用onOptionsItemSelected(),插入已在另一个方法中使用的代码:
abf = (AboutFragment) getSupportFragmentManager().findFragmentByTag(ABOUT_FRAGMENT_TAG);
then as you have the fragment you can invoke some method from the fragment and possibly get return value to know if the back is handled or not and if something more needs to be done... 然后,当你有片段时,你可以从片段中调用一些方法,并可能获得返回值,以了解是否处理了背面以及是否需要做更多的事情......
You can use onPrepareOptionsMenu(Menu menu)
in you fragment class for listening to you action bar menus... 您可以在片段类中使用
onPrepareOptionsMenu(Menu menu)
来收听操作栏菜单...
@Override
public void onPrepareOptionsMenu(Menu menu)
{
super.onPrepareOptionsMenu(menu);
// to get an item of menu from action bar you can do it like...
// this below line will find an item of menu with id action_search...
MenuItem searchMenuItem = menu.findItem(R.id.action_search);
// like this you can find other menu items
// another example is
MenuItem infoMenuItem = menu.findItem(R.id.action_info);
}
I'm using search view in my fragment class practically for searching... 我在片段类中使用搜索视图实际上用于搜索...
First reason is that you have'nt properly implemented onCreateOptionsMenu()
and onOptionsItemSelected()
@Override methods in Activity
so uncomment that Activity
can also call their respective super
methods. 第一个原因是你没有在
Activity
正确实现onCreateOptionsMenu()
和onOptionsItemSelected()
@ Override方法,因此取消注释Activity
也可以调用它们各自的super
方法。
Second reason is that your onCreateOptionsMenu()
code is commented which needs not
to be. 第二个原因是你的
onCreateOptionsMenu()
代码被评论, not
需要。 Important thing is that super super.onCreateOptionsMenu(menu, inflater);
重要的是超级
super.onCreateOptionsMenu(menu, inflater);
must be called to draw the menu of the Fragment
必须调用以绘制
Fragment
的菜单
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}
And also change change onOptionsItemSelected()
in Fragment
to this: 并且还将
Fragment
onOptionsItemSelected()
更改为:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.e("Menu:selected","Menu");
if (item.getItemId() == android.R.id.home) {
mListener.onHomePressed();
return true;
}else{
return super.onOptionsItemSelected(item);
}
}
And now in Activity
change your onCreateOptionsMenu()
to this: 现在在
Activity
中将onCreateOptionsMenu()
更改为:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
and onOptionsItemSelected()
to this: 和
onOptionsItemSelected()
到这个:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.