从适配器调用Activity方法

时间:2012-08-27 12:45:47

标签: android list adapter addressing

是否可以从Activity调用ListAdapter中定义的方法?

(我想在Button行中生成list's,当点击此按钮时,它应该执行相应的Activity中定义的方法。我尝试设置onClickListener在我的ListAdapter但我不知道如何调用这种方法,它的路径是什么......)

当我使用Activity.this.method()时出现以下错误:

No enclosing instance of the type Activity is accessible in scope

任何想法?

9 个答案:

答案 0 :(得分:279)

是的,你可以。

在适配器中添加新字段:

private Context mContext;

在适配器构造函数中添加以下代码:

public AdapterName(......, Context context) {
  //your code.
  this.mContext = context;
}

在适配器的getView(...)中:

Button btn = (Button) convertView.findViewById(yourButtonId);
btn.setOnClickListener(new Button.OnClickListener() {
  @Override
  public void onClick(View v) {
    if (mContext instanceof YourActivityName) {
      ((YourActivityName)mContext).yourDesiredMethod();
    }
  }
});

替换为您自己的类名,您可以在其中查看代码,活动等。

如果您需要将同一个适配器用于多个活动,那么:

创建界面

public interface IMethodCaller {
    void yourDesiredMethod();
}

在此方法调用功能所需的活动中实现此接口。

然后在Adapter getView()中,调用如:

Button btn = (Button) convertView.findViewById(yourButtonId);
btn.setOnClickListener(new Button.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (mContext instanceof IMethodCaller) {
            ((IMethodCaller) mContext).yourDesiredMethod();
        }
    }
});

你完成了。如果您需要将此适配器用于不需要此调用机制的活动,则代码将不会执行(如果检查失败)。

答案 1 :(得分:112)

你可以这样做:

声明接口:

public interface MyInterface{
    public void foo();
}

让你的活动改变它:

public class MyActivity extends Activity implements MyInterface{
    public void foo(){
        //do stuff
    }
}

然后将您的活动传递给ListAdater:

public MyAdapter extends BaseAdater{
    private MyInterface listener;

    public MyAdapter(MyInterface listener){
        this.listener = listener;
    }
}

在适配器的某个地方,当你需要调用那个Activity方法时:

listener.foo();

答案 2 :(得分:60)

原件:

我理解当前的答案,但需要一个更清晰的例子。以下是我与Adapter(RecyclerView.Adapter)和Activity一起使用的示例。

在您的活动中:

这将实现我们interface中的Adapter。在此示例中,当用户点击RecyclerView中的项目时会调用它。

public class MyActivity extends Activity implements AdapterCallback {

    private MyAdapter myAdapter;

    @Override
    public void onMethodCallback() {
       // do something
    }

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

        myAdapter = new MyAdapter(this);
    }
}

在适配器中:

Activity中,我们启动了Adapter并将其作为参数传递给构造函数。这将为我们的回调方法启动interface。您可以看到我们使用回调方法进行用户点击。

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private AdapterCallback adapterCallback;

    public MyAdapter(Context context) {
        try {
            adapterCallback = ((AdapterCallback) context);
        } catch (ClassCastException e) {
            throw new ClassCastException("Activity must implement AdapterCallback.", e);
        }
    }

    @Override
    public void onBindViewHolder(MyAdapter.ViewHolder viewHolder, int position) {
        // simple example, call interface here
        // not complete
        viewHolder.itemView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    adapterCallback.onMethodCallback();
                } catch (ClassCastException e) {
                   // do something
                }
            }
        });
    }

    public static interface AdapterCallback {
        void onMethodCallback();
    }
}

答案 3 :(得分:12)

基本和简单。

在你的适配器中使用它。

private View.OnClickListener mSubmitButtonOnClick = new View.OnClickListener(){ @Override public void onClick(View v) { if(getArray() != null) { insertRecord(getArray()); finish(); } else{ Toast.makeText(AddClaimFormPage.this, "Please select at least one item to claim.", Toast.LENGTH_SHORT).show(); } } };

答案 4 :(得分:6)

另一种方法是::

在适配器中写一个方法让我们说 public void callBack(){}。

现在,在活动中为适配器创建对象时会覆盖此方法。 在适配器中调用方法时,将调用覆盖方法。

Myadapter adapter = new Myadapter() {
  @Override
  public void callBack() {
    // dosomething
  }
};

答案 5 :(得分:1)

对于Kotlin:

在适配器中,只需致电

(context as Your_Activity_Name).yourMethod()

答案 6 :(得分:1)

在Kotlin中,现在有了使用lambda函数的更简洁的方法,不需要接口:

class MyAdapter(val adapterOnClick: (Any) -> Unit) {
    fun setItem(item: Any) {
        myButton.setOnClickListener { adapterOnClick(item) }
    }
}

class MyActivity {
    override fun onCreate(savedInstanceState: Bundle?) {
        var myAdapter = MyAdapter { item -> doOnClick(item) }
    }


    fun doOnClick(item: Any) {

    }
}

答案 7 :(得分:0)

if (parent.getContext() instanceof yourActivity) {
  //execute code
}

如果GroupView getView() adapter yourActivity parent方法var interaction: UIDocumentInteractionController? interaction = UIDocumentInteractionController(url: URL(string: "<PDF FILE PATH>")!) interaction.delegate = self interaction.presentPreview(animated: true) // IF SHOW DIRECT 的{​​{1}}活动interaction.presentOpenInMenu(from: /*<SOURCE BUTTON FRAME>*/, in: self.view, animated: true)

,则此条件将允许您执行某些操作

注意:UIDocumentInteractionControllerDelegate是GroupView

答案 8 :(得分:0)

对于 kotlin,您可以执行以下操作:

if(context is MainActivity){ context.functionToCall(values) }