it-swarm.com.ru

Получение активности из контекста в 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. Я передаю правильный контекст в профиль?
  2. Как я могу получить содержащую деятельность из контекста?
149
OVERTONE

Из вашей Activity просто передайте this как Context для вашего макета:

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

После этого у вас будет Context в макете, но вы будете знать, что это на самом деле ваш Activity, и вы можете разыграть его так, чтобы у вас было то, что вам нужно:

Activity activity = (Activity) context;
420
Boris Strandjev
  1. Нет
  2. Ты не можешь

В Android есть два разных контекста. Одна для вашего приложения (назовем это БОЛЬШОЙ) и одна для каждого представления (назовем это контекстом активности).

LinearLayout - это представление, поэтому вы должны вызвать контекст действия. Чтобы вызвать это из действия, просто назовите это. Так просто, не правда ли?

Когда вы используете

this.getApplicationContext();

Вы называете БОЛЬШОЙ контекст, который описывает ваше приложение и не может управлять вашим представлением.

Большая проблема с Android заключается в том, что контекст не может вызвать вашу активность. Это большая проблема, чтобы избежать этого, когда кто-то начинает разработку Android. Вы должны найти лучший способ кодирования вашего класса (или заменить «Контекст контекста» на «Активность действия» и при необходимости привести его к «Контексту»).

С уважением.


Просто чтобы обновить мой ответ. Самый простой способ получить ваш Activity context - это определить экземпляр static в вашем Activity. Например

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, вы можете использовать такой код, чтобы получить свой Activity context:

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

Это то, что я успешно использовал для преобразования Context в Activity при работе в пользовательском интерфейсе в фрагментах или пользовательских представлениях. Он будет распаковывать ContextWrapper рекурсивно или вернет ноль, если это не удастся.

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

Если вы хотите вызывать метод действия из пользовательского класса макета (не класса активности). Вам следует создать делегат с использованием интерфейса. 

Это не проверено, и я закодировал это правильно. но я передаю способ достичь того, что вы хотите.

Прежде всего создать и интерфейс 

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){}
               });
7
Xar E Ahmer

Контекстом может быть Приложение, Сервис, Активность и многое другое.

Обычно контекст Views в Activity - это сама Activity, поэтому вы можете подумать, что можете просто преобразовать этот Context в Activity, но на самом деле вы не всегда можете это сделать, потому что в этом случае контекст также может быть ContextThemeWrapper.

ContextThemeWrapper широко используется в последних версиях AppCompat и Android (благодаря атрибуту Android: theme в макетах), поэтому я бы лично никогда не выполнял это приведение.

Итак, короткий ответ: вы не можете надежно извлечь действие из контекста в представлении. Передайте Activity в представление, вызвав для него метод, который принимает Activity в качестве параметра.

6
BladeCoder

Никогда не используйте getApplicationContext () с представлениями.

Это всегда должен быть контекст деятельности, так как представление привязано к деятельности. Кроме того, у вас может быть набор пользовательских тем, и при использовании контекста приложения все темы будут потеряны. Узнайте больше о различных версиях контекстов здесь .

2
lomza

Я использовал конвертировать активность

Activity activity = (Activity) context;
0
Samuel Ivan

Этот метод должен быть полезным ..!

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;

    }

Я надеюсь, что это помогает .. Веселое кодирование!

0
Taslim Oseni

действие - это специализация контекста, поэтому, если у вас есть контекст, вы уже знаете, какое действие вы намереваетесь использовать, и можете просто привестиaвc; гдеa- это действие, аc- это контекст.

Activity a = (Activity) c;
0
ACLima