如何从视图中获取托管活动?

Posted

技术标签:

【中文标题】如何从视图中获取托管活动?【英文标题】:How to get hosting Activity from a view? 【发布时间】:2012-01-06 18:40:41 【问题描述】:

我有一个 Activity 和 3 个 EditTexts 和一个自定义视图,它充当专用键盘以将信息添加到 EditTexts。

目前我将Activity 传递到视图中,以便我可以获取当前聚焦的编辑文本并从自定义键盘更新内容。

有没有一种方法可以引用父活动并获得当前关注的EditText 而无需将活动传递到视图中?

【问题讨论】:

正确答案是gomino。 【参考方案1】:

我刚刚从 official support library 的 MediaRouter 中提取了该源代码,到目前为止它运行良好:

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

【讨论】:

同时?为什么? 这只是一种在所有基本上下文中冒泡的方法,直到找到活动,或者在找到根上下文时退出循环。因为根上下文会有一个空的baseContext,导致循环结束。 非常好!我用 getActivity() 替换了 ((Activity) getContext()) ,它工作正常......谢谢 如前所述,如果您的 View 不是从 Activity 上下文调用的,则 getContext() 可能并不总是代表 Activity 对象。例如。它不适用于自定义视图。 @AbhinavSaxena 你能给我们举一个这个代码会失败的例子吗?即使方法本身返回 null,它也不应该到达那里。【参考方案2】:

以下方法可能对您有所帮助

    Activity host = (Activity) view.getContext();和 view.isFocused()

【讨论】:

请不要忘记,如果您的 View 不是从 Activity 上下文调用的,getContext() 可能并不总是返回 Activity 对象。请务必提前计划并提供适当的后备方案。 @WordPressDeveloper - 如何在没有活动的情况下创建视图?你是说远程视图?是否还有其他在 Activity 之外创建视图的情况? @kilaka Widgets、Fragments、RemoteViews、LayoutInflaters 都是您可以创建不绑定到 Activity 的视图的情况。 @WordPressDeveloper - 当您在片段中创建视图时,它的上下文仍然是活动。片段只能驻留在活动中。 这是一个非常危险的演员阵容。很有可能(如果您正在使用 appcompat)您所获得的上下文已被包装,将类似 ContextThemeWrapper 的内容转换为 Activity 将抛出 ClassCastException。您需要一种方法来解开基本上下文(应该是一个 Activity),这本身就是危险的,因为有一个原生和 v7 版本的 ContextThemeWrapper【参考方案3】:

更新

tailrec fun Context.getActivity(): Activity? = this as? Activity
    ?: (this as? ContextWrapper)?.baseContext?.getActivity()

感谢@Westy92

用法:

context.getActivity()

【讨论】:

谢谢,非常感谢在 kotlin 上进行的这个不错的扫描活动 你也可以这样做:tailrec fun Context?.getActivity(): Activity? = this as? Activity ?: (this as? ContextWrapper)?.baseContext?.getActivity()【参考方案4】:

我采用了Gomino 的answer 并对其进行了修改以完全适合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。我的回答是普遍适用的,尽管通过一些努力和理解:***.com/a/51077569/787399【参考方案5】:

请注意,如果您知道您的视图在 Fragment 内,您可以这样做:

FragmentManager.findFragment(this).getActivity();

从你的onAttachedToWindowonDraw 调用它,你不能更早调用它(例如onFinishInflate),否则你会得到一个例外。

如果您不确定您的视图是否在 Fragment 内,请参阅其他答案,例如Gomino,只是想把它扔在那里。

【讨论】:

【参考方案6】:

用于 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
    

【讨论】:

您可以将两个if 替换为when,将isInstance() 替换为!is ContextWrapperis Activity 根据@Gomino,根上下文将有一个空的baseContext。因此,在这种情况下,您的实现可能会抛出 ClassCastException 这是旧的解决方案。更好地使用@Vlad 的解决方案【参考方案7】:

android 7+ 中,视图无法再访问封闭的 Activity,因此无法再将 view.getContext() 强制转换为 Activity。

相反,以下代码适用于 Android 7+ 和 6:

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

【讨论】:

“在 Android 7+ 中,视图无法再访问封闭的 Activity,因此无法将 view.getContext() 强制转换为 Activity” 有什么参考吗? @SimpleFellow 正如其他 cmets 中提到的那样,getContext 可能会返回一个 ContextThemeWrapper,因此 View 不再可以直接访问 Activity。相反,您必须递归搜索父上下文,直到找到父 Activity 或使用我在此答案中提供的方法。【参考方案8】:

@覆盖 public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) if(request.getUrl().getHost().startsWith("pay.google.com")) Intent intent = new Intent(Intent.ACTION_VIEW, request.getUrl()); view.getContext().startActivity(intent); 返回真; ... ...

【讨论】:

嗨,欢迎来到 Stack Overflow。请解释您的答案,而不仅仅是代码示例;例如,看看其他答案。

以上是关于如何从视图中获取托管活动?的主要内容,如果未能解决你的问题,请参考以下文章

如何从视图中获取活动?

如何从回收站视图 android 中传递一个 url onclick 项目并 onclick 获取位置 dipaly 在另一个活动中的 url

如何从主 Activity 获取视图

如何在视图绑定中的活动中获取回收者视图当前项目文本值

java 从活动中获取视图

java 从活动中获取视图