298

当我在另一个片段(我们称之为主片段)上显示一个片段(全屏#77000000背景)时,我的主片段仍然对点击做出反应(即使我们没有看到它,我们也可以点击一个按钮)。

问题:如何防止点击第一个(主)片段?

编辑

不幸的是,我不能只隐藏主要片段,因为我在第二个片段上使用透明背景(因此,用户可以看到位于后面的内容)。

4

12 回答 12

629

clickable第二个片段视图的属性设置为 true。视图将捕获事件,以便它不会传递给主片段。所以如果第二个片段的视图是一个布局,这将是代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clickable="true" />
于 2013-03-27T15:30:03.380 回答
75

解决方案非常简单。在我们的第二个片段(与我们的主要片段重叠)中,我们只需要捕获onTouch事件:

@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstance){
    View root = somehowCreateView();

    /*here is an implementation*/

    root.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            return true;
        }
    });
    return root;
}
于 2012-04-30T20:07:06.177 回答
26

只需添加clickable="true"focusable="true"到父布局

 <android.support.constraint.ConstraintLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:clickable="true"
      android:focusable="true">

      <!--Your views-->

 </android.support.constraint.ConstraintLayout>

如果你正在使用AndroidX,试试这个

 <androidx.constraintlayout.widget.ConstraintLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:clickable="true"
      android:focusable="true">

          <!--Your views-->

 </androidx.constraintlayout.widget.ConstraintLayout>
于 2018-05-19T11:37:38.827 回答
11

如果两个片段放置在同一个容器视图中,则在显示第二个片段时应该隐藏第一个片段。

如果想了解更多关于如何解决 Fragment 问题的问题,可以看我的库:https ://github.com/JustKiddingBaby/FragmentRigger

FirstFragment firstfragment;
SecondFragment secondFragment;
FragmentManager fm;
FragmentTransaction ft=fm.beginTransaction();
ft.hide(firstfragment);
ft.show(secondFragment);
ft.commit();
于 2017-12-20T07:41:00.240 回答
7

您需要 android:focusable="true"添加android:clickable="true"

Clickable表示它可以被指针设备点击或被触摸设备轻敲。

Focusable意味着它可以从键盘等输入设备获得焦点。像键盘这样的输入设备无法根据输入本身决定将其输入事件发送到哪个视图,因此它们将它们发送到具有焦点的视图。

于 2018-11-21T12:46:26.897 回答
4

方法一:

您可以添加到所有片段布局

android:clickable="true"
android:focusable="true"
android:background="@color/windowBackground"

方法 2:(以编程方式)

从等扩展所有片段FragmentBase。然后将此代码添加到FragmentBase

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    getView().setBackgroundColor(getResources().getColor(R.color.windowBackground));
    getView().setClickable(true);
    getView().setFocusable(true);
}
于 2020-03-15T16:13:45.777 回答
2

我们中的一些人为这个线程贡献了不止一个解决方案,但我还想提一个其他解决方案。如果您不喜欢像我一样在 XML 中将可点击和可聚焦等于 true 的每个布局的根 ViewGroup。如果你有一个像下面这样的,你也可以把它放在你的基地;

override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ) : View? {
        super.onCreateView(inflater, container, savedInstanceState)

        val rootView = inflater.inflate(layout, container, false).apply {
            isClickable = true
            isFocusable = true
        }

        return rootView
    }

您也可以使用内联变量,但出于个人原因我不喜欢它。

我希望它对那些讨厌布局 XML 的人有所帮助。

于 2020-03-18T09:36:57.307 回答
1

可接受的答案将“起作用”,但也会导致性能成本(过度绘制,重新测量方向变化),因为底部的片段仍在绘制中。也许您应该简单地通过标签或 ID 找到片段,并在需要再次显示时将可见性设置为 GONE 或 VISIBLE。

在科特林:

fragmentManager.findFragmentByTag(BottomFragment.TAG).view.visibility = GONE

此解决方案优于使用动画时的替代方法hide()show()方法。FragmentTransaction您只需从onTransitionStart()andonTransitionEnd()中调用它Transition.TransitionListener

于 2018-08-16T22:12:47.407 回答
0

您可以做的是,您可以通过使用 onClick 属性对前一个片段的布局进行空白单击该主片段的父布局,并且在活动中您可以创建一个函数doNothing(View view)并且不要在其中写入任何内容。这将为您完成。

于 2016-08-03T06:06:29.257 回答
0

这听起来像是 DialogFragment 的一个案例。否则,使用 Fragment Manager 提交一个隐藏,另一个显示。这对我有用。

于 2017-08-18T07:23:03.673 回答
0

的添加android:clickable="true"对我不起作用。当 CoordinatorLayout 是父布局时,此解决方案不适用于它。这就是为什么我将RelativeLayout 作为父布局,添加android:clickable="true"到它并将CoordinatorLayout 放置在这个RelativeLayout 上。

于 2018-06-06T06:24:24.577 回答
0

我有多个具有相同 xml 的片段。
花了几个小时后,我删除setPageTransformer并开始工作

   //  viewpager.setPageTransformer(false, new BackgPageTransformer())

我有严格的逻辑。

public class BackgPageTransformer extends BaseTransformer {

    private static final float MIN_SCALE = 0.75f;

    @Override
    protected void onTransform(View view, float position) {
        //view.setScaleX Y
    }

    @Override
    protected boolean isPagingEnabled() {
        return true;
    }
}
于 2018-08-22T07:50:32.357 回答