다른 조각 문제에 대한 조각


271

하나의 조각을 표시 할 때 (이것은 전체 화면 #77000000 배경 )을 다른 조각 (메인이라고 함) 위에 메인 조각은 여전히 ​​클릭에 반응합니다 (보이지 않아도 버튼을 클릭 할 수 있음).

질문 : 첫 번째 (주) 조각에서 클릭을 방지하는 방법은 무엇입니까?

편집하다

불행히도, 두 번째 조각에 투명한 배경을 사용하기 때문에 주요 조각을 숨길 수 없습니다 (따라서 사용자는 뒤에있는 것을 볼 수 있습니다).


당신이 일에 우리에게 준 것을 바탕으로, 당신은 설정을 시도해야 Visibility당신의을 main FragmentGONE당신이 그것을 사용하지 않을 때.
adneal

1
onClicked 메서드를 구현하는 방법을 보지 않으면 클릭 할 때 "false"가 반환되는 것 같습니다.
DeeV

@DeeV, onClick메소드는 아무것도 반환하지 않습니다. 그러나 당신은 아이디어를 제공합니다, 감사합니다 (곧 답변을 게시 할 것입니다).
Dmitry Zaytsev

1
도 네가 옳아. onTouch가이를 반환합니다. 터치 이벤트가 왜 파편에 빠졌는지 이해하기를 바랍니다. 터치 이벤트를 발행하지 않는 경우에는 그렇게하지 않아야합니다.
DeeV

@DeeV, 뷰 (예 : 다른 것의 상단)가 onTouch 이벤트를 잡지 않으면 시스템은 동일한 좌표로 다른 뷰를 계속 검색합니다.
Dmitry Zaytsev

답변:


578

설정 clickabletrue로 두 번째 조각의 뷰 속성입니다. 뷰는 이벤트를 잡아서 주요 조각으로 전달되지 않습니다. 따라서 두 번째 조각의 뷰가 레이아웃 인 경우 코드는 다음과 같습니다.

<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

1
이것은 나를 위해 작동하지 않았습니다. 나는이 RelativeLayout조각 안에, 그리고 내가 가지고있는 전체보기 설정 clickeable속성을. @Dmitry의 솔루션은 내 문제를 해결합니다.
4gus71n

3
이것은 나를 위해 일했습니다. 안드로이드에서 "clickable"은 분명히 iOS와 비슷합니다. "userInteractionEnabled"
mvds

17
Android가 왜 우리에게 열악한 코딩 조건을 적용합니까?!
Lo-Tan

1
ViewPager와 동일한 문제가 있습니다. 첫 페이지를 스크롤하면 두 번째 페이지에도 전달 되며이 솔루션은 작동하지 않습니다. 어떤 아이디어?
Gokhan Arik

72

해결책은 매우 간단합니다. 두 번째 조각 (주 조각과 겹침)에서 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로 작동했지만 왜 명시 적으로 해야하는지 말해 줄 수 있습니까?
사냥

@ 필요하지 않습니다. 그것은 또 다른 방법입니다 (허용 된 답변 참조)
Dmitry Zaytsev

두 번째 조각의 xml 기본 레이아웃에서 android : clickable = "true"
Rishabh Srivastava

이 솔루션에는 문제가 있습니다. 접근성 토크백 모드를 사용하면 개별 요소를 읽지 않고 대신 루트보기에 초점을 맞 춥니 다.
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실제로 필요하지 않습니다.
Dmitry Zaytsev 12

2
제 생각에는 focusable="true"여기에 안드로이드 Studio에서 경고를 피하기 위해 단지이다.
Artem M

9

두 개의 프래그먼트가 동일한 컨테이너보기에 배치 된 경우 두 번째 프래그먼트를 표시 할 때 첫 번째 프래그먼트를 숨겨야합니다.

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
이것이 정답이어야합니다! 고마워요. 다른 프로젝트 에서이 질문을 해결했습니다. 그러나 나는 어떻게 그것을 해결 했습니까? 그리고 마침내 당신의 대답을 얻었습니다. 감사합니다.
Licat Julius

1
이것이 올바른 해결책이라고 생각하지 않습니다. 조각 / 활동은 뷰 스택에서 작동합니다. 맨 위 조각이 스택에서 튀어 나온 후에 .show를 다시 호출해야합니다. 즉 맨 아래 조각이 사라 졌다는 것을 알려야합니다. 유지 관리 할 논리가 추가되었습니다.
XY

4

당신은 android:focusable="true"함께 추가해야합니다 android:clickable="true"

Clickable 즉, 포인터 장치로 클릭하거나 터치 장치로 탭할 수 있습니다.

Focusable키보드와 같은 입력 장치에서 포커스를 얻을 수 있음을 의미합니다. 키보드와 같은 입력 장치는 입력 자체를 기반으로 입력 이벤트를 보낼 뷰를 결정할 수 없으므로 포커스가있는 뷰로 보냅니다.


2
새로운 Android Studio에서 경고를 피하려면 focusable = "true"가 필요합니다
Hossam Hassan

2

우리 중 일부 가이 스레드에 기여한 솔루션이 두 개 이상 있지만 다른 솔루션을 언급하고 싶습니다. 클릭과 포커스를 두는 것을 좋아하지 않는다면 나와 같은 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
    }

인라인 변수를 사용할 수도 있지만 내 이유로 선호하지 않았습니다.

레이아웃 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 : (프로그래밍 방식으로)

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

0

할 수있는 일은 onClick 속성을 사용하여 해당 주요 조각의 부모 레이아웃에 빈 조각 클릭을 제공 할 수 있으며 활동 중에는 함수를 만들고 doNothing(View view)아무것도 쓰지 않을 수 있습니다 . 이것은 당신을 위해 그것을 할 것입니다.


0

DialogFragment의 경우처럼 들립니다. 그렇지 않으면 Fragment Manager를 사용하여 하나는 숨기고 다른 하나는 표시합니다. 그것은 나를 위해 일했다.


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.