web-dev-qa-db-ja.com

ビューからホスティングアクティビティを取得する方法は?

3つのActivitysを持つEditTextと、EditTextsに情報を追加するための専用キーボードとして機能するカスタムビューがあります。

現在、ビューにActivityを渡しているので、現在フォーカスされている編集テキストを取得し、カスタムキーボードからコンテンツを更新できます。

ビューにアクティビティを渡すことなく、親アクティビティを参照し、現在フォーカスされているEditTextを取得する方法はありますか?

168
mAndroid

公式サポートライブラリ のMediaRouterからソースコードを取得したところ、これまでのところ正常に動作しています。

private Activity getActivity() {
    Context context = getContext();
    while (context instanceof ContextWrapper) {
        if (context instanceof Activity) {
            return (Activity)context;
        }
        context = ((ContextWrapper)context).getBaseContext();
    }
    return null;
}
266
Gomino

次の方法が役立ちます

  1. Activity Host = (Activity) view.getContext();そして
  2. view.isFocused()
166
Dipesh Rathod

Gominoanswer を取得し、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;
    }
}
6
brownieGirl

Android 7+では、ビューは外側のアクティビティにアクセスできなくなったため、view.getContext()をアクティビティにキャストできなくなりました。

代わりに、以下のコードはAndroid 7+および6で機能します。

private static Activity getActivity(final View view) {
    return (Activity) view.findViewById(Android.R.id.content).getContext();
}
0
Sebas LG

[注:この回答を見た後、他の投稿を参照してください: 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)メソッドでactivityonCreate(Bundle restoreState)が呼び出される直前です。したがって、localeが変更されるとすぐに、コントロールをdashboard/home画面に送り返して、すぐに効果を確認する必要があります。

activitygetCurrentActivity()からどれが現在のものであるかがわかるように、MyApplicationを更新することもできます。

アプリケーションのロケールを設定するには、 プログラムでロケールを設定 を参照してください

ハッピーコーディング... :-)

0
Abhinav Saxena

親アクティビティを取得するための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
    }
}
0
Fedir Tsapana