別のフラグメントの問題のフラグメント


271

1つのフラグメント(#77000000背景付きのフルスクリーン)を別のフラグメント(メインと呼ぶ)の上に表示しても、メインフラグメントはクリックに反応します(表示されていなくてもボタンをクリックできます)。

質問:最初の(メイン)フラグメントのクリックを防ぐ方法は?

編集

残念ながら、2番目のフラグメントに透明な背景を使用しているため、メインフラグメントを非表示にすることはできません(そのため、ユーザーは背後にあるものを確認できます)。


あなたが仕事に私たちを与えたものに基づいて、設定を試してみてくださいVisibilityあなたのをmain FragmentGONEあなたがそれを使用していないとき。
12

1
onClickedメソッドを実装する方法がわからないので、クリックすると「false」が返されると思います。
DeeV 2012

@DeeV、onClickメソッドは何も返しません。しかし、あなたはアイデアを与えてくれてありがとう(私はすぐに答えを投稿します)。
Dmitry Zaytsev 2012

1
ドー。あなたが正しい。onTouchはそれを返します。タッチイベントがフラグメントを通過した理由を理解したいと思います。touchイベントを発行していない場合は、そのようにすべきではありません。
DeeV 2012

@DeeVは、ビュー(たとえば、他のビューの上)がonTouchイベントをキャッチしないように見え、システムは同じ座標を持つ他のビューの検索を続行します。
Dmitry Zaytsev 2012

回答:


578

clickable2番目のフラグメントのビューのプロパティをtrueに設定します。ビューはイベントをキャッチして、メインフラグメントに渡されないようにします。したがって、2番目のフラグメントのビューがレイアウトの場合、次のコードになります。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clickable="true" />

4
これでうまくいきました。@Dmitry Zaitsevが上で与えた解決策よりも簡単なようです。これが悪い考えになる理由はありますか?何も考えられないようですが、確かにしたいです。
ariets 2013

1
これは私にはうまくいきませんでした。私はRelativeLayoutフラグメントの中にいて、ビュー全体をclickeableプロパティで設定しています。@Dmitryの解決策は私の問題を解決します。
4gus71n 2013年

3
これでうまくいきました。Androidの「クリッカブル」は、iOSの「userInteractionEnabled」にいくらか似ています
mvds

17
なぜAndroidは厳しいコーディング条件の対象となるのですか?
Lo-Tan、

1
ViewPagerで同じ問題が発生しています。最初のページをスクロールすると、2番目のページにも移動しますが、このソリューションはうまくいきませんでした。何か案は?
Gokhan Arik 2015年

72

解決策は非常に簡単です。2番目のフラグメント(メインフラグメントと重複しています)では、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;
}

あなたの解決策はそのために+1で機能しましたが、なぜこれを明示的に行う必要があるのか​​教えていただけますか?
2014

@ハントする必要はありません。それは、それを行うもう1つの方法です(承認された回答を参照)
Dmitry Zaytsev 2014

2番目のフラグメントのxmlメインレイアウトでandroid:clickable = "true"。
Rishabh Srivastava 2015

このソリューションには問題があります。アクセシビリティトークバックモードをONにすると、個々の要素は読み取られず、ルートビューにフォーカスが移ります。
Amit Garg

Kotlinバージョン:root.setOnTouchListener {_、_-> true}
Gal Rom

21

ただ、追加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>

これは、受け入れられた回答とどういうわけか違いますか?focuseable本当に必要ではありません。
ドミトリーザイツェフ2018年

2
これfocusable="true"は、Android Studioでの警告を回避するためだけのものだと思います。
Artem M

9

2つのフラグメントが同じコンテナビューに配置されている場合、2番目のフラグメントを表示しているときに最初のフラグメントを非表示にする必要があります。

Fragmentに関する問題を解決する方法についてさらに質問が必要な場合は、私のライブラリを参照してくださいhttps : //github.com/JustKiddingBaby/FragmentRigger

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

1
これは正解です!男ありがとう 私は別のプロジェクトでこの質問を解決しました。しかし、私はそれをどのように解決したかを忘れてしまいました。最後に、私はあなたの答えを得ました。ありがとうございました。
リカットジュリアス2018

1
これが正しい解決策だとは思いません。フラグメント/アクティビティはビュースタックで機能します。上部のフラグメントがスタックからポップされた後、もう一度.showを呼び出す必要があります。つまり、下部のフラグメントに、上部のフラグメントがなくなったことを通知する必要があります。維持するロジックが追加されただけです。
XY

4

あなたは追加する必要がある android:focusable="true"android:clickable="true"

Clickable これは、ポインターデバイスでクリックしたり、タッチデバイスでタップしたりできることを意味します。

Focusableキーボードなどの入力デバイスからフォーカスを取得できることを意味します。キーボードなどの入力デバイスは、入力自体に基づいて入力イベントを送信するビューを決定できないため、フォーカスのあるビューに送信します。


2
新しいAndroid Studioでの警告を回避するには、focusable = "true"が必要です
Hossam Hassan

2

私たちの一部がこのスレッドに貢献した解決策は複数ありますが、他の解決策についても触れておきたいと思います。あなたが気に入らない場合、クリック可能でフォーカス可能にすることは、私のようなすべてのレイアウトのルート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が嫌いな人のために役立つことを願っています。


1

許容できる答えは「機能」しますが、下部のフラグメントがまだ描画されているため、パフォーマンスコスト(オーバードロー、方向の変更時に再測定)も発生します。おそらく、タグまたはIDでフラグメントを見つけ、再度表示する必要がある場合は、可視性をGONEまたはVISIBLEに設定する必要があります。

コトリンでは:

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

このソリューションは、アニメーションを使用する場合の代替方法hide()show()方法よりFragmentTransactionも適しています。あなただけからそれを呼び出すonTransitionStart()onTransitionEnd()しますTransition.TransitionListener


1

方法1:

すべてのフラグメントレイアウトに追加できます

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

方法2:(プログラムで)

FragmentBaseetc からすべてのフラグメントを拡張します。次に、このコードを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);
}

0

uができることは、メインフラグメントの親レイアウトにonClickプロパティを使用することにより、前のフラグメントのレイアウトにブランククリックを与えることができ、アクティビティでは、関数doNothing(View view)を作成してそれに何も書き込まないことができます。これはあなたのためにそれを行います。


0

これは、DialogFragmentの場合のように聞こえます。それ以外の場合は、フラグメントマネージャーを使用して、1つを非表示にし、もう1つを表示します。これでうまくいきました。


0

を追加してもandroid:clickable="true"うまくいきませんでした。このソリューションは、親レイアウトの場合、CoordinatorLayoutでは機能しません。そのため、親レイアウトとしてRelativeLayoutを作成android:clickable="true"して追加し、このRelativeLayoutにCoordinatorLayoutを配置しました。


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;
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.