web-dev-qa-db-fra.com

Comment obtenir l'activité d'hébergement à partir d'une vue?

J'ai un Activity avec 3 EditTexts et une vue personnalisée qui agit comme un clavier spécialisé pour ajouter des informations dans le EditTexts.

Actuellement, je passe le Activity dans la vue afin que je puisse obtenir le texte d'édition actuellement sélectionné et mettre à jour le contenu à partir du clavier personnalisé.

Existe-t-il un moyen de référencer l'activité parent et d'obtenir le EditText actuellement ciblé sans transmettre l'activité à la vue?

168
mAndroid

Je viens d'extraire ce code source du MediaRouter dans le bibliothèque de support officielle et jusqu'à présent, il fonctionne correctement:

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

les méthodes suivantes peuvent vous aider

  1. Activity Host = (Activity) view.getContext(); et
  2. view.isFocused()
166
Dipesh Rathod

J'ai pris Gominoréponse et je l'ai modifié pour qu'il s'adapte parfaitement à myUtils.Java afin que je puisse l'utiliser où et quand je le souhaite. J'espère que quelqu'un trouve ça utile :)

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

Dans Android 7+, la vue n'a plus accès à l'activité englobante. Par conséquent, view.getContext() ne peut plus être converti en activité.

Au lieu de cela, le code ci-dessous fonctionne dans Android 7+ et 6:

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

[Remarque: après avoir vu cette réponse, consultez mon autre message: https://stackoverflow.com/a/51100507/787399 ]

J'ai une approche différente à cet égard, et cela fonctionne.

Ce que je fais, je crée une classe étendue Application personnalisée et la marque dans manifest: -

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

et

Mon application dans le manifeste: -

...
<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">
...

Ensuite, dans mon BaseActivity (classe abstraite qui étend AppCompatActivity, cela signifie qu’elle doit être étendue à toutes les activités, avec des fonctionnalités communes, aux classes déléguées que vous souhaitez rendre accessible dans tous les composants, fragments, adaptateurs, etc.): -

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

Puis dans mes customViews (étend les vues, TextViews pour appliquer les paramètres régionaux et les polices): -

...
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);
    }
...

Cette solution utilise le concept d'héritage, de classes déléguées et de connaissance du fait que le contexte de l'application peut être consulté n'importe où (remplaçable avec votre propre classe étendue d'application dans le manifeste, et le cycle de vie de l'activité, où, sur résumé, vous pouvez indiquer l'application (MyApplication). que c'est votre activité actuelle.

Maintenant, tout comme vous voulez changer les paramètres régionaux de l'application, le meilleur endroit pour le changer est juste avant que setContentView(layout_id) d'un activity soit appelé dans la méthode onCreate(Bundle restoreState). Par conséquent, dès que locale est modifié, vous devez renvoyer le contrôle à votre écran dashboard/home Afin de voir immédiatement l'effet.

Vous pouvez également actualiser votre activity car vous savez lequel est le courant de getCurrentActivity() de votre MyApplication.

Pour définir les paramètres régionaux de votre application, voir Définir les paramètres régionaux par programmation

Bonne codage ... :-)

0
Abhinav Saxena

Propriété d'extension Kotlin pour que View récupère l'activité parent:

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