3つのActivity
sを持つEditText
と、EditText
sに情報を追加するための専用キーボードとして機能するカスタムビューがあります。
現在、ビューにActivity
を渡しているので、現在フォーカスされている編集テキストを取得し、カスタムキーボードからコンテンツを更新できます。
ビューにアクティビティを渡すことなく、親アクティビティを参照し、現在フォーカスされているEditText
を取得する方法はありますか?
公式サポートライブラリ のMediaRouterからソースコードを取得したところ、これまでのところ正常に動作しています。
private Activity getActivity() {
Context context = getContext();
while (context instanceof ContextWrapper) {
if (context instanceof Activity) {
return (Activity)context;
}
context = ((ContextWrapper)context).getBaseContext();
}
return null;
}
次の方法が役立ちます
Activity Host = (Activity) view.getContext()
;そしてview.isFocused()
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;
}
}
Android 7+では、ビューは外側のアクティビティにアクセスできなくなったため、view.getContext()
をアクティビティにキャストできなくなりました。
代わりに、以下のコードはAndroid 7+および6で機能します。
private static Activity getActivity(final View view) {
return (Activity) view.findViewById(Android.R.id.content).getContext();
}
[注:この回答を見た後、他の投稿を参照してください: https://stackoverflow.com/a/51100507/787399 ]
これには別のアプローチがあり、これは機能します。
私がしていることは、カスタムアプリケーション拡張クラスを作成し、マニフェストでマークすることです。
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);
}
...
それから私のcustomViews(ロケール設定とフォントを適用するためにビュー、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);
}
...
このソリューションは、継承の概念、デリゲートクラス、およびアプリケーションコンテキストにどこからでもアクセスできるという知識を使用します(マニフェスト内の独自のアプリケーション拡張クラスと置き換え可能)、およびアクティビティのライフサイクル。これがあなたの現在の活動であること。
これで、アプリケーションのロケールを変更したいのと同じように、ロケールを変更するのに最適な場所は、setContentView(layout_id)
メソッドでactivity
のonCreate(Bundle restoreState)
が呼び出される直前です。したがって、locale
が変更されるとすぐに、コントロールをdashboard/home
画面に送り返して、すぐに効果を確認する必要があります。
activity
のgetCurrentActivity()
からどれが現在のものであるかがわかるように、MyApplication
を更新することもできます。
アプリケーションのロケールを設定するには、 プログラムでロケールを設定 を参照してください
ハッピーコーディング... :-)
親アクティビティを取得するためのViewのKotlin拡張プロパティ:
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
}
}