安卓 - 如何从上下文获取视图?

71

我想从Context或Intent中获取视图或findViewById()?

我正在尝试在我的广播接收器中访问特定视图,onReceive的参数是context和intent。

现在,我有一个类,在其中是我的广播接收器。现在,我正在尝试将广播接收器与其分离,但我需要一种方式来使我仍然可以从我的分离的广播接收器类与我的类上的视图进行通信。

谢谢。

5个回答

79
例如,您可以找到任何TextView:
TextView textView = (TextView) ((Activity) context).findViewById(R.id.textView1);

4
好的回答。这是2015年的做法,上面的方法似乎非常冗余。 - Marc DiMillo
1
你不能总是指望上下文是Activity的一个实例,不是吗? - Big McLargeHuge
如果您有一个Activity,那么它可以被转换,而不是Context。这并没有回答问题。 - Javier Delgado
我的问题与我的情况有些不同,但是这种方法可以达到我想要的效果。非常感谢,伙计! - Steven T.

67

从上下文开始,可以通过以下方式获取相关活动的根视图:

View rootView = ((Activity)_context).Window.DecorView.FindViewById(Android.Resource.Id.Content);

在原生的Android中,它会看起来像这样:

View rootView = ((Activity)mContext).getWindow().getDecorView().findViewById(android.R.id.content)

然后只需在此上调用findViewById

View v = rootView.findViewById(R.id.your_view_id);

3
记得将 View v = rootView.findViewById(R.id.your_view_id); 强制类型转换为 View v = (View) rootView.findViewById(R.id.your_view_id);,而且 View 类可以是任何派生自 View 的子类。 - Joaquin Iurchuk
1
尝试时我收到了“Caused by: java.lang.ClassCastException: android.app.Application cannot be cast to android.app.Activity”的错误。 - drynyn
4
这是因为这个例子假设一个 Activity 被传递作为上下文,这并不是一个安全的假设。你可以使用 instanceof 关键字来检查强制类型转换是否安全。(可在谷歌搜索“instanceof java”获取示例)。 - eimmer

7

在您的广播接收器中,您可以通过从XML资源中填充根布局来访问视图,然后使用findViewByid()从该根布局中找到所有视图:

View view = View.inflate(context, R.layout.ROOT_LAYOUT, null);

现在您可以通过“view”访问视图并将其转换为视图类型:
myImage = (ImageView) view.findViewById(R.id.my_image);

我应该将什么放置在根参数上? - lorraine batol
root参数是充气层次结构的根视图。在上面的示例中,我已经展示了如何填充一个已经是根的视图,因此您可以将此参数保持为false。如果您填充的视图不是根视图,则将根视图放置在第三个参数位置。 - Marcin S.
3
应该使用“null”而不是“false”吗? - Roberto
2
我认为重新填充整个视图并不是一种非常高效或可靠的方法,因为它已经通过调用setContentView()进行了填充。但是,如果您省略对setContentView()的调用,并在手动填充后手动附加它,则可能会没问题(我忘记了如何做到这一点,但手动视图附加可以在任何ActivityFragment中完成)。 - samus

1

首先使用这个:

LayoutInflater inflater = (LayoutInflater) Read_file.this
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

Read file is current activity in which you want your context.

View layout = inflater.inflate(R.layout.your_layout_name,(ViewGroup)findViewById(R.id.layout_name_id));

然后您可以使用此功能在布局中查找任何元素。
ImageView myImage = (ImageView) layout.findViewById(R.id.my_image);

-2

为什么不直接使用单例模式呢?

import android.content.Context;


public class ClassicSingleton {
    private Context c=null;
    private static ClassicSingleton instance = null;
    protected ClassicSingleton()
    {
       // Exists only to defeat instantiation.
    }
    public void setContext(Context ctx)
    {
    c=ctx;
    }
    public Context getContext()
    {
       return c;
    }
    public static ClassicSingleton getInstance()
    {
        if(instance == null) {
            instance = new ClassicSingleton();
        }
        return instance;
    }
}

然后在活动类中:

 private ClassicSingleton cs = ClassicSingleton.getInstance();

而在非活动类中:

ClassicSingleton cs= ClassicSingleton.getInstance();
        Context c=cs.getContext();
        ImageView imageView = (ImageView) ((Activity)c).findViewById(R.id.imageView1);

3
很不错的尝试,但不幸的是这会引入一个内存泄漏问题,因为ClassicSingleton将持有对Activity的引用。 - Dmitry Zaytsev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接