【问题标题】:Android added Fragment to screen, but taps fall through new Fragment view to the previous oneAndroid 将 Fragment 添加到屏幕,但点击会通过新的 Fragment 视图转到前一个视图
【发布时间】:2012-02-20 21:29:12
【问题描述】:

我第一次使用 Fragments 并遇到了奇怪的行为。我有一个片段覆盖整个视图的活动。它包含一个 ListView。当我点击 ListView 中的某个项目时,我想显示一个包含有关该项目的信息的详细信息片段。

这就是我展示新片段视图的方式:

FragmentManager fragmentManager = this.getActivity().getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();

DetailsFragment fragment = new DetailsFragment();
transaction.add(R.id.viewRoot, fragment).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                .addToBackStack("Details").commit();

R.id.viewRoot是第一个Fragment的布局xml中根布局的id,所以新的Fragment会填满整个屏幕。

我的问题:当新片段可见并覆盖整个屏幕时,任何落在背景上的点击或点击(即未点击新片段上的按钮或文本字段)似乎正在穿过视图并落在第一个片段。因此,我点击一个 ListView 项目,这会导致 DetailsFragment 添加到屏幕上。然后,当我点击 DetailsFragment 的背景时,该点击落下并落在 ListView 上,导致为我碰巧在幕后击中的任何项目添加另一个 DetailsFragment。

我是否错误地添加了我的新片段?为什么我的点击/点击失败了?

为 caiuspb 编辑:

public class BaseFragment extends Fragment {

    public void pushNewFragment(Fragment fragment, String description) {
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();

        transaction.remove(this);
        transaction.add(R.id.viewRoot, fragment).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                        .addToBackStack(description).commit();
    }

}

我所有的片段都扩展了我的 BaseFragment 类。

【问题讨论】:

  • 你试过transaction.replace(R.id.viewRoot, fragment)吗?
  • 我以前没有,但我只是尝试过,但它的行为方式相同。
  • 发现同样的问题 -> 似乎可以通过这个简单的解决方法来解决:在片段中的所有内容后面添加一个透明按钮,以捕捉每个会通过的点击

标签: android android-fragments


【解决方案1】:

我尝试了收到的建议,但没有一个奏效。最后,我的解决方案是将 OnTouchListener 添加到丢弃所有触摸的子片段的根视图中。

View view = inflater.inflate(R.layout.mylayout, container, false);
view.setOnTouchListener(new View.OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return true;
    }
});

【讨论】:

  • 最简单的方法是为新片段的根 XML 视图添加 clickable="true"。
  • @iBog 谢谢。这是最懒惰和最简单的方法
【解决方案2】:

StackOverflow 上还有一篇关于这种奇怪的 Fragment 行为的帖子。在添加之前尝试删除您的片段,因为替换方法似乎有问题

编辑: 将片段逻辑移动到您的活动中,因为您的活动包含您的片段。今天我尝试使用 Android 支持库中的 FragmentActivity 和 Fragments。现在我可以使用没有任何错误的替换方法。这是我的方法,并且有效:

public class DashActivity extends FragmentActivity{
...
private void changeRightFragment(Fragment fragment) {
        Log.i(TAG, "Loading Fragment into container: " + fragment.getClass().toString());
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.replace(R.id.rightfrag, fragment);
        // Add a transition effect
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        // Add the Fragment to the BackStack so it can be restored by
        // pressing the Back button
        ft.addToBackStack(null);
        ft.commit();
    }
    ...
public void setUserFragment(User user) {
    UserFragment fragment = new UserFragment(user);
    changeRightFragment(fragment);
}

因此,如果您想从 Fragment 内部调用 changeFragment 方法,请使用 Activity 的回调机制

【讨论】:

  • 您是否尝试从片段内部更改片段?在我看来,您应该将片段逻辑放入您的活动中
  • 如果我在添加新片段之前删除()我的第一个片段......当用户从第二个片段回击时......第一个片段将不再在那里等待他们。我不想那样做,我想创建一个堆栈(类似于 iOS 中的 UINavigationController)。
  • 你可以通过执行'fragmentTransaction.addToBackStack(null);'把你的fragment放到栈上在您提交更改之前。 remove() 方法只是从容器中删除您的片段,但不会删除您的堆栈
  • 我不是在调用 replace(),而是在调用 add()。如果我确实切换到使用删除然后添加,这是否意味着每当我从子片段回调时我都必须将片段添加回容器?
  • 很难帮助你,因为你的帖子只包含你程序的一个 sn-p。在将 Detailsfragment 添加到容器之前,您必须删除“ListFragment”。 Remove() 不会杀死你 Fragment 它只是从它的容器中删除 Fragment。因此,如果您使用 remove() 和 add() 并按下 DetailsFragment 中的后退按钮,DetailsFragment 将被终止,您应该会看到您的 ListFragment。但是,您似乎并没有真正使用 Fragments 的好处。 -> developer.android.com/guide/topics/fundamentals/…
猜你喜欢
  • 2013-03-27
  • 2019-01-25
  • 1970-01-01
  • 2011-11-22
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-29
相关资源
最近更新 更多