从片段返回主页活动而不启动新活动(主页)

Posted

技术标签:

【中文标题】从片段返回主页活动而不启动新活动(主页)【英文标题】:Going back to Home Activity from fragment without starting the new Acivity(Home Page) 【发布时间】:2016-09-20 04:29:03 【问题描述】:

我有一个列出人员的片段。它在(主)活动中调用,该活动在 PeopleListFragment 之前启动。按下后退按钮时,整个应用程序完成。我需要转到主活动而不是关闭。我我很困惑,是否使用 PopBackStack()、PopBackStackimmediate() 或 OnBackPressed()。有人可以帮我解决这个问题吗?

PeopleListFragment

public class PeopleListFragment extends Fragment implements PeopleController.PeopleListView, SearchView.OnQueryTextListener 

    private static final String TAG = "PeopleListFragment";
    public static final boolean DEBUG = Constant.DEBUG;

    private static final String EXTRA_EMPLOYEE_ID = "employeeId";
    private static final String EXTRA_FIRST_NAME = "firstName";
    private static final String EXTRA_LAST_NAME = "lastName";

    private ProgressDialog progressDialog;

    private ArrayList<People> contactList = new ArrayList<>();
    private ListView mContactlistView;

    Parcelable state;
    private Intent intent;
    private PeopleAdapter adapter;

    /**
     * Passes the value to another activity/fragment
     *
     * @param employeeId
     * @param firstName
     * @param lastName
     * @return
     */
    public static PeopleListFragment newInstance(String employeeId, String firstName, String lastName) 

        PeopleListFragment fragment = new PeopleListFragment();

        Bundle args = new Bundle();
        args.putString(EXTRA_EMPLOYEE_ID, employeeId);
        args.putString(EXTRA_FIRST_NAME, firstName);
        args.putString(EXTRA_LAST_NAME, lastName);
        fragment.setArguments(args);

        return fragment;
    

    public PeopleListFragment() 
        // Required empty public constructor
    


    @Override
    public void onAttach(Context context) 
        super.onAttach(context);


    

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        contactList = new ArrayList<>();

        //Initializing the People controller

        PeopleController.getInstance(getActivity()).addPeopleListCallback(this);

    


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        // Inflating the layout for people list fragment

        return inflater.inflate(R.layout.fragment_people_list, container, false);
    

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) 
        super.onViewCreated(view, savedInstanceState);

        mContactlistView = (ListView) view.findViewById(R.id.people_list);
        mContactlistView.setAdapter(adapter);

        if (state != null) 
            Log.d(TAG, "Restoring list view state");

            mContactlistView.requestFocus();
            mContactlistView.onRestoreInstanceState(state);
        
    


    @Override
    public void onActivityCreated(Bundle savedInstanceState) 
        super.onActivityCreated(savedInstanceState);


        adapter = new PeopleAdapter(getActivity().getApplicationContext(),
                R.layout.people_list_item, contactList);

        mContactlistView.setAdapter(adapter);
        mContactlistView.setTextFilterEnabled(false);
        mContactlistView.setFastScrollEnabled(true);

        mContactlistView.setOnItemClickListener(new AdapterView.OnItemClickListener() 
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) 

                String empId = String.valueOf(adapter.getItem(position).getEmployeeId());
                String fname = String.valueOf(adapter.getItem(position).getFirstName());
                String lname = String.valueOf(adapter.getItem(position).getLastName());

                intent = new Intent(getActivity(),
                        PeopleDetailsActivity.class);

                intent.putExtra("EmployeeId", empId);
                intent.putExtra("fName", fname);
                intent.putExtra("lName", lname);

                startActivity(intent);
            
        );
    


    public void updateListView(ArrayList<People> peopleList) 

        contactList = peopleList;
        adapter.updateItems(contactList);

        if (contactList.size() == 0) 
            if (DEBUG) 
                Log.i(TAG, "Contact List is Empty");
            

            if (progressDialog.isShowing()) 
                progressDialog.dismiss();
            

         else 
            mContactlistView.setVisibility(View.VISIBLE);
        

    

    @Override
    public void showProgress() 

        if (progressDialog != null) 
            progressDialog.show();
            mContactlistView.setVisibility(View.GONE);
        

    

    @Override
    public void hideProgress() 
        if (progressDialog != null) 
            progressDialog.dismiss();
        

    


    @Override
    public void displayPeopleList(ArrayList<People> peoples) 
        updateListView(peoples);
    

    @Override
    public void updatePeopleList(ArrayList<People> peoples) 
        updateListView(peoples);

    

    @Override
    public void onStart() 
        super.onStart();

        PeopleController.getInstance(getActivity()).getPeople();

    

    @Override
    public void onResume() 
        super.onResume();

        PeopleController.getInstance(getActivity()).onResume();

    

    @Override
    public void onPause() 

        super.onPause();
        PeopleController.getInstance(getActivity()).onPause();

    

    @Override
    public void onDestroy() 
        super.onDestroy();

        PeopleController.getInstance(getActivity()).removePeopleListCallback();
    

    @Override
    public void showError(int errorCode) 

        if (errorCode == NetworkClient.HTTP_UNAUTHORIZED_SESSION) 

            logout();

         else if (errorCode == NetworkClient.FAILURE) 

            if (contactList.size() == 0) 

                Toast.makeText(getActivity().getApplicationContext(), "Empty Contact List",
                        Toast.LENGTH_LONG).show();

             else 
                //show sync warning
                Snackbar.make(mContactlistView, R.string.info_no_event,
                        Snackbar.LENGTH_SHORT)
                        .show();
            
         else if (errorCode == NetworkClient.NO_INTERNET_CONNECTION) 
            if (contactList.size() == 0) 
                Toast.makeText(getActivity().getApplicationContext(), "No Internet Connection",
                        Toast.LENGTH_LONG).show();
            
        
    

    protected void logout() 
        if (getActivity() != null && getActivity() instanceof BaseActivity) 
            ((BaseActivity) getActivity()).logout();
        
    

    public void search(String searchText) 
        adapter.getFilter().filter(searchText);
    


    @Override
    public boolean onQueryTextSubmit(String query) 
        return false;
    

    @Override
    public boolean onQueryTextChange(String newText) 

        search(newText);
        return true;
    


    /**
     * In this method the search interface is setup for searching a particular employee
     *
     * @param menu
     * @return
     */
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
        super.onCreateOptionsMenu(menu, inflater);

        inflater = getActivity().getMenuInflater();
        inflater.inflate(R.menu.options_menu, menu);

        SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);

        SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
        searchView.setIconifiedByDefault(false);
        searchView.setOnQueryTextListener(this);

    

MainActivity

public class MainActivity extends BaseActivity 

    protected static final int NAVDRAWER_ITEM_HOME = 0;
    protected static final int NAVDRAWER_ITEM_PEOPLE = 1;
    protected static final int NAVDRAWER_ITEM_CALENDAR = 2;
    protected static final int NAVDRAWER_ITEM_TRAINING = 3;
    protected static final int NAVDRAWER_ITEM_ANNOUNCEMENT = 4;

    protected static final int NAVDRAWER_ITEM_INVALID = -1;

    private DrawerLayout mDrawerLayout;
    Intent intent;

    /**
     * List of Title for each @link NavigationView item
     */
    private static final int[] NAVDRAWER_TITLE_RES_ID = 
            R.string.app_name,
            R.string.people,
            R.string.calendar,
            R.string.training,
            R.string.announcement
    ;

    /**
     * Primary color list for each @link NavigationView item
     */
    private static final int[] NAVDRAWER_PRIMARY_COLOR_RES_ID = 
            R.color.trainingPrimaryColor,
            R.color.peoplePrimaryColor,
            R.color.calendarPrimaryColor,
            R.color.trainingPrimaryColor,
            R.color.announcementPrimaryColor
    ;

    /**
     * Status bar color list for each @link NavigationView item
     */
    private static final int[] NAVDRAWER_PRIMARY_DARK_COLOR_RES_ID = 
            R.color.trainingPrimaryDarkColor,
            R.color.peoplePrimaryDarkColor,
            R.color.calendarPrimaryDarkColor,
            R.color.trainingPrimaryDarkColor,
            R.color.announcementPrimaryDarkColor
    ;

    FragmentManager fragmentManager;
    private PeopleListFragment mPeopleListFragment;
    private AnnouncementListFragment mAnnouncementListFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        if (getSelfNavDrawerItem() > 0) 
            setTitle(NAVDRAWER_TITLE_RES_ID[getSelfNavDrawerItem()]);

            setToolbarBackgroundColor(NAVDRAWER_PRIMARY_COLOR_RES_ID[getSelfNavDrawerItem()]);

            setStatusBarColor(NAVDRAWER_PRIMARY_DARK_COLOR_RES_ID[getSelfNavDrawerItem()]);
//            sendScreenName(getString(NAVDRAWER_TITLE_RES_ID[getSelfNavDrawerItem()]));
        

        initNavDrawer();

    

    /**
     * Initialize @link NavigationView and set Listener for the View
     */
    private void initNavDrawer() 
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        if (mDrawerLayout == null) 
            return;
        

        //To display Menu
        NavigationView mNavigationView = (NavigationView) findViewById(R.id.navigation_view);

        // To preserve original icon color in NavigationView
        mNavigationView.setItemIconTintList(null);


        ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                getToolbar(), R.string.open, R.string.close) 
            @Override
            public void onDrawerOpened(View drawerView) 
                super.onDrawerOpened(drawerView);
            

            @Override
            public void onDrawerClosed(View drawerView) 
                super.onDrawerClosed(drawerView);
            
        ;

        mDrawerLayout.addDrawerListener(mDrawerToggle);
        mDrawerToggle.syncState();

        mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() 
            @Override
            public boolean onNavigationItemSelected(MenuItem item) 
                mDrawerLayout.closeDrawers();

                int itemId = NAVDRAWER_ITEM_INVALID;

                switch (item.getItemId()) 
                    case R.id.home:
                        itemId = NAVDRAWER_ITEM_HOME;
                        break;

                    case R.id.people:
                        itemId = NAVDRAWER_ITEM_PEOPLE;
                        break;

                    case R.id.calendar:
                        itemId = NAVDRAWER_ITEM_CALENDAR;
                        break;

                    case R.id.training:
                        itemId = NAVDRAWER_ITEM_TRAINING;
                        break;

                    case R.id.announcement:
                        itemId = NAVDRAWER_ITEM_ANNOUNCEMENT;
                        break;
                

                onNavDrawerItemClicked(itemId);
                return false;
            
        );

        NavigationMenuView navigationMenuView = (NavigationMenuView) mNavigationView.getChildAt(0);
        //Add a Divider between Menu Items in NavigationView
        navigationMenuView.addItemDecoration(new LineDividerItemDecoration(this, R.drawable.line_divider,
                1));
    


    /**
     * It return which Navigation view item it displaying/active, if activity does not
     * contain @link NavigationView it'll return @link #NAVDRAWER_ITEM_INVALID
     *
     * @return Navigation Item ID
     */
    protected int getSelfNavDrawerItem() 
        return NAVDRAWER_ITEM_INVALID;
    

    /**
     * When @link NavigationView item click it'll be called
     *
     * @param itemId Id of clicked item
     */
    private void onNavDrawerItemClicked(final int itemId) 
        if (itemId == getSelfNavDrawerItem()) 
            //if current Navigation Item is clicked again don't do anything simply close the
            // Drawerlayout
            mDrawerLayout.closeDrawer(GravityCompat.START);
            return;
        

        goToNavDrawerItem(itemId);

        mDrawerLayout.closeDrawer(GravityCompat.START);

        /*mHandler.postDelayed(new Runnable() 
            @Override
            public void run() 
                goToNavDrawerItem(itemId);
            
        , NAVDRAWER_LANUCH_DELAY);

        View mainContent = findViewById(R.id.main_content);
        if (mainContent != null) 
            mainContent.animate().alpha(0).setDuration(MAIN_CONTENT_FADEOUT_DURATION).start();
        */
    

    /**
     * Start New Activity for clicked item
     *
     * @param itemId Id of clicked item
     */
    private void goToNavDrawerItem(int itemId) 


        Fragment fragment = null;
        Class fragmentClass = null;


        Intent intent = null;

        switch (itemId) 

            case NAVDRAWER_ITEM_HOME:

                intent = new Intent(this, HomeActivity.class);

                fragmentClass = HomeFragment.class;

                //to clear the activity stack to avoid showing previous activity by pressing back key
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                break;

            case NAVDRAWER_ITEM_PEOPLE:
                setTitle("People");
                setStatusBarColor(R.color.peoplePrimaryDarkColor);
                setToolbarBackgroundColor(R.color.peoplePrimaryColor);

                fragmentClass = PeopleListFragment.class;
                break;

            case NAVDRAWER_ITEM_CALENDAR:

           //Calendar fragment
                break;

            case NAVDRAWER_ITEM_TRAINING:

             //Training fragment
                break;

            case NAVDRAWER_ITEM_ANNOUNCEMENT:

                setTitle("Announcement");
                setStatusBarColor(R.color.announcementPrimaryDarkColor);
                setToolbarBackgroundColor(R.color.announcementPrimaryColor);

                fragmentClass = AnnouncementListFragment.class;

                break;
        


        try 
            fragment = (Fragment) (fragmentClass != null ? fragmentClass.newInstance() : null);
         catch (Exception e) 
            e.printStackTrace();
        


        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.display_frame_container, fragment).commit();

        mDrawerLayout.closeDrawers();

        if (intent != null) 
            startActivity(intent);
        

        //To cancel the transition animation
        overridePendingTransition(0, 0);
    

    @Override
    protected int getLayoutResourceId() 
        return R.layout.activity_main;
    


基础活动

public abstract class BaseActivity extends AppCompatActivity
        implements TrainingListFragment.TrainingCallback 
    /**
     * Drawer Layout for creating @link NavigationView
     */

    private Handler mHandler;


    /**
     * Toolbar
     */
    private Toolbar mToolbar;

    /**
     * Google Analytical Tracker
     */
    private Tracker mTracker;

    /*private static final int NAVDRAWER_LANUCH_DELAY = 250;

    private static final int MAIN_CONTENT_FADEOUT_DURATION = 250;*/

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(getLayoutResourceId());

        String session = PreferenceUtil.getInstance(this).getSession();

        if (TextUtils.isEmpty(session)) 
            logout();
        

        mToolbar = (Toolbar) findViewById(R.id.main_toolbar);

        setSupportActionBar(mToolbar);

        //Initialize the Google Analytical Tracker
        mTracker = ((INetApplication) getApplication()).getDefaultTracker();


        mHandler = new Handler();


    

    /**
     * Send Current Activity Name to Google Analytics
     *
     * @param screenName Name of the Current Screen
     */
    protected void sendScreenName(String screenName) 
        mTracker.setScreenName("Activity~" + screenName);
        mTracker.send(new HitBuilders.ScreenViewBuilder().build());
    

    /**
     * Send Calendar Event to Google Analytics
     *
     * @param value Selected Date
     */
    protected void sendCalendarEventToAnalytics(String value) 
        String CATEGORY_CALENDAR = "Calendar";
        String ACTION_SELECT_DATE = "Select Date";

        mTracker.send(new HitBuilders.EventBuilder()
                .setCategory(CATEGORY_CALENDAR)
                .setAction(ACTION_SELECT_DATE)
                .setLabel(value).build());
    


    /**
     * To clear the User session and display the Login screen
     */
    public void logout() 
        //clear the session and employee id value from preference
        PreferenceUtil.getInstance(this).setSession("");
        PreferenceUtil.getInstance(this).setEmpId("");

        Intent loginIntent = new Intent(this, LoginActivity.class);
        //to clear the activity stack to avoid showing previous activity by pressing back key
        loginIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(loginIntent);

        finish();
    


    /**
     * It will give the Layout Resource ID
     *
     * @return int value of Layout Resource
     */
    protected abstract
    @LayoutRes
    int getLayoutResourceId();


    @Override
    protected void onPause() 
        super.onPause();
        //To cancel the transition animation
        overridePendingTransition(0, 0);
    

    @Override
    protected void onPostCreate(Bundle savedInstanceState) 
        super.onPostCreate(savedInstanceState);

        /*View mainContent = findViewById(R.id.main_content);
        if (mainContent != null) 
            mainContent.setAlpha(0);
            mainContent.animate().alpha(1).setDuration(MAIN_CONTENT_FADEOUT_DURATION).start();
        */
    


    /**
     * To enable/disable HomeUp option in @link Toolbar
     *
     * @param isHomeDisplay boolean to change the HomeUp option
     */
    public void setHomeUpEnable(boolean isHomeDisplay) 
        if (getSupportActionBar() != null) 
            getSupportActionBar().setDisplayHomeAsUpEnabled(isHomeDisplay);
            getSupportActionBar().setHomeButtonEnabled(isHomeDisplay);
            Drawable backArrowDrawable = ContextCompat.getDrawable(this,
                    android.support.design.R.drawable.abc_ic_ab_back_material);

            backArrowDrawable.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
            getSupportActionBar().setHomeAsUpIndicator(backArrowDrawable);

        
    

    /**
     * To change the background color of @link Toolbar
     *
     * @param colorValue color value
     */
    public void setToolbarBackgroundColor(@ColorRes int colorValue) 
        mToolbar.setBackgroundColor(ContextCompat.getColor(this, colorValue));
    

    /**
     * To change the statusbarcolor
     *
     * @param colorValue color value
     */
    public void setStatusBarColor(@ColorRes int colorValue) 
        UIUtil.getInstance(this).setStatusBarColor(ContextCompat.getColor(this, colorValue));
    

    /**
     * Set the title of this @link #mToolbar.
     *
     * @param title title value in string
     */
    public void setTitle(String title) 
        mToolbar.setTitle(title);
    

    /**
     * Set the title of this @link #mToolbar.
     *
     * @param title a string resource
     */
    public void setTitle(@StringRes int title) 
        mToolbar.setTitle(title);
    

    public Toolbar getToolbar() 
        return mToolbar;
    


    @Override
    public void onTrainingItemClick(String trainingId, String trainingTitle, boolean joinStatus,
                                    String trainingTime) 

        Intent intent = new Intent(this, TrainingDetailActivity.class);

        intent.putExtra(TrainingDetailFragment.EXTRA_ID, trainingId);
        intent.putExtra(TrainingDetailFragment.EXTRA_TITLE, trainingTitle);
        intent.putExtra(TrainingDetailFragment.EXTRA_JOINED_STATUS, joinStatus);
        intent.putExtra(TrainingDetailFragment.EXTRA_TRAINING_TIME, trainingTime);

        startActivity(intent);
    

    @Override
    public void displayInfoView(int displayCode) 

    



【问题讨论】:

希望对您有所帮助:***.com/questions/36326776/… 你可以使用:getActivity().getSupportFragmentManager().popBackStack(); 【参考方案1】:

如果您使用堆栈来维护片段,则使用堆栈弹出片段,直到堆栈大小变为 1

while(getParent().stackSize() >2) 
        getParent().popFragments();
    

【讨论】:

while(getParent().stackSize() >2) getParent().popFragments(); 我没有使用堆栈来维护片段。无论我做什么,我的应用程序都会关闭 然后试试这个 while(getActivity().getSupportFragmentManager().getBackStackEntryCount() > 2) getFragmentManager().popBackStack(); 对不起,我是 android 新手。我不知道在哪里使用这个。我应该在 detach 方法中尝试这个吗..? 在您想搬家的地方使用它【参考方案2】:

要替换片段,请使用以下代码

 @Override
    public void replaceFragment(Fragment fragment, String title) 
        String backStateName = fragment.getClass().getName();
        FragmentManager manager = getSupportFragmentManager();
        boolean fragmentPopped = manager.popBackStackImmediate(backStateName, 0);
        if (!fragmentPopped)  //fragment not in back stack, create it.
            FragmentTransaction ft = manager.beginTransaction();
            ft.replace(R.id.container_body, fragment);
            ft.addToBackStack(backStateName);
            ft.commit();
            //     getSupportActionBar().setDisplayShowTitleEnabled(false);
            getSupportActionBar().setTitle("");
        
    

使用此代码添加片段

在您的 Fragment onCreateView 中添加以下行

 setHasOptionsMenu(true);

使用以下代码返回上一个片段。

 @Override
    public boolean onOptionsItemSelected(MenuItem item) 
        switch (item.getItemId()) 
            case android.R.id.home:
                if (getActivity().getSupportFragmentManager().getBackStackEntryCount() > 1) 
                    getFragmentManager().popBackStack();
                    return true;
                
                return true;
            default:
                return super.onOptionsItemSelected(item);
        
    

@Override
public void onDetach() 
    super.onDetach();
    if (getActivity().getSupportFragmentManager().getBackStackEntryCount() > 1) 
        getFragmentManager().popBackStack();
    

【讨论】:

如果你想清除除第一个片段之外的所有片段,只需在 for 循环中执行此操作 if (getActivity().getSupportFragmentManager().getBackStackEntryCount() > 1) getFragmentManager().popBackStack();返回真; getActivity().getSupportFragmentManager() -->显示无法解决的错误。还有其他选择吗? 在 Fragment 子类中,您必须使用 getFragmentManager 代替 getSupportFragmentManager。如果导入来自支持库,您将获得支持。 我已经使用了上面的代码。但是没有任何动作发生。它只是在同一个peoplelsitfragment中。 你想去主要活动还是主要片段?...如果你的片段类是第二个活动,你必须删除finish();从你的第一个活动意图调用..如果你想从当前片段转到主片段,你必须正确使用上面的代码。【参考方案3】:

您需要将事务添加到后台堆栈,然后才会弹出片段。

FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.display_frame_container, fragment).commit();

这个给

FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.display_frame_container, fragment).addToBackStack("").commit();

当您按下返回按钮时,它会自动转到 MainActivity

【讨论】:

不..它没有导航回 MainActivity。

以上是关于从片段返回主页活动而不启动新活动(主页)的主要内容,如果未能解决你的问题,请参考以下文章

应用程序在点击主页按钮后崩溃,然后通过单击应用程序图标返回相同的活动

程序活动主页按钮返回上一个活动

导航抽屉活动:在按钮单击时从片段移动到片段

Android Fragment onClick 按钮打开具有相同活动的新 Fragment

在android中检测主页按钮按下

导航抽屉主页按钮在打开另一个活动并返回后不打开抽屉