web-dev-qa-db-ja.com

アンドロイドの文脈から活動を得る

これは私が困惑しています。

カスタムレイアウトクラス内からアクティビティメソッドを呼び出す必要があります。これの問題点は、レイアウト内からアクティビティにアクセスする方法がわからないことです。

ProfileView

public class ProfileView extends LinearLayout
{
    TextView profileTitleTextView;
    ImageView profileScreenImageButton;
    boolean isEmpty;
    ProfileData data;
    String name;

    public ProfileView(Context context, AttributeSet attrs, String name, final ProfileData profileData)
    {
        super(context, attrs);
        ......
        ......
    }

    //Heres where things get complicated
    public void onClick(View v)
    {
        //Need to get the parent activity and call its method.
        ProfileActivity x = (ProfileActivity) context;
        x.activityMethod();
    }
}

ProfileActivity

public class ProfileActivityActivity extends Activity
{
    //In here I am creating multiple ProfileViews and adding them to the activity dynamically.

    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.profile_activity_main);
    }

    public void addProfilesToThisView()
    {
        ProfileData tempPd = new tempPd(.....)
        Context actvitiyContext = this.getApplicationContext();
        //Profile view needs context, null, name and a profileData
        ProfileView pv = new ProfileView(actvitiyContext, null, temp, tempPd);
        profileLayout.addView(pv);
    }
}

上記のとおり、profileViewをプログラム的にインスタンス化し、それをactivityContextに渡しています。 2つの質問

  1. Profileviewに正しいコンテキストを渡していますか?
  2. コンテキストから包含アクティビティを取得する方法
161
OVERTONE

あなたのActivityから、あなたのレイアウトのthisとしてContextを渡すだけです:

ProfileView pv = new ProfileView(this, null, temp, tempPd);

その後、レイアウトにContextが入りますが、それが実際にあなたのActivityであることがわかり、必要なものが揃うようにキャストすることができます。

Activity activity = (Activity) context;
441
Boris Strandjev
  1. いいえ
  2. できない

Androidには2つの異なるコンテキストがあります。 1つはあなたのアプリケーション用(それをBIG用と呼びましょう)そしてもう1つは各ビュー(それをアクティビティコンテキストと呼びましょう)用です。

LinearLayoutはビューなので、アクティビティコンテキストを呼び出す必要があります。アクティビティから呼び出すには、単に "this"を呼び出します。とても簡単ですね。

使うとき

this.getApplicationContext();

あなたはBIGコンテキストを呼び出します。これはあなたのアプリケーションを説明するものでビューを管理することはできません。

Androidの大きな問題は、コンテキストがあなたの活動を呼び出せないことです。誰かがAndroidの開発を始めるときにこれを避けるのは大したことです。クラスをコーディングするためのより良い方法を見つける必要があります(または、「コンテキストコンテキスト」を「アクティビティアクティビティ」に置き換えて、必要に応じて「コンテキスト」にキャストする必要があります)。

よろしく。


私の答えを更新するためだけに。あなたのActivity contextを取得する最も簡単な方法はあなたのstaticActivityインスタンスを定義することです。例えば

public class DummyActivity extends Activity
{
    public static DummyActivity instance = null;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        // Do some operations here
    }

    @Override
    public void onResume()
    {
        super.onResume();
        instance = this;
    }

    @Override
    public void onPause()
    {
        super.onPause();
        instance = null;
    }
}

そして、あなたのTaskDialogViewで、あなたはあなたのActivity contextを得るためにそのような種類のコードを使うことができます:

if (DummyActivity.instance != null)
{
    // Do your operations with DummyActivity.instance
}
28
Manitoba

これは、フラグメントまたはカスタムビューのUI内で操作するときにContextActivityに変換するのに成功したものです。 ContextWrapperを再帰的に解凍するか、失敗した場合はnullを返します。

public Activity getActivity(Context context)
{
    if (context == null)
    {
        return null;
    }
    else if (context instanceof ContextWrapper)
    {
        if (context instanceof Activity)
        {
            return (Activity) context;
        }
        else
        {
            return getActivity(((ContextWrapper) context).getBaseContext());
        }
    }

    return null;
}
26
Theo

カスタムレイアウトクラス(Activityクラス以外)からアクティビティメソッドを呼び出す場合は、インターフェイスを使用してデリゲートを作成する必要があります。

それはテストされておらず、私はそれを正しくコーディングしました。しかし、私はあなたが望むものを達成する方法を伝えています。

まず最初にcreateとInterface

interface TaskCompleteListener<T> {
   public void onProfileClicked(T result);
}



public class ProfileView extends LinearLayout
{
    private TaskCompleteListener<String> callback;
    TextView profileTitleTextView;
    ImageView profileScreenImageButton;
    boolean isEmpty;
    ProfileData data;
    String name;

    public ProfileView(Context context, AttributeSet attrs, String name, final ProfileData profileData)
    {
        super(context, attrs);
        ......
        ......
    }
    public setCallBack( TaskCompleteListener<String> cb) 
    {
      this.callback = cb;
    }
    //Heres where things get complicated
    public void onClick(View v)
    {
        callback.onProfileClicked("Pass your result or any type");
    }
}

そしてこれを任意のアクティビティに実装します。

そしてそれを好きに呼ぶ

ProfileView pv = new ProfileView(actvitiyContext, null, temp, tempPd);
pv.setCallBack(new TaskCompleteListener
               {
                   public void onProfileClicked(String resultStringFromProfileView){}
               });
8
Xar E Ahmer

コンテキストは、アプリケーション、サービス、アクティビティなどです。

通常、アクティビティ内のビューのコンテキストはアクティビティ自体なので、このコンテキストをアクティビティにキャストすることはできますが、実際には常に行うことはできません。この場合、コンテキストはContextThemeWrapperになることもあります。

ContextThemeWrapperは最近のバージョンのAppCompatとAndroid(レイアウトのAndroid:theme属性のおかげで)で多用されているので、私は個人的にこのキャストを実行することは決してないでしょう。

簡単に言うと、ビュー内のコンテキストから確実にアクティビティを取得することはできません。パラメータとしてActivityを受け取るメソッドを呼び出すことによって、Activityをビューに渡します。

6
BladeCoder

ビューにgetApplicationContext()を使用することはありません。

ビューはアクティビティに関連付けられているため、常にアクティビティのコンテキストにする必要があります。また、あなたはカスタムテーマセットを持っているかもしれず、そしてアプリケーションのコンテキストを使用するとき、すべてのテーマは失われるでしょう。さまざまなバージョンのコンテキスト については、こちら を参照してください。

2
lomza

そして、コトリンでは:

tailrec fun Context.activity(): Activity? = when {
  this is Activity -> this
  else -> (this as? ContextWrapper)?.baseContext?.activity()
}
0
rjrjr

Convertアクティビティを使用しました

Activity activity = (Activity) context;
0
Samuel Ivan

この方法は役に立ちます。

public Activity getActivityByContext(Context context){

if(context == null){
    return null;
    }

else if((context instanceof ContextWrapper) && (context instanceof Activity)){
        return (Activity) context;
    }

else if(context instanceof ContextWrapper){
        return getActivity(((ContextWrapper) context).getBaseContext());
    }

return null;

    }

これが役に立つことを願っています..メリーコーディング!

0
Taslim Oseni

アクティビティはコンテキストを特殊化したものです。したがって、コンテキストがある場合は、どのアクティビティを使用するつもりか知っていて、単純にaからc;ここで、aはアクティビティで、cはコンテキストです。

Activity a = (Activity) c;
0
ACLima