Ali Bagheri
Ali Bagheri

Reputation: 3419

How get Activity from a view?

I have a extended class .i need activity.

public class RequestRecord extends RelativeLayout
{
    public RequestRecord(Context context)
    {
        super(context);
        ContextWrapper ctx = ((ContextWrapper) getContext());
        ScrollView sv = (ScrollView) ((Activity) 
                                   ctx).findViewById(R.id.myReqList_scroll);
   }
}

Exception: java.lang.ClassCastException: android.app.ContextImpl cannot be cast to android.content.ContextWrapper

help me?

Upvotes: 1

Views: 2956

Answers (4)

cincy_anddeveloper
cincy_anddeveloper

Reputation: 1152

What ever context object is being returned by getContext() doesn't extend ContextWrapper. Further, View shouldn't access their parent Activity, nor should they even know about an Activity. Why would a view need to be aware of another view in such manner. The proper way, if you want to access a sibling view, would be to get your parent ViewGroup and iterate over it's children. Note, while in the constructor, you don't have a parent View yet so calling getParent() will return null. You need to do that work during any of the on* methods such as: onMeasure(...), onLayout(), onSizeChanged and onSizeChanged.

Upvotes: 1

Milan Jurkulak
Milan Jurkulak

Reputation: 625

fun getActivity(context: Context?): Activity? {
    return if (context is Activity) context
    else if (context is ContextThemeWrapper) getActivity(context.getBaseContext())
    else if (context?.javaClass?.simpleName?.contentEquals("ContextImpl") ?: false)
        getActivity(getOuterContext(context))
    else {
        while (context is ContextWrapper) {
            if (context is Activity)
                context
            else
                getActivity(context.getBaseContext())
        }
        null
    }
}

fun getOuterContext(context: Context?): Context? {
    try {
        val f: Field? = context?.javaClass?.getDeclaredField("mOuterContext")
        f?.setAccessible(true)
        return if (f == null) null else (f.get(context) as Context?)
    } catch (e: java.lang.Exception) {
        e.printStackTrace()
        return null
    }
}

Upvotes: 0

EpicPandaForce
EpicPandaForce

Reputation: 81539

This used to always work for me, when I obtained the view from inflation rather than with some tricky manual instantiation (for example, it won't work if the view is created with application context):

@NonNull
public static <T extends Activity> T findActivity(@NonNull Context context) {
    if(context == null) {
        throw new IllegalArgumentException("Context cannot be null!");
    }
    if(context instanceof Activity) {
        // noinspection unchecked
        return (T) context;
    } else {
        ContextWrapper contextWrapper = (ContextWrapper) context;
        Context baseContext = contextWrapper.getBaseContext();
        if(baseContext == null) {
            throw new IllegalStateException("Activity was not found as base context of view!");
        }
        return findActivity(baseContext);
    }
}

Upvotes: 2

Akhil
Akhil

Reputation: 6697

If ScrollView myReqList_scroll is inside your RequestRecord, you can call like this

public class RequestRecord extends RelativeLayout
{
    public RequestRecord(Context context)
    {
        super(context);
        ScrollView sv = (ScrollView) findViewById(R.id.myReqList_scroll);
    }
}

Upvotes: 0

Related Questions