2017.6.6 TintContextWrapper cannot be cast to ...Activity

1483 ワード

問題の説明:
ビューがActivityのContentViewに描画する場合、そのContextはこのActivityに関連付けられているに違いない.そこで、ビューで直接Activityメソッドを使用する場合(最も一般的な方法はActivity.startActivity()メソッドであるべきである)、ビューにActivityオブジェクトを渡す必要はないと考える.一般的にこのActivityオブジェクトをViewで取得するのは簡単です.次のコードでいいです.
Activity activity = (Activity) getContext();

ただし、ViewがAppCompat系のViewを継承する場合(AppCompatTextView、AppCompatImageViewなど)、次の方法で次の例外が発生する可能性があります.
  View view1 = ((Activity) view.getContext()).getLayoutInflater().inflate(R.layout.date_dialog, null);
**java.lang.ClassCastException: android.support.v7.widget.TintContextWrapper cannot be cast to ...Activity**

问题解决:原因を知るのは简単です.簡単にContextWrapperを使えます.getBaseContext()はこのActivityを得る.しかし、ContextWrapperからActivityを剥がしたほうが安全です.
/**
     * try get host activity from view.
     * views hosted on floating window like dialog and toast will sure return null.
     * @return host activity; or null if not available
     */
    public static Activity getActivityFromView(View view) {
        Context context = view.getContext();
        while (context instanceof ContextWrapper) {
            if (context instanceof Activity) {
                return (Activity) context;
            }
            context = ((ContextWrapper) context).getBaseContext();
        }
        return null;
    }

以上のような方法で、ViewからActivityを取得する問題を汎用的に解決することができる.実は、グーグルv 7パッケージのAndroid.support.v7.app.MediaRouteButtonはそうしました