Programing

Android의 컨텍스트에서 활동 가져 오기

crosscheck 2020. 5. 28. 07:59
반응형

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를 전달합니다. 두 가지 질문 :

  1. 올바른 컨텍스트를 Profileview에 전달하고 있습니까?
  2. 컨텍스트에서 포함 활동을 얻으려면 어떻게해야합니까?

에서 레이아웃 으로 다음 Activity전달 하십시오.thisContext

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

나중에 Context레이아웃에 표시되지만 실제로 레이아웃임을 알 Activity수 있으며 필요한 것을 갖도록 캐스팅 할 수 있습니다.

Activity activity = (Activity) context;

  1. 아니
  2. 넌 못해

Android에는 두 가지 컨텍스트가 있습니다. 하나는 응용 프로그램 (BIG 하나라고 함)과 각보기 (활동 컨텍스트라고 함)마다 하나입니다.

linearLayout은 뷰이므로 활동 컨텍스트를 호출해야합니다. 활동에서 호출하려면 간단히 "this"를 호출하십시오. 너무 쉽지 않습니까?

사용할 때

this.getApplicationContext();

애플리케이션을 설명하고 뷰를 관리 할 수없는 BIG 컨텍스트를 호출합니다.

Android의 큰 문제는 컨텍스트가 활동을 호출 할 수 없다는 것입니다. 누군가 안드로이드 개발을 시작할 때 이것을 피하는 것은 큰 일입니다. 클래스를 코딩하는 더 좋은 방법을 찾아야합니다 (또는 "컨텍스트 컨텍스트"를 "활동 활동"으로 바꾸고 필요할 때 "컨텍스트"로 캐스트).

문안 인사.


Just to update my answer. The easiest way to get your Activity context is to define a static instance in your Activity. For example

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;
    }
}

And then, in your Task, Dialog, View, you could use that kind of code to get your Activity context:

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

This is something that I have used successfully to convert Context to Activity when operating within the UI in fragments or custom views. It will unpack ContextWrapper recursively or return null if it fails.

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;
}

If you like to call an activity method from within a custom layout class(non-Activity Class).You should create a delegate using interface.

It is untested and i coded it right . but i am conveying a way to achieve what you want.

First of all create and Interface

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");
    }
}

And implement this to any Activity.

and call it like

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

Context may be an Application, a Service, an Activity, and more.

Normally the context of Views in an Activity is the Activity itself so you may think you can just cast this Context to Activity but actually you can't always do it, because the context can also be a ContextThemeWrapper in this case.

ContextThemeWrapper is used heavily in the recent versions of AppCompat and Android (thanks to the android:theme attribute in layouts) so I would personally never perform this cast.

So short answer is: you can't reliably retrieve an Activity from a Context in a View. Pass the Activity to the view by calling a method on it which takes the Activity as parameter.


Never ever use getApplicationContext() with views.

It should always be activity's context, as the view is attached to activity. Also, you may have a custom theme set, and when using application's context, all theming will be lost. Read more about different versions of contexts here.


I used convert Activity

Activity activity = (Activity) context;

an Activity is a specialization of Context so, if you have a Context you already know which activity you intend to use and can simply cast a into c; where a is an Activity and c is a Context.

Activity a = (Activity) c;

This method should be helpful..!

public Activity getActivityByContext(Context context){

if(context == null){
    return null;
    }

else if((context instanceof ContextWrapper) && (context instanceof Activity)){
        return (Activity) context;
    }

else if(context instanceof ContextWrapper){
        return getActivity(((ContextWrapper) context).getBaseContext());
    }

return null;

    }

I hope this helps.. Merry coding!


And in Kotlin:

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

참고URL : https://stackoverflow.com/questions/9891360/getting-activity-from-context-in-android

반응형