Как получить активность хостинга из вида? - PullRequest
164 голосов
/ 26 ноября 2011

У меня есть Activity с 3 EditText с и настраиваемое представление, которое действует на специальной клавиатуре для добавления информации в EditText с.

В настоящее время я передаю Activity в представление, чтобы я мог получить текущий отредактированный текст редактирования и обновить содержимое с пользовательской клавиатуры.

Есть ли способ сослаться на родительское действие и получить текущее EditText без передачи действия в представление?

Ответы [ 7 ]

260 голосов
/ 06 октября 2015

Я только что вытащил этот исходный код из MediaRouter в официальную библиотеку поддержки , и пока он работает нормально:

private Activity getActivity() {
    Context context = getContext();
    while (context instanceof ContextWrapper) {
        if (context instanceof Activity) {
            return (Activity)context;
        }
        context = ((ContextWrapper)context).getBaseContext();
    }
    return null;
}
166 голосов
/ 26 ноября 2011

следующие методы могут вам помочь

  1. Activity host = (Activity) view.getContext(); и
  2. view.isFocused()
4 голосов
/ 31 января 2018

Я взял Gomino ' answer и изменил его, чтобы он идеально подходил для myUtils.java, чтобы я мог использовать его где угодно и когда угодно.Надеюсь, кто-то найдет это полезным:)

abstract class myUtils {
    public static Activity getActivity(View view) {
        Context context = view.getContext();
        while (context instanceof ContextWrapper) {
            if (context instanceof Activity) {
                return (Activity)context;
            }
            context = ((ContextWrapper)context).getBaseContext();
        }
        return null;
    }
}
1 голос
/ 22 апреля 2019

Свойство расширения Kotlin для View для извлечения родительской активности:

val View.activity: Activity?
get() {
    var ctx = context
    while (true) {
        if (!ContextWrapper::class.java.isInstance(ctx)) {
            return null
        }
        if (Activity::class.java.isInstance(ctx)) {
            return ctx as Activity
        }
        ctx = (ctx as ContextWrapper).baseContext
    }
}
0 голосов
/ 28 июня 2018

[Примечание: увидев этот ответ, посмотрите мой другой пост: https://stackoverflow.com/a/51100507/787399 ]

У меня другой подход к этому, и это работает.

Что я делаю, я создаю собственный расширенный класс Application и помечаю его в манифесте: -

public class MyApplication extends Application {

    private AppCompatActivity currentActivity;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    public void setCurrentActivity(AppCompatActivity _activity){
        this.currentActivity = _activity;
    }

    public AppCompatActivity getCurrentActivity() {
        return currentActivity;
    }
}

и

MyApplication в манифесте: -

...
<application
        android:name=".core.MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
...

Затем в моем BaseActivity (абстрактный класс, который расширяет AppCompatActivity, подразумевается расширение всеми действиями, с общими функциями делегируйте классы, которые вы хотите сделать доступными во всех компонентах, фрагментах, адаптерах и т. д.): -

...
@Override
    protected void onResume() {
        super.onResume();
        ((MyApplication) getApplicationContext()).setCurrentActivity(this);
    }
...

Затем в моих пользовательских представлениях (расширяет представления, TextViews для применения настроек и шрифтов локали): -

...
private void setFontFromAsset(Context context, AttributeSet attrs, int defStyle) {
        BaseActivity activity = (BaseActivity)((MyApplication) context.getApplicationContext()).getCurrentActivity();
        FontAndLocaleManager fontAndLocaleManager = activity.getFontAndLocaleManager();
        fontAndLocaleManager.setFontFromAsset(this, R.styleable.FontButton, R.styleable.FontButton_btFontFace, attrs, defStyle);
    }
...

В этом решении используются концепция наследования, классы делегатов и знания о том, что к контексту приложения можно получить доступ где угодно (его можно заменить собственным расширенным классом приложения в манифесте, а также жизненным циклом активности, где при возобновлении вы можете сообщить приложению (MyApplication), что это ваша текущая деятельность.

Теперь, так же, как вы хотите изменить локаль приложения, лучшее место для его изменения - незадолго до вызова setContentView(layout_id) из activity в методе onCreate(Bundle restoreState). Поэтому, как только locale изменяется, вы должны отправить элемент управления обратно на экран dashboard/home, чтобы сразу увидеть эффект.

Вы также можете обновить свой activity, поскольку вы знаете, какой из них является текущим с getCurrentActivity() вашего MyApplication.

Чтобы установить языковой стандарт для вашего приложения, см. Программно установить языковой стандарт

Happy Coding ...: -)

0 голосов
/ 19 апреля 2018

Для меня это сработало:

Context context = SdkUtils.getRootViewContext(getRootView());

и затем произнесение заклинаний вот так (Activity) context

0 голосов
/ 13 мая 2017

В Android 7+ представление больше не имеет доступа к вмещающему действию, поэтому view.getContext() больше не может быть приведено к действию.

Вместо этого код ниже работает в Android 7+ и6:

private static Activity getActivity(final View view) {
    return (Activity) view.findViewById(android.R.id.content).getContext();
}
...