在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个问题:
- 我是否将正确的上下文传递到Profileview?
- 如何从上下文中获取包含的活动?
从你的Activity
,只要通过this
作为您的布局Context
:
ProfileView pv = new ProfileView(this, null, temp, tempPd);
之后,你将在布局中有一个Context
,但是你会知道它实际上是你的Activity
,你可以施放它,以便你有你所需要的:
Activity activity = (Activity) context;
- 没有
- 你不能
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; } }
然后,在你的Task
, Dialog
, View
,你可以使用这种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;