Android получить хостинг активность с точки зрения
У меня есть Activity
с 3 EditText
s и пользовательский вид, который действует как специализированная клавиатура для добавления информации в EditText
s.
В настоящее время я прохожу Activity
в вид, чтобы я мог получить фокусированный в данный момент текст редактирования и обновить содержимое с пользовательской клавиатуры.
Есть ли способ ссылки на родительскую активность и получить в настоящее время сосредоточены EditText
не передавая активность в поле зрения?
11 ответов
Следующие методы могут помочь вам
Activity host = (Activity) view.getContext()
; а такжеview.isFocused()
Я только что вытащил этот исходный код из MediaRouter в официальную библиотеку поддержки, и пока он работает нормально:
private Activity getActivity() {
Context context = getContext();
while (context instanceof ContextWrapper) {
if (context instanceof Activity) {
return (Activity)context;
}
context = ((ContextWrapper)context).getBaseContext();
}
return null;
}
Мне нравится это решение, написанное на Котлине
tailrec fun Context?.activity(): Activity? = when (this) {
is Activity -> this
else -> (this as? ContextWrapper)?.baseContext?.activity()
}
Использование в View
учебный класс
context.activity()
Декомпилированный код:
public static final Activity activity(Context context) {
while (!(context instanceof Activity)) {
if (!(context instanceof ContextWrapper)) {
context = null;
}
ContextWrapper contextWrapper = (ContextWrapper) context;
if (contextWrapper == null) {
return null;
}
context = contextWrapper.getBaseContext();
if (context == null) {
return null;
}
}
return (Activity) context;
}
Я взял Gomino и изменил его, чтобы он идеально подходил для 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;
}
}
Просто хочу отметить, что если вы знаете, что ваше представление находится внутри, вы можете просто сделать:
FragmentManager.findFragment(this).getActivity();
Если вы не уверены, что ваш вид находится внутри
Fragment
затем обратитесь к другим ответам, например, Гомино, просто хотел выбросить его там.
Ответ Котлина на основе @gomino
fun View?.getActivitySafely():Activity?{
var context: Context = this!!.context
while (context is ContextWrapper) {
if (context is Activity) {
return context
}
context = context.baseContext
}
return null
}
[Примечание: увидев этот ответ, посмотрите мой другой пост: /questions/21973257/kak-programmno-ustanovit-shrift-dlya-shrifta-spinner/21973261#21973261]
У меня другой подход к этому, и это работает.
Что я делаю, я создаю собственный расширенный класс 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);
}
...
Затем в моих пользовательских представлениях (расширяет представления, текстовые представления для применения настроек языка и шрифтов):-
...
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
,
Чтобы установить языковой стандарт вашего приложения, см. Раздел "Программный набор языковых стандартов".
Удачного кодирования...:-)
@Override public boolean shouldOverrideUrlLoading(представление WebView, запрос WebResourceRequest) { if(request.getUrl(). GetHost(). StartWith("pay.google.com")) { Intent intent = new Intent(Intent.ACTION_VIEW, request.getUrl()); view.getContext().startActivity(намерение); вернуть истину; } ... ... }
Для меня это сработало:
Context context = SdkUtils.getRootViewContext(getRootView());
а затем кастинг, как это (Activity) context
Свойство расширения 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
}
}
В Android 7+ представление больше не имеет доступа к вложенным действиям, поэтому view.getContext()
больше не может быть приведен к Деятельности.
Вместо этого приведенный ниже код работает в Android 7+ и 6:
private static Activity getActivity(final View view) {
return (Activity) view.findViewById(android.R.id.content).getContext();
}