【问题标题】:Fragment onBackPressed method called by other Fragment其他 Fragment 调用的 Fragment onBackPressed 方法
【发布时间】:2015-12-26 21:46:41
【问题描述】:

我对 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);
}

}

片段 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);

    }
}

}

感谢您的帮助 :)

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    这是您正在创建的一个非常奇怪的架构项目。无论如何,您实际上并没有处理后按事件,而是在处理 D1 中的任何类型的按键。这是一个问题,但另一个问题是您的所有片段同时存在,即使您只能看到一个。你需要做的是正确处理onBackPressed()(方法存在于activity上,不在Fragment上)

    要处理它,您需要跟踪当前显示的Fragment,并检查是否将事件传递给Fragment。因为 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();
    }
    

    【讨论】:

      猜你喜欢
      • 2016-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多