【问题标题】:can we call startActivityForResult from adapter?How to get the response?我们可以从适配器调用 startActivityForResult 吗?如何获得响应?
【发布时间】:2013-11-16 07:25:18
【问题描述】:

是否可以在适配器中使用方法startActivtyForResult?那么如何获得响应?在哪里执行回调函数?

【问题讨论】:

  • 创建接口并在您的适配器上实现传递您想要的任何数据并调用adapter.yourmethodname()表单onActivityResult..

标签: android


【解决方案1】:

是的,这是可能的。您需要适配器中 Context 的引用并调用活动:

Intent intent = new Intent(context, TargetActivity.class);
((Activity) context).startActivityForResult(intent, REQUEST_FOR_ACTIVITY_CODE);

注意上下文必须是活动上下文,否则此代码将失败。

您像往常一样使用onActivityResult 在封闭活动中获得结果。

所以,例如:

在您的适配器中:

MyAdapter(Context context) {
    mContext = context;
}

public View getView(int position, View convertView, ViewGroup parent) {
    …
    open.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            …
            Activity origin = (Activity)mContext;
            origin.startActivityForResult(new Intent(mContext, SecondActivity.class), requestCode);
        }   
    });
    …
}

public  void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("MyAdapter", "onActivityResult");
}

在您的第二个活动中,照常使用setResultfinish

在您的主要活动中,捕获结果并传递给适配器回调:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    mAdapter.onActivityResult(requestCode, resultCode, data);
}

【讨论】:

  • 在自定义适配器中我得到 ProjectListAdapter 类型的 onActivityResult(int, int, Intent) 方法必须覆盖或实现超类型方法
  • onActivityResult 必须在 Activity 中,而不是在适配器中。从活动中,您调用适配器中的另一个方法。
  • 我编辑了答案以添加示例代码。现在我觉得很清楚了。
  • @JohnJoe 调用活动
【解决方案2】:

是的。您可以从适配器调用 startactivityforresult()。

有两种情况- 1.从activity调用适配器,在activity中需要onActivityResult。 2.从Fragment调用适配器,需要onActivityResult在fragment中。

案例一:在Activity中获取OnActivityResult,然后将Activity的引用传递给适配器构造函数

public MyAdapter(Activity pActivity, List<MyBean> pList) {
        mList = pList;
        mActivity = pActivity;       
    }

现在开始ActivityForResult

Intent intent = new Intent(context, TargetActivity.class);
mActivity.startActivityForResult(intent, REQUEST_FOR_ACTIVITY_CODE);

案例2:在Fragment中获取OnActivityResult,然后将fragment的引用传递给适配器构造函数

 public MyGamesAdapter(Fragment pContext, List<MyBean> pList,) {
        mList = pList;
        mMyFragment =pContext;
    }

 Intent intent = new Intent(context, TargetActivity.class);
    mMyFragment.startActivityForResult(intent, REQUEST_FOR_ACTIVITY_CODE);

现在在活动或片段中覆盖 OnActivityResult 并获取结果。

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    mAdapter.onActivityResult(requestCode, resultCode, data);
}

【讨论】:

  • 见道格拉斯·德鲁蒙德的回答
【解决方案3】:

我使用了一种更简单的方法。在您的活动/片段中创建一个公共函数,它将为结果调用活动

public void startActivityFromAdapter(String Arguments){
    //todo: add steps you would like to compute
    startActivityForResult(Intent, REQ_CODE);
}

创建适配器时,将当前活动/片段作为参数传递。我将以活动为例

public MyAdaper(Activity activity, ArrayList<String> list){
    this.activity = activity;
    this.list = list;
}

通过将 Activity 转换为 Activity 类从视图中调用公共函数

 @Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    
    holder.applyBt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            ((ActivityName) activity).startActivityFromAdapter(list.get(position).code);
        }
    });
}

并在您的调用活动/片段中使用 onActivityResult

编辑:

我不建议使用上述方法,因为它限制适配器只能用于一项活动。更好的是你必须使用相同的接口

创建一个接口和一个 onClickFunction

public interface AdapterInteface{
    void onBtClick(int Position)
}

现在当您创建适配器时,接受此接口作为参数并在单击按钮时调用该函数

public MyAdaper(Activity activity, ArrayList<String> list, AdapterInterface adapterInterface){
    this.activity = activity;
    this.list = list;
    this.adapterInterface = adapterInterface
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    
    holder.applyBt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            adapterInterface.onBtClicked(position)
        }
    });
}

在您的活动/片段上实现此接口,并将您的活动/片段上的 onBtClicked 函数覆盖为 startActivityForResult

【讨论】:

    【解决方案4】:

    像这样在活动类中写一个函数

    public void startCommentActivity(Intent i){
        startActivityForResult(i, 100);
    }
    

    在适配器类中调用它

    mActivity.startCommentActivity(intent);
    

    【讨论】:

    • 之前需要:mActivity = (MyActivity) context;
    • 看不到主Activity的这个方法。编译器不允许这样做。
    【解决方案5】:

    androidX Activity 实现has a new set of APIs 可以在任何你想要的地方获得活动结果。

    此功能取代旧的 startActivityForResult() / onActivityResult()onRequestPermissionsResult(),它们已在 ComponentActivity 中被弃用。

    开始第二个活动并期望从中获得结果的示例:

    final Intent intent = new Intent(context, SecondActivity.class);
    final ActivityResultContracts.StartActivityForResult contract = new ActivityResultContracts.StartActivityForResult();
    
    activity.registerForActivityResult(contract, result ->
        YourClass.manageTheResult(result))
        .launch(intent);
    

    请求用户权限的示例:

    final String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO};
    
    final ActivityResultContracts.RequestMultiplePermissions contract = new ActivityResultContracts.RequestMultiplePermissions();
    
    activity.registerForActivityResult(contract, result -> {
        YourClass.manageTheResult(permissions, result);
    }).launch(permissions);
    

    管理“发送者意图”的示例:

    final IntentSenderRequest request = new IntentSenderRequest.Builder(yourIntentSender)
        .build();
    
    final ActivityResultContracts.StartIntentSenderForResult contract = new ActivityResultContracts.StartIntentSenderForResult();
    
    activity.registerForActivityResult(contract, result ->
        YourClasss.manageTheResult(result))
        .launch(request);
    

    【讨论】:

    • 虽然我们现在确实有更新的 API,但这并不能回答从适配器执行此操作的问题。
    猜你喜欢
    • 1970-01-01
    • 2018-12-05
    • 2021-08-12
    • 1970-01-01
    • 2012-11-28
    • 2013-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-20
    相关资源
    最近更新 更多