Android 关于另一个碎片问题的碎片

Android 关于另一个碎片问题的碎片,android,android-fragments,Android,Android Fragments,当我在另一个片段(我们称之为主片段)上显示一个片段(背景为7700000的全屏片段)时,我的主片段仍然会对点击做出反应(即使看不到,我们也可以点击按钮) 问题:如何防止点击第一个(主)片段 编辑 不幸的是,我不能仅仅隐藏主片段,因为我在第二个片段上使用了透明背景(这样,用户可以看到后面的内容)。解决方案非常简单。在我们的第二个片段(与我们的主片段重叠)中,我们只需要捕获onTouch事件: @Override public View onCreateView(LayoutInflater inf

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

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

编辑


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

解决方案非常简单。在我们的第二个片段(与我们的主片段重叠)中,我们只需要捕获
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;
}

将第二个片段视图上的
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" />


您可以使用onClick属性对前一个片段的布局进行空白单击,然后在活动中创建一个函数
执行任何操作(查看视图)
,并且不在其中写入任何内容。这就可以了。

这听起来像是DialogFragment的例子。否则,使用片段管理器提交一个隐藏,另一个显示。这对我来说很有效。

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

如果您想了解更多关于如何解决有关Fragment的问题的问题,可以查看我的库:

只需将
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>

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

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

在科特林:

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

使用动画时,此解决方案比
FragmentTransaction
hide()
show()
方法更可取。您只需从
Transition.TransitionListener的
onTransitionStart()
onTransitionEnd()
调用它。TransitionListener
我有多个具有相同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;
    }
}

您需要添加
android:focusable=“true”
android:clickable=“true”

可点击
意味着它可以被指针设备点击或被触摸设备点击


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

Metod 1:

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

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

我们中的一些人对此线程贡献了不止一种解决方案,但我还想提及另一种解决方案。如果您不想像我一样,在XML中为每个布局的根视图组设置clickable和focusable等于true。你也可以把它放在你的基地,如果你有一个就像下面

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的人有所帮助。

根据您给我们提供的内容,您应该尝试在不使用时将
片段的
可见性设置为
消失了的
。在没有看到如何实现onClicked方法的情况下,我猜您返回了“false”单击时,@DeeV,
onClick
方法不返回任何内容。但是你给我一个想法,谢谢(我很快会发布答案)。哦。你说得对。onTouch返回它。我只是希望我能理解为什么一个触摸事件会从一个碎片中消失。如果您没有发出触摸事件,则不应该这样做。@DeeV,看起来如果您的视图(例如位于其他视图之上的视图)没有捕捉到触摸事件,则系统将继续搜索具有相同坐标的其他视图。这对我很有效。这似乎比上面@Dmitry Zaitsev给出的解决方案更简单。这是个坏主意,有什么原因吗?我似乎想不出什么,但我只是想确定一下。这对我来说不起作用。我在片段中有一个
RelativeLayout
,我用
clickable
属性设置了整个视图。@Dmitry的解决方案解决了我的问题。这对我很有效。Android中的“clickable”显然有点像iOS的“userInteractionEnabled”,为什么Android让我们受制于苛刻的编码条件?!我对ViewPager也有同样的问题。当我在第一页上滚动时,它也会转到第二页,这个解决方案对我不起作用。有什么想法吗?你的解决方案是+1,但你能告诉我为什么我们需要明确地这样做吗?@Hunt你不必这么做。这只是另一种方法(请参阅接受的答案)android:clickable=“true”在第二个片段的xml主布局上。此解决方案存在一个问题,当您在上进入可访问性对讲模式时,它不会读取单个元素,而是将焦点放在根视图上。Kotlin版本:root.setOnTouchListener{uu,{uu->true}这与公认的答案有什么不同吗
focusable
并不是真的需要。我认为
focusable=“true”@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);
}
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
    }