片段在后台

时间:2016-05-13 12:56:46

标签: android android-fragments

在我的应用中,我的第一个Fragment位于BackStack中,并且在交易时该片段未添加到backstack。

编辑。

  

我在第一次横断后多次使用相同的碎片,但是   横断后跟第一个加入后台堆栈   addToBackStack(TAG);但我从来没有将第一个片段添加到backstack中   但我仍然不明白为什么我必须点击两次才能发送应用程序   到背景。

这是代码

FragmentManager fm = getSupportFragmentManager();
Bundle args = new Bundle();
args.putString("url", Constants.URL_BASE);
feedFragment.setArguments(args);
fm.beginTransaction().replace(R.id.content_frame, feedFragment).commit();

现在,当我按下后退按钮时,它会移除片段,但应用程序不会转到后台。当我第二次按下后退按钮时,它会进入后台。

replace()本身是否将片段添加到backstack?如果是,那么我如何删除片段并让我的应用转到后台onBackPressed? 如果它没有将片段添加到backstack,为什么会发生这种情况?我应该如何使它正常工作?

三江源!

编辑:

这里是完整的活动代码。

public class MainActivity extends AppCompatActivity {
    private final String TAG = getClass().getName();
    private DrawerLayout drawerLayout;
    private FeedFragment feedFragment = new FeedFragment();
    private ListView listView;
    private LinearLayout searchLayout;
    private RelativeLayout logolayout;
    private Toolbar toolbar;
    private Button settingBtn;
    private Button bookmarkBtn;
    private Button searchBtn;
    private Tracker mTracker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ApplicationController applicationController = (ApplicationController) getApplication();
        mTracker = applicationController.getDefault();
        initToolbar();
        initUi();
        loadCategorgies();
        initFeed();
    }

    public void initUi() {
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        listView = (ListView) findViewById(R.id.lv_categories);
        settingBtn = (Button) findViewById(R.id.btn_settings);
        bookmarkBtn = (Button) findViewById(R.id.btn_bookmarks);
        searchBtn = (Button) findViewById(R.id.btn_search);


        settingBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fragmentManager = getSupportFragmentManager();
                fragmentManager.beginTransaction().replace(R.id.content_frame, new SettingFragment()).addToBackStack("setting").commit();
                drawerLayout.closeDrawers();
            }
        });

        bookmarkBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fragmentManager = getSupportFragmentManager();
                fragmentManager.beginTransaction().replace(R.id.content_frame, new BookmarkFragment()).addToBackStack("bookmark").commit();
                drawerLayout.closeDrawers();
            }
        });

        searchBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fragmentManager = getSupportFragmentManager();
                fragmentManager.beginTransaction().replace(R.id.content_frame, new SearchFragment()).addToBackStack("search").commit();
                drawerLayout.closeDrawers();
            }
        });
    }

    public void initToolbar() {
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_action_menu_inactive);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    public void hideLogo() {
        ImageView imageView = (ImageView) toolbar.findViewById(R.id.logo);
        imageView.setVisibility(View.GONE);
    }

    public void showLogo() {
        ImageView imageView = (ImageView) toolbar.findViewById(R.id.logo);
        imageView.setVisibility(View.VISIBLE);
    }

    public void loadCategorgies() {
        StringRequest stringRequest = new StringRequest(Constants.URL_GET_CATEGORIES, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                if (Constants.isDev)
                    Log.d(TAG, response);
                final CategoriesDTO categoriesDTO = Constants.gson.fromJson(response, CategoriesDTO.class);
                CatgoriesAdapter catgoriesAdapter = new CatgoriesAdapter(categoriesDTO, MainActivity.this);
                listView.setAdapter(catgoriesAdapter);
                listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                        if (Constants.isDev)
                            Log.d(TAG, "clicked" + categoriesDTO.getCategories().get(position).getTitle());
                        FeedFragment feedFragment = new FeedFragment();
                        FragmentManager fm = getSupportFragmentManager();
                        Bundle args = new Bundle();
                        args.putString("url", Constants.URL_BASE_CATEGORY + categoriesDTO.getCategories().get(position).getSlug());
                        feedFragment.setArguments(args);
                        fm.beginTransaction().replace(R.id.content_frame, feedFragment).addToBackStack(categoriesDTO.getCategories().get(position).getSlug()).commit();
                        drawerLayout.closeDrawers();
                    }
                });
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });
        ApplicationController.getmInstance().addToRequestQueue(stringRequest);
    }

    public void initFeed() {
        FragmentManager fm = getSupportFragmentManager();
        Bundle args = new Bundle();
        args.putString("url", Constants.URL_BASE);
        feedFragment.setArguments(args);
        fm.beginTransaction().replace(R.id.content_frame, feedFragment).commit();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        switch (id) {
            case android.R.id.home:
                drawerLayout.openDrawer(GravityCompat.START);
                return true;
        }
        return super.onOptionsItemSelected(item);

    }

    @Override
    protected void onResume() {
        super.onResume();
        if (Constants.isDev)
            Log.i(TAG, "Setting screen name: " + TAG);
        mTracker.setScreenName("Image~" + TAG);
        mTracker.send(new HitBuilders.ScreenViewBuilder().build());
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        //moveTaskToBack(true);
    }
}

修改

mcve

这是HomeActivity。

public class HomeActivity extends AppCompatActivity {
    private final String TAG = getClass().getName();
    private DrawerLayout drawerLayout;
    private FragmentManager fragmentManager;
    private FeedFragment feedFragment = new FeedFragment();
    private Toolbar toolbar;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home_activity);
        fragmentManager = getSupportFragmentManager();
        initToolbar();
        initFeed();
    }
    public void initToolbar() {
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_action_menu_inactive);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }
public void initUi() {
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
}
    public void initFeed() {

        Bundle args = new Bundle();
        args.putString("url", Constants.URL_BASE);
        feedFragment.setArguments(args);
        fragmentManager.beginTransaction().replace(R.id.content_frame, feedFragment).commit();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        switch (id) {
            case android.R.id.home:
                drawerLayout.openDrawer(GravityCompat.START);
                return true;
        }
        return super.onOptionsItemSelected(item);

    }

    @Override
    protected void onResume() {
        super.onResume();
        if (Constants.isDev)
            Log.i(TAG, "Setting screen name: " + TAG);
        mTracker.setScreenName("Image~" + TAG);
        mTracker.send(new HitBuilders.ScreenViewBuilder().build());
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
    }
}

这是碎片。

public class FeedFragment extends Fragment {
private final String TAG = getClass().getName();
private View view;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.feed_fragment, container, false);
    return view;
}

5 个答案:

答案 0 :(得分:0)

此代码没问题,当你开始活动时没有问题,你没有把它放在后面的堆栈。

FragmentManager fm = getSupportFragmentManager();
Bundle args = new Bundle();
args.putString("url", Constants.URL_BASE);
feedFragment.setArguments(args);
fm.beginTransaction().replace(R.id.content_frame, feedFragment).commit();

但是在initUI()之后你调用了loadcategories()方法,你将feed片段放在backstack中。所以这就是你需要点击两次的原因。

FeedFragment feedFragment = new FeedFragment();
                    FragmentManager fm = getSupportFragmentManager();
                    Bundle args = new Bundle();
                    args.putString("url", Constants.URL_BASE_CATEGORY + categoriesDTO.getCategories().get(position).getSlug());
                    feedFragment.setArguments(args);
                    fm.beginTransaction().replace(R.id.content_frame, feedFragment).addToBackStack(categoriesDTO.getCategories().get(position).getSlug()).commit();

做一件事

@Override
public void onBackPressed() {
       FragmentManager fm = getFragmentManager();
       if(fm.getBackStackEntryCount() == 1){
        fm.popBackStack ("YOUR_TAG",FragmentManager.POP_BACK_STACK_INCLUSIVE);
       }
       super.onBackPressed();
       }

答案 1 :(得分:0)

Try to make own switch like:
import android.support.v4.app.Fragment;
and make switch case and use it like this: 

 case 44: {

                page = 44;

                fragment = new FragmentOne();
                getSupportActionBar().setTitle(R.string.page_44);

                action = true;

                break;
            }
 if (action) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.container_body, fragment)
                    .commit();
        }


and finally in
 backpress(){

displayView(44);}

答案 2 :(得分:0)

如果你的意思是你的应用程序显示不应该存在的空白片段,那么你需要编辑片段事务,从容器中获取片段并添加一些条件以在第一个片段不是时将其添加到backstack空值。见下面的例子

Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.content_frame);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content_frame, feedFragment)
if(fragment != null){
    ft.addToBackStack(categoriesDTO.getCategories().get(position).getSlug());
}
ft.commit();

我希望这有帮助:)

答案 3 :(得分:0)

我添加这样的碎片:

private void addTransaction(Fragment fragment) {
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.replace(R.id.content_frame, fragment, "visible_fragment");
    ft.addToBackStack(null);
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    ft.commit();
}

我使用它来管理按下后退按钮上的片段事务:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(Gravity.LEFT); //CLOSE Nav Drawer!
        } else {
            if (getFragmentManager().getBackStackEntryCount() == 0) {
                this.finish();
                return false;
            }

            if (getFragmentManager().getBackStackEntryCount() > 1) {
                getFragmentManager().popBackStack();
                removeCurrentFragment();
                return false;
            }
        }
    }
    return super.onKeyDown(keyCode, event);
}

从Backstack中删除当前片段

public void removeCurrentFragment() {
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    Fragment currentFrag = getFragmentManager().findFragmentByTag("visible_fragment");
    String fragName = "NONE";

    if (currentFrag != null) {
        fragName = currentFrag.getClass().getSimpleName();
        transaction.remove(currentFrag);
    }

    transaction.commit();
}

要在backstack上处理更改,您必须在您的活动和FragmentManager.OnBackStackChangedListener @Override方法上实施onBackStackChanged(),例如:

@Override
public void onBackStackChanged() {
    // Get your current fragment
    Fragment fragment = getFragment();

    // Update your UI such as title, drawer selected options, etc
}

private Fragment getFragment() {
    return getFragmentManager().findFragmentByTag("visible_fragment");
}

希望它有所帮助。

答案 4 :(得分:-1)

在onBackPressed中,在super.onBackPressed()之前添加:

len

修改

要实现您所需的功能,请尝试以下方法:

moveTaskToBack(true);