뷰에서 호스팅 활동을 얻는 방법?


187

나는이 Activity3 개 EditText의과에 정보를 추가 할 특수 키보드 역할을하는 사용자 지정보기 EditText들.

현재 Activity뷰에 전달하여 현재 포커스가있는 편집 텍스트를 가져오고 사용자 정의 키보드에서 내용을 업데이트 할 수 있습니다.

부모 활동을 참조 EditText하고 활동을 뷰에 전달하지 않고 현재 초점을 맞추는 방법이 있습니까?


7
정답은 gomino입니다.
djunod

답변:


305

방금 공식 지원 라이브러리 의 MediaRouter에서 해당 소스 코드를 가져 와서 잘 작동했습니다.

private Activity getActivity() {
    Context context = getContext();
    while (context instanceof ContextWrapper) {
        if (context instanceof Activity) {
            return (Activity)context;
        }
        context = ((ContextWrapper)context).getBaseContext();
    }
    return null;
}

13
동안? 왜 왜?
Jakob Eriksson

9
그것은 활동이 발견 될 때까지 모든 기본 컨텍스트를 통해 거품을 내거나 루트 컨텍스트가 발견되면 루프를 종료하는 방법입니다. 원인 루트 컨텍스트는 null baseContext를 가지므로 루프가 종료됩니다.
Gomino

1
아주 좋아! 나는 ((Activity) getContext ())를 getActivity ()로 바꾸었고 잘 작동합니다 .... 감사합니다
Christian

들었 듯이 getContext ()는 뷰가 Activity 컨텍스트에서 호출되지 않은 경우 항상 Activity 객체를 나타내는 것은 아닙니다. 예를 들어 커스텀 뷰에서는 작동하지 않습니다.
Tohid

@AbhinavSaxena이 코드가 실패하는 예를 들어 주시겠습니까? 메소드 자체가 null을 반환하더라도 절대 거기에 도달해서는 안됩니다.
Tiago

168

다음 방법이 도움이 될 수 있습니다

  1. Activity host = (Activity) view.getContext(); 과
  2. view.isFocused()

35
getContext()뷰가 액티비티 컨텍스트에서 호출되지 않은 경우 항상 액티비티 객체를 반환 하지 않을 수도 있습니다. 미리 계획하고 적절한 폴백을 제공하십시오.
Dzhuneyt

1
@WordPressDeveloper-활동없이 어떻게 뷰를 만들 수 있습니까? 당신은 원격보기를 의미합니까? 활동 외부에서 작성된 다른보기가 있습니까?
AlikElzin-kilaka

1
@kilaka Widgets, Fragments, RemoteViews, LayoutInflaters는 모두 활동과 관련이없는보기를 만들 수있는 경우입니다.
Dzhuneyt

4
@WordPressDeveloper-프래그먼트로 뷰를 생성 할 때 컨텍스트는 여전히 활동입니다. 조각은 활동에만 상주 할 수 있습니다.
AlikElzin-kilaka

24
이것은 매우 위험한 캐스트입니다. 유사한 무언가를 주조, 당신이있어 상황이 포장된다 (당신이 APPCOMPAT 사용하는 경우) 좋은 기회가 ContextThemeWrapperActivity발생합니다 ClassCastException. 기본 컨텍스트 (액션이어야 함)의 랩을 해제하는 방법이 필요합니다. 기본 컨텍스트는 v7 버전이므로 기본적으로 위험 ContextThemeWrapper합니다.
alex

11

나는 Kotlin으로 작성된이 솔루션을 좋아합니다.

tailrec fun Context?.activity(): Activity? = when (this) {
    is Activity -> this
    else -> (this as? ContextWrapper)?.baseContext?.activity()
}

View수업 에서의 사용법

context.activity()

디 컴파일 된 코드 :

public static final Activity activity(Context context) {
    while (!(context instanceof Activity)) {
        if (!(context instanceof ContextWrapper)) {
            context = null;
        }
        ContextWrapper contextWrapper = (ContextWrapper) context;
        if (contextWrapper == null) {
            return null;
        }
        context = contextWrapper.getBaseContext();
        if (context == null) {
            return null;
        }
    }
    return (Activity) context;
}

1
감사합니다. kotlin
mochadwi

8

Gomino대답을 취하여 myUtils.java 에 완벽하게 맞게 수정하여 필요할 때마다 사용할 수 있습니다. 누군가가 도움이되기를 바랍니다 :)

abstract class myUtils {
    public static Activity getActivity(View view) {
        Context context = view.getContext();
        while (context instanceof ContextWrapper) {
            if (context instanceof Activity) {
                return (Activity)context;
            }
            context = ((ContextWrapper)context).getBaseContext();
        }
        return null;
    }
}

이 함수에서 반환 될 때 null을 얻을 가능성이 있으므로 효과적인 답은 아닙니다. 내 대답은 보편적으로 적용하지만 약간의 노력과 이해를 통해 : stackoverflow.com/a/51077569/787399
Abhinav Saxena는

-1

Android 7 이상에서는 뷰가 더 이상 엔 클로징 활동에 액세스 할 view.getContext()수 없으므로 더 이상 활동으로 캐스트 할 수 없습니다.

대신 아래 코드는 Android 7 이상 및 6에서 작동합니다.

private static Activity getActivity(final View view) {
    return (Activity) view.findViewById(android.R.id.content).getContext();
}

6
"view.getContext ()가 활동에 캐스트 할 수 없도록에서 안드로이드 7+ 뷰는 더 이상 둘러싸 활동에 액세스 할 수 없습니다" 언급?
Simple Fellow

다른 의견에서 언급 한 것처럼 @SimpleFellow getContext는 아마도 ContextThemeWrapper뷰가 더 이상 활동에 직접 액세스 할 수 없도록 a를 반환합니다 . 대신 부모 활동을 찾거 나이 답변에서 제공 한 방법을 사용할 때까지 부모 컨텍스트를 반복적으로 검색해야합니다.
Sebas LG

-1

부모 활동을 검색하기위한 View의 Kotlin 확장 등록 정보 :

val View.activity: Activity?
get() {
    var ctx = context
    while (true) {
        if (!ContextWrapper::class.java.isInstance(ctx)) {
            return null
        }
        if (Activity::class.java.isInstance(ctx)) {
            return ctx as Activity
        }
        ctx = (ctx as ContextWrapper).baseContext
    }
}

당신은 두 개의 대체 할 수 ifwhenisInstance()!is ContextWrapperis Activity
데이비드 미구엘

@Gomino에 따르면 루트 컨텍스트에는 null baseContext가 있습니다. 따라서이 경우 구현시 ClassCastException이 발생할 수 있습니다.
David Miguel

이것은 오래된 해결책입니다. 더 나은은 @Vlad으로 솔루션을 사용하는
Fedir Tsapana

-1

@Override public boolean shouldOverrideUrlLoading (WebView view, WebResourceRequest request) {if (request.getUrl (). getHost (). startsWith ( "pay.google.com")) {의도 의도 = 새로운 의도 (Intent.ACTION_VIEW, request.getUrl ()); view.getContext (). startActivity (intent); true를 반환; } ... ...}


1
안녕하세요, Stack Overflow에 오신 것을 환영합니다. 코드 샘플 이상의 답변을 설명하십시오. 예를 들어 다른 답변을보십시오.
Itamar Mushkin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.