片段onBackPressed方法由其他Fragment调用

时间:2015-12-26 21:46:41

标签: android android-fragments

我在ViewPager和Fragment实现方面遇到了一些问题。

我在ViewPager中有4个片段{A; B; C:D},其中一个是配置文件视图(D片段)。当用户登录时,我有一个FragmentTransaction用一个详细的配置文件视图{D --- D1}替换该配置文件视图。在那个详细的配置文件视图视图中,我实现了一个自定义的onBackPressed行为,仅针对像这样的片段

    this.rootView.setFocusableInTouchMode(true);
    this.rootView.requestFocus();
    this.rootView.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {

            if (event.getAction() != KeyEvent.ACTION_DOWN) {
                final MaterialDialog mMaterialDialog = new 
                MaterialDialog(getActivity());
                mMaterialDialog.setTitle("LOG OUT")
                        .setMessage("If you log out right now, you will not be able to make a booking")
                        .setPositiveButton("OK", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                ParseUser user = ParseUser.getCurrentUser();
                                user.logOut();

                                mMaterialDialog.dismiss();

                                FragmentTransaction trans = getFragmentManager()
                                        .beginTransaction();
                                trans.replace(R.id.profile_frame, new ProfileFragment());
                                trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
                                trans.commit();
                            }
                        })
                        .setNegativeButton("CANCEL", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                mMaterialDialog.dismiss();
                            }
                        });
                mMaterialDialog.show();


                return true;
            }

            switch (keyCode) {
                case KeyEvent.KEYCODE_1:
                    break;
                case KeyEvent.KEYCODE_2:

                    break;
                case KeyEvent.KEYCODE_3:
                    break;

            }

            return true;

        }
    });

我的问题是当用户点击片段B中的后退按钮时,它会触发片段D1方法。为什么会这样?这是我的主要活动和完整片段D1代码

主要活动

    public class MainActivity extends FragmentActivity {

private TabLayout tabLayout; private LinearLayout settings, booking, about;
private Button contactUs, visitOurSite;
private DrawerLayout drawer; private LinearLayout drawerContent;
private Tracker tracker;
private Fragment musicFrag, profileDetailFrag, filterFrag, mapFrag, profileFrag, favoritesFrag;
private ViewPager viewPager;
private int[] tabIconsUnselected = {
        R.drawable.tab_home,
        R.drawable.tab_map,
        R.drawable.tab_favorites,
        R.drawable.tab_profile
};

private int[] tabIconsSelected = {
        R.drawable.tab_home_pressed,
        R.drawable.tab_map_pressed,
        R.drawable.tab_favorites_pressed,
        R.drawable.tab_profile_pressed
};

public static FragmentManager fragmentManager;
private Window window;

@Override
protected void onStart() {
    super.onStart();
    GoogleAnalytics.getInstance(this).reportActivityStart(this);
}

@Override
protected void onStop() {
    super.onStop();
    GoogleAnalytics.getInstance(this).reportActivityStop(this);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);

    fragmentManager = getSupportFragmentManager();

    Typeface semiBold = Typeface.createFromAsset(getAssets(), "fonts/GillSans-SemiBold.ttf");
    Typeface light = Typeface.createFromAsset(getAssets(), "fonts/GillSans-Light.ttf");
    Typeface bold = Typeface.createFromAsset(getAssets(), "fonts/GillSans-Bold.ttf");

    drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    viewPager = (ViewPager) findViewById(R.id.viewpager);
    viewPager.setPageTransformer(true, new ParallaxPagerTransformer(R.id.parallax_content));
    viewPager.setOffscreenPageLimit(1);
    setupViewPager(viewPager);

    tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);
    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            switch (tab.getPosition()) {
                case 0:
                    tracker.send(new HitBuilders.EventBuilder().setCategory("Tabs").setAction("Click").setLabel("Home tab").build());
                    viewPager.setCurrentItem(tab.getPosition());
                    setPressed(tab.getPosition());

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        window = getWindow();
                        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                        window.setStatusBarColor(getResources().getColor(R.color.colorSecondaryDark));
                    }

                    break;
                case 1:
                    viewPager.setCurrentItem(tab.getPosition());
                    setPressed(tab.getPosition());

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        window = getWindow();
                        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                        window.setStatusBarColor(getResources().getColor(R.color.colorSecondaryDark));
                    }

                    break;
                case 2:
                    viewPager.setCurrentItem(tab.getPosition());
                    setPressed(tab.getPosition());

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        window = getWindow();
                        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                        window.setStatusBarColor(getResources().getColor(R.color.colorSecondaryDark));
                    }

                    break;
                case 3:
                    viewPager.setCurrentItem(tab.getPosition());
                    setPressed(tab.getPosition());

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        window = getWindow();
                        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                        window.setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));
                    }

                    break;
            }
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

    contactUs = (Button) findViewById(R.id.contact);
    contactUs.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            tracker.send(new HitBuilders.EventBuilder().setCategory("Navigation Drawer").setAction("Click").setLabel("Contact Us").build());
            startActivity(new Intent(MainActivity.this, ContactUsActivity.class));
        }
    });

    visitOurSite = (Button) findViewById(R.id.web);
    visitOurSite.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Uri uri = Uri.parse("http://landing.vamospues.co");
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            startActivity(intent);
        }
    });

    settings = (LinearLayout) findViewById(R.id.settings_button);
    TextView settingsLabel = (TextView) settings.getChildAt(1);
    settingsLabel.setTypeface(semiBold);

    settings.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(new Intent(MainActivity.this, SettingsActivity.class));
            finish();
        }
    });

    booking = (LinearLayout) findViewById(R.id.booking_button);
    booking.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(new Intent(MainActivity.this, BookingActivity.class));
        }
    });
    TextView reservationsLabel = (TextView) booking.getChildAt(1);
    reservationsLabel.setTypeface(semiBold);

    about = (LinearLayout) findViewById(R.id.about_button);
    TextView aboutLabel = (TextView) about.getChildAt(1);
    aboutLabel.setTypeface(semiBold);

    about.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            tracker.send(new HitBuilders.EventBuilder().setCategory("Navigation Drawer").setAction("Click").setLabel("About").build());
            startActivity(new Intent(MainActivity.this, AboutActivity.class));
        }
    });

    setupTabIcons();
}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    drawer.openDrawer(findViewById(R.id.drawer_content));
}

private void setPressed(int i) {
    if (i==0){
        tabLayout.getTabAt(0).setIcon(tabIconsSelected[0]);
        tabLayout.getTabAt(1).setIcon(tabIconsUnselected[1]);
        tabLayout.getTabAt(2).setIcon(tabIconsUnselected[2]);
        tabLayout.getTabAt(3).setIcon(tabIconsUnselected[3]);
    }
    if (i==1){
        tabLayout.getTabAt(0).setIcon(tabIconsUnselected[0]);
        tabLayout.getTabAt(1).setIcon(tabIconsSelected[1]);
        tabLayout.getTabAt(2).setIcon(tabIconsUnselected[2]);
        tabLayout.getTabAt(3).setIcon(tabIconsUnselected[3]);
    }
    if (i==2){
        tabLayout.getTabAt(0).setIcon(tabIconsUnselected[0]);
        tabLayout.getTabAt(1).setIcon(tabIconsUnselected[1]);
        tabLayout.getTabAt(2).setIcon(tabIconsSelected[2]);
        tabLayout.getTabAt(3).setIcon(tabIconsUnselected[3]);
    }
    if (i==3){
        tabLayout.getTabAt(0).setIcon(tabIconsUnselected[0]);
        tabLayout.getTabAt(1).setIcon(tabIconsUnselected[1]);
        tabLayout.getTabAt(2).setIcon(tabIconsUnselected[2]);
        tabLayout.getTabAt(3).setIcon(tabIconsSelected[3]);
    }
}

private void setupTabIcons() {
    tabLayout.getTabAt(0).setIcon(tabIconsSelected[0]);
    tabLayout.getTabAt(1).setIcon(tabIconsUnselected[1]);
    tabLayout.getTabAt(2).setIcon(tabIconsUnselected[2]);
    tabLayout.getTabAt(3).setIcon(tabIconsUnselected[3]);
}

private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    adapter.addFrag(new FilterFragment(), "ONE");
    adapter.addFrag(new MapFragment(), "TWO");
    adapter.addFrag(new FavoritesFragment(), "THREE");
    adapter.addFrag(new ProfileFragment(), "FOUR");
    viewPager.setAdapter(adapter);
}

}

FRAGMENT D1

   public class ProfileDetailFragment extends Fragment {

private View rootView; RotateLoading loader;
private CircleImageView profilePic; ScrollView profileContainer;
private String id, name, mail, birthday, phone, url;
private TextView nameLabel, mailLabel, birthdayLabel, phoneLabel;
private Bitmap picture;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    if (rootView != null) {
        ViewGroup parent = (ViewGroup) rootView.getParent();
        if (parent != null)
            parent.removeView(rootView);
    }
    try {
        rootView = inflater.inflate(R.layout.profile_detail_fragment, container, false);
    } catch (InflateException e) {

    }

    if(ParseUser.getCurrentUser() == null){
        FragmentTransaction trans = getChildFragmentManager()
                .beginTransaction();
        trans.replace(R.id.profile_frame, new ProfileFragment());
        trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        trans.commit();
    }

    loader = (RotateLoading) rootView.findViewById(R.id.loading);
    profileContainer = (ScrollView) rootView.findViewById(R.id.profile_container);
    profileContainer.setVisibility(View.GONE);

    nameLabel = (TextView) rootView.findViewById(R.id.name_label);
    mailLabel = (TextView) rootView.findViewById(R.id.mail_label);
    birthdayLabel = (TextView) rootView.findViewById(R.id.birthday_label);
    phoneLabel = (TextView) rootView.findViewById(R.id.phone_label);
    profilePic = (CircleImageView) rootView.findViewById(R.id.profile_pic);

    this.rootView.setFocusableInTouchMode(true);
    this.rootView.requestFocus();
    this.rootView.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {

            if (event.getAction() != KeyEvent.ACTION_DOWN) {
                final MaterialDialog mMaterialDialog = new MaterialDialog(getActivity());
                mMaterialDialog.setTitle("LOG OUT")
                        .setMessage("If you log out right now, you will not be able to make a booking")
                        .setPositiveButton("OK", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                ParseUser user = ParseUser.getCurrentUser();
                                user.logOut();

                                mMaterialDialog.dismiss();

                                FragmentTransaction trans = getFragmentManager()
                                        .beginTransaction();
                                trans.replace(R.id.profile_frame, new ProfileFragment());
                                trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
                                trans.commit();
                            }
                        })
                        .setNegativeButton("CANCEL", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                mMaterialDialog.dismiss();
                            }
                        });
                mMaterialDialog.show();


                return true;
            }

            switch (keyCode) {
                case KeyEvent.KEYCODE_1:
                    break;
                case KeyEvent.KEYCODE_2:

                    break;
                case KeyEvent.KEYCODE_3:
                    break;

            }

            return true;

        }
    });

    return rootView;
}


@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {

    new RemoteDataTask().execute();
    super.onViewCreated(view, savedInstanceState);
}

public class RemoteDataTask extends AsyncTask<Void,Void,Void>
{

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        loader.start();

    }

    @Override
    protected Void doInBackground(Void... params) {
        ParseUser user = ParseUser.getCurrentUser();
        id = user.get("id").toString();
        name = user.get("name").toString();
        mail = user.getEmail();
        birthday = user.get("birthday").toString();
        phone = user.get("phone").toString();
        url = user.get("pic_url").toString();

        return null;
    }


    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        loader.stop();
        profileContainer.setVisibility(View.VISIBLE);
        Picasso.with(getActivity()).load(url).into(profilePic);
        birthdayLabel.setText(birthday);
        mailLabel.setText(mail);
        nameLabel.setText(name);
        phoneLabel.setText(phone);

    }
}

}

感谢您的帮助:)

1 个答案:

答案 0 :(得分:0)

这是您正在创建的一个非常奇怪的架构项目。在任何情况下,您都没有真正处理后退事件,您在D1中处理任何类型的按键。这是一个问题,但另一个问题是所有碎片同时存在,即使你只能看到它。您需要做的是正确处理onBackPressed()(该方法存在于活动上,而不是片段上)

要处理它,您需要跟踪当前显示的片段,并检查是否将事件传递给片段。因为onBackPressed没有遵循通常的事件签名,所以我们不能简单地返回false来说不要让事件传播,所以你需要从你的D片段中移除听众(我会去现在假设是ProfileFragment),并将代码放入您自己的方法中(让我们假设你也称之为onBackPressed)

关于活动:

@Override
public void onBackPressed() {
    //NOTE: I havent checked if getSelectedPosition exists, so track it however you want
    if ( viewPager.getSelectedPosition() == 3 ) {
        ((ProfileFragment) profileFragment).onBackPressed();
    } else {
        super.onBackPressed(); 
    }
}

然后在ProfileFragment / D

public void onBackPressed() {
    final MaterialDialog mMaterialDialog = new MaterialDialog(getActivity());
    ...
    mMaterialDialog.show();
}