这个问题难倒了我。

我需要从自定义布局类中调用一个活动方法。这样做的问题是,我不知道如何从布局内访问活动。

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与它一起传入。两个问题:

我是否将正确的上下文传递到Profileview? 我如何从上下文获得包含活动?


当前回答

这个方法应该是有用的..!

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;

    }

我希望这能有所帮助。编码快乐!

其他回答

实时数据回调怎么样,

class ProfileView{
    private val _profileViewClicked = MutableLiveData<ProfileView>()
    val profileViewClicked: LiveData<ProfileView> = _profileViewClicked
}

class ProfileActivity{

  override fun onCreateView(...){

    profileViewClicked.observe(viewLifecycleOwner, Observer { 
       activityMethod()
    })
  }

}

从你的Activity中,传入这个作为布局的Context:

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

然后你会在布局中有一个Context,但你会知道它实际上是你的Activity,你可以转换它,这样你就有了你需要的东西:

Activity activity = (Activity) context;

没有 你不能

在Android中有两种不同的上下文。一个用于您的应用程序(我们称之为BIG),另一个用于每个视图(我们称之为活动上下文)。

linearLayout是一个视图,所以你必须调用activity context。要从活动中调用它,只需调用“this”。很简单,不是吗?

当你使用

this.getApplicationContext();

调用BIG上下文,它描述应用程序,不能管理视图。

Android的一个大问题是context不能调用你的activity。当有人开始Android开发时,要避免这种情况是很重要的。您必须找到更好的方法来编写类(或将“Context Context”替换为“Activity Activity”,并在需要时将其转换为“Context”)。

的问候。


更新一下我的答案。获取Activity上下文的最简单方法是在Activity中定义一个静态实例。例如

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

然后,在你的任务,对话框,视图中,你可以使用那种代码来获得你的活动上下文:

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

如果您想从自定义布局类(非活动类)中调用活动方法。您应该使用接口创建委托。

它是未经测试的,我编码它的权利。但我在传达一种实现你想要的方式。

首先创建和接口

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

Activity是Context的专门化,所以,如果你有一个Context,你已经知道你打算使用哪个Activity,并且可以简单地将a转换为c;其中a是活动,c是上下文。

Activity a = (Activity) c;