在android中从上下文获取活动

这一个让我难住。

我需要从自定义布局类中调用一个活动方法。 这个问题是我不知道如何从布局中访问活动。

ProfileView

public class ProfileView extends LinearLayout { TextView profileTitleTextView; ImageView profileScreenImageButton; boolean isEmpty; ProfileData data; String name; public ProfileView(Context context, AttributeSet attrs, String name, final ProfileData profileData) { super(context, attrs); ...... ...... } //Heres where things get complicated public void onClick(View v) { //Need to get the parent activity and call its method. ProfileActivity x = (ProfileActivity) context; x.activityMethod(); } } 

ProfileActivity

 public class ProfileActivityActivity extends Activity { //In here I am creating multiple ProfileViews and adding them to the activity dynamically. public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.profile_activity_main); } public void addProfilesToThisView() { ProfileData tempPd = new tempPd(.....) Context actvitiyContext = this.getApplicationContext(); //Profile view needs context, null, name and a profileData ProfileView pv = new ProfileView(actvitiyContext, null, temp, tempPd); profileLayout.addView(pv); } } 

正如你在上面看到的,我正在以编程方式实例化profileView并传入activityContext。 2个问题:

  1. 我是否将正确的上下文传递到Profileview?
  2. 如何从上下文中获取包含的活动?

从你的Activity ,只要通过this作为您的布局Context

 ProfileView pv = new ProfileView(this, null, temp, tempPd); 

之后,你将在布局中有一个Context ,但是你会知道它实际上是你的Activity ,你可以施放它,以便你有你所需要的:

 Activity activity = (Activity) context; 
  1. 没有
  2. 你不能

Android中有两种不同的上下文。 一个用于你的应用程序(我们称之为BIG之一),另一个用于每个视图(我们称之为活动上下文)。

linearLayout是一个视图,所以你必须调用活动上下文。 要从活动中调用它,只需调用“this”即可。 这么容易不是吗?

当你使用

 this.getApplicationContext(); 

您可以调用BIG上下文,描述您的应用程序并且无法pipe理您的视图。

Android的一个大问题是上下文无法调用您的活动。 当有人开始进行Android开发时,避免这种情况是一件大事。 你必须find一个更好的方法来编写你的类(或者把“活动活动”replace为“上下文上下文”,并在需要的时候把它转换为“上下文”)。

问候。


只是为了更新我的答案。 获取Activity context的最简单方法是在Activity context定义一个static实例。 例如

 public class DummyActivity extends Activity { public static DummyActivity instance = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Do some operations here } @Override public void onResume() { super.onResume(); instance = this; } @Override public void onPause() { super.onPause(); instance = null; } } 

然后,在你的TaskDialogView ,你可以使用这种types的代码来获得你的Activity context

 if (DummyActivity.instance != null) { // Do your operations with DummyActivity.instance } 

如果您想从自定义布局类(非活动类)中调用活动方法,则应使用接口创build委托。

这是未经testing,我编码的权利。 但我正在传达一种方法来实现你想要的。

首先创build和接口

 interface TaskCompleteListener<T> { public void onProfileClicked(T result); } public class ProfileView extends LinearLayout { private TaskCompleteListener<String> callback; TextView profileTitleTextView; ImageView profileScreenImageButton; boolean isEmpty; ProfileData data; String name; public ProfileView(Context context, AttributeSet attrs, String name, final ProfileData profileData) { super(context, attrs); ...... ...... } public setCallBack( TaskCompleteListener<String> cb) { this.callback = cb; } //Heres where things get complicated public void onClick(View v) { callback.onProfileClicked("Pass your result or any type"); } } 

并执行此任何活动。

并称之为

 ProfileView pv = new ProfileView(actvitiyContext, null, temp, tempPd); pv.setCallBack(new TaskCompleteListener { public void onProfileClicked(String resultStringFromProfileView){} }); 

上下文可以是应用程序,服务,活动等等。

通常情况下,活动中的视图的上下文是活动本身,因此您可能认为只能将此上下文转换为活动,但实际上并不总是这样做,因为在这种情况下,上下文也可以是ContextThemeWrapper。

ContextThemeWrapper在AppCompat和Android的最新版本中被大量使用(感谢布局中的android:theme属性),所以我个人决不会执行这个转换。

所以简短的答案是:你不能可靠地从视图中的上下文中检索一个活动。 将Activity传递给视图,方法是调用Activity作为参数。

这是我已经成功地使用在片段或自定义视图中在UI中操作时将Context转换为Activity 。 它将recursion解压缩ContextWrapper,如果失败则返回null。

 public Activity getActivity(Context context) { if (context == null) { return null; } else if (context instanceof ContextWrapper) { if (context instanceof Activity) { return (Activity) context; } else { return getActivity(((ContextWrapper) context).getBaseContext()); } } return null; } 

我用转换活动

 Activity activity = (Activity) context; 

永远不要在视图中使用getApplicationContext()

它应该始终是活动的背景,因为这个观点是附属于活动的。 此外,你可能有一个自定义的主题设置,并在使用应用程序的上下文时,所有的主题都将丢失。 在这里阅读更多不同版本的上下文。

一个Activity是Context的一个专门化,所以如果你有一个Context,你已经知道你打算使用哪个activity,并且可以简单地将a转换成c ; 其中a是活动, c是上下文。

 Activity a = (Activity) c;