setDisplayHomeAsUpEnabled(true) 打开选项菜单

Posted

技术标签:

【中文标题】setDisplayHomeAsUpEnabled(true) 打开选项菜单【英文标题】:setDisplayHomeAsUpEnabled(true) opens Options Menu 【发布时间】:2018-12-25 13:50:19 【问题描述】:

我有一个片段MyProfile (包含有关已登录用户的信息) 我希望片段Team 使用它(包含有关所有团队成员的信息)。当我将MyProfile 用于Team 片段时,我需要up 按钮。我阅读了文档guide,从up navigation inside fragment 尝试了所有内容,并在this example 上停止了。

在我的例子中,问题不是回到前一个片段,而是打开选项菜单。

MainActivity

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) 
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    int id = item.getItemId();

    if (id == R.id.nav_team) 
        fragmentTransaction.replace(R.id.container, new TeamFragment())
                .addToBackStack(null)
                .commit();
    

团队片段

public class TeamFragment extends Fragment 

private String LOG_TAG = getClass().getSimpleName();
private ListView teamList;
private android.support.v4.app.FragmentManager fragmentManager;

public TeamFragment() 
    // Required empty public constructor


@Override
public void onCreate(@Nullable Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    fragmentManager = getFragmentManager();


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 
    ((MainActivity) getActivity()).setActionBarTitle("Team");

    View rootView = inflater.inflate(R.layout.fragment_announcement, container, false);
    final SwipeRefreshLayout swipeToUpdate = rootView.findViewById(R.id.swiperefresh);

    teamList = rootView.findViewById(R.id.announcements_list);
    getTeamFromAPI(Contract.TEAM);

    teamList.setOnItemClickListener(new AdapterView.OnItemClickListener() 
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
            ImageView avatar = view.findViewById(R.id.team_img);
            TextView fullname = view.findViewById(R.id.team_fullname);
            TextView jobtitle = view.findViewById(R.id.team_jobtitle);
            TextView email = view.findViewById(R.id.team_email);

            avatar.buildDrawingCache();
            Bitmap bitmap = avatar.getDrawingCache();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
            byte[] bAvatar = baos.toByteArray();
             //when team member i replace here current fragment with profile fragment
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            Fragment fragment = ProfileFragment.newInstance(String.valueOf(fullname.getText()),
                    String.valueOf(jobtitle.getText()),
                    String.valueOf(email.getText()), bAvatar);
            fragmentTransaction.replace(R.id.container, fragment, "MEMBER_PROFILE")
                    .addToBackStack(null)
                    .commit();
        
    );
    return rootView;


private void getTeamFromAPI(String url) 
    //fetch team members from database

我尝试返回 TeamFragment 的地方

ProfileFragment

    public class ProfileFragment extends Fragment

private String LOG_TAG = getClass().getSimpleName();
private String mFullname;
private String mTitle;
private String mEmail;
private byte[] mAvatar;

private android.support.v4.app.FragmentManager fragmentManager;
private ActionBar actionBar;
private View rootView;

public ProfileFragment() 
    // Required empty public constructor


public static ProfileFragment newInstance(String name, String title, String email, byte[] avatar) 
    Bundle bundle = new Bundle();
    bundle.putString("fullname", name);
    bundle.putString("title", title);
    bundle.putString("email",email);
    bundle.putByteArray("avatar", avatar);

    ProfileFragment fragment = new ProfileFragment();
    fragment.setArguments(bundle);

    return fragment;


private void readBundle(Bundle bundle) 
    if (bundle != null) 
        this.mFullname = bundle.getString("fullname");
        this.mTitle = bundle.getString("title");
        this.mEmail = bundle.getString("email");
        this.mAvatar = bundle.getByteArray("avatar");
    


@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    fragmentManager = getFragmentManager();

    // Sets "up navigation" for both phone/tablet configurations
    actionBar = ((MainActivity)getActivity()).getSupportActionBar();
    actionBar.setHomeButtonEnabled(true);
    actionBar.setDisplayHomeAsUpEnabled(true);
    setHasOptionsMenu(true);



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 
    // Inflate the layout for this fragment
    rootView = inflater.inflate(R.layout.fragment_announcement, container, false);
    ListView listView = rootView.findViewById(R.id.announcements_list);

    SwipeRefreshLayout swipe = rootView.findViewById(R.id.swiperefresh);
    swipe.setEnabled(false);


    readBundle(getArguments());
    ArrayList<ProfileObject> list = new ArrayList<>();
    list.add(new ProfileObject(mFullname, mTitle,mEmail,mAvatar));

    ProfileAdapter adapter = new ProfileAdapter(getContext(), list);
    listView.setAdapter(adapter);

    return rootView;


@Override
public boolean onOptionsItemSelected(MenuItem item) 
    switch (item.getItemId()) 
        case android.R.id.home:

            Log.e(LOG_TAG+"/onOptionsItemSelected","Pressed: "+item.getItemId());
            android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            ProfileFragment member_profile = (ProfileFragment)fragmentManager.findFragmentByTag("MEMBER_PROFILE");
            fragmentTransaction.remove(member_profile).commit();
            fragmentManager.popBackStack();
            actionBar.setDisplayHomeAsUpEnabled(false);
            return true;

        default:
            return super.onOptionsItemSelected(item);
    

但正如我已经说过的,只有打开选项菜单。我是不是在某个概念上犯了错误?

更新:onOptionsItemSelected 内部存在问题。如果添加

@Override
public boolean onOptionsItemSelected(MenuItem item) 
    switch (item.getItemId()) 
        case android.R.id.home:
            Log.e(LOG_TAG+"/onOptionsItemSelected","Pressed: "+item.getItemId());
            return true;
        default:
            return super.onOptionsItemSelected(item);
    

然后单击返回箭头,Logcat 中将没有任何内容。

【问题讨论】:

return true 在开关盒的末尾? @Pavneet_Singh 那么应该有什么? 您是否要从 ProfileFragment 返回到 TeamFragment ?那些不是嵌套片段吧? @adityakamble49 对,这就是我想要的。是的,我只是将一个片段替换为另一个片段。为什么?我猜onOptionsItemSelected 中的Profile 片段内部有问题...当我在case R.id.home: 之后添加Log.d("..","..") 时,我的Logcat 没有任何反应 【参考方案1】:

根据您的代码,您已经为 R.id.home 处理了 onOptionsItemSelected(),但我看到您正在使用 Android UI 本身提供的 ActionBar 后退按钮

actionBar = ((MainActivity)getActivity()).getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);

在这种情况下,Home Button 被引用为 android.R.id.homeNOT R.id.home

这就是您在 Logcat 中也没有获得任何更新的原因(正如您在 cmets 中提到的那样)。

如下更新您的开关盒并替换 R.id.homeandroid.R.id.home

@Override
public boolean onOptionsItemSelected(MenuItem item) 
    switch (item.getItemId()) 
        case android.R.id.home: // <- Update this

            android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            ProfileFragment member_profile = (ProfileFragment)fragmentManager.findFragmentByTag("MEMBER_PROFILE");
            fragmentTransaction.remove(member_profile).commit();
            fragmentManager.popBackStack();
            actionBar.setDisplayHomeAsUpEnabled(false);
            return true;

        default:
             return super.onOptionsItemSelected(item);

【讨论】:

是的,你是对的,但事实并非如此。我从该列表中删除了 android. 作为可能的解决方案之一 (***.com/search?q=up+navigation+inside+fragment) 否则,它仍在打开选项菜单 其他原因可能是你没有在后台添加ProfileFragment 确实!谢谢!但是,它只是打开选项菜单而不是返回 我认为 `setHasOptionsMenu(true);` 方法会覆盖活动中的后退按钮。删除该方法并尝试返回按钮是否有效

以上是关于setDisplayHomeAsUpEnabled(true) 打开选项菜单的主要内容,如果未能解决你的问题,请参考以下文章

NullPointerException:在null对象引用上使用ActionBar.setDisplayHomeAsUpEnabled(boolean)'

Android实现滑动效果,但是其中mActionBar.setDisplayHomeAsUpEnabled(false);这句代码报空指,怎么解决

试图在我的 Android 应用程序中 setDisplayHomeAsUpEnabled(true) 并且它给了我一个 NullPointerException

如何更改工具栏主页图标颜色

自己定义Actionbar

ActionBar