Android 另一个片段问题的片段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10389620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 03:32:26  来源:igfitidea点击:

Fragment over another fragment issue

androidandroid-fragments

提问by Dmitry Zaytsev

When I'm showing one fragment (which is full screen with #77000000background) over another fragment (let's call it main), my main fragment still reacts to clicks (we can click a button even if we don't see it).

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

Question: how to prevent clicks on first (main) fragment?

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

EDIT

编辑

Unfortunately, I can't just hide main fragment, because I'm using transparent background on second fragment (so, user can see what located behind).

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

回答by Jure Vizjak

Set clickableproperty on the second fragment's view to true. The view will catch the event so that it will not be passed to the main fragment. So if the second fragment's view is a layout, this would be the code:

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" />

回答by Dmitry Zaytsev

Solution is pretty simple. In our second fragment (that overlaps our main fragment) we just need to catch onTouchevent:

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

回答by Miravzal

Just add clickable="true"and focusable="true"to parent layout

只需添加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>

If you are using AndroidX, try this

如果你正在使用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>

回答by JingYeoh

You should hide the first fragment when you are showing the second Fragment if two fragments is placed in same container view.

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

If you want to know more questions about how to solve problems about Fragment, you can see my library: https://github.com/JustKiddingBaby/FragmentRigger

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

FirstFragment firstfragment;
SecondFragment secondFragment;
FragmentManager fm;
FragmentTransaction ft=fm.beginTransaction();
ft.hide(firstfragment);
ft.show(secondFragment);
ft.commit();

回答by Hossam Hassan

You need to add android:focusable="true"with android:clickable="true"

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

Clickablemeans that it can be clicked by a pointer device or be tapped by a touch device.

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

Focusablemeans that it can gain the focus from an input device like a keyboard. Input devices like keyboards cannot decide which view to send its input events to based on the inputs itself, so they send them to the view that has focus.

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

回答by Yekta Sar?o?lu

There is more than one solution that some of us contributed to this thread but also I would like to mention one other solution. If you don't fancy putting clickable and focusable equals true to every layout's root ViewGroup in XML like me. You can also put it to your base if you have one just like below;

我们中的一些人为此线程贡献了不止一种解决方案,但我还想提及另一种解决方案。如果您不喜欢像我一样在 XML 中将可点击和可聚焦等同于每个布局的根 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
    }

You can also use inline variable but I did not prefer it for my reasons.

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

I hope it helps for the ones who hate layout XMLs.

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

回答by Allan Veloso

The acceptable answer will "work", but will also cause performance cost (overdraw, re-measuring on orientation change) as the fragment on the bottom is still being drawn. Maybe you should simply find the fragment by tag or ID and set visibility to GONE or VISIBLE when you need to show again.

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

In Kotlin:

在科特林:

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

This solution is preferable to the alternative hide()and show()methods of FragmentTransactionwhen you use animations. You just call it from the onTransitionStart()and onTransitionEnd()of Transition.TransitionListener.

此解决方案比使用动画时的替代方法hide()show()方法更可取FragmentTransaction。您只需从onTransitionStart()onTransitionEnd()中调用它Transition.TransitionListener

回答by AskQ

I had multiple fragments with same xml.
After spending hours, I removed setPageTransformerand it started working

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

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

I had scalling logic.

我有缩放逻辑。

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

回答by Zhebzhik Babich

The adding of android:clickable="true"didn't work for me. This solution not works on CoordinatorLayout when it's a parent layout. That's why I've made RelativeLayout as parent layout, added android:clickable="true"to it and placed CoordinatorLayout on this RelativeLayout.

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

回答by Satish Silveri

What u can do is u can give a Blank click to the previous fragment's layout by using onClick property to parent layout of that main fragment and in activity you can create a function doNothing(View view)and do not write anything in it. This will do it for you.

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