Activity
で定義されているメソッドをListAdapter
から呼び出すことはできますか?
(list's
行にButton
を作成し、このボタンをクリックすると、対応するアクティビティで定義されているメソッドを実行する必要があります。onClickListener
にListAdapter
を設定しようとしましたが、このメソッドの呼び出し方法がわかりません。その道は...)
Activity.this.method()
を使用すると、次のエラーが表示されます。
No enclosing instance of the type Activity is accessible in scope
何か案が ?
はい、できます。
アダプターに新しいフィールドを追加します。
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();
}
このメソッド呼び出し機能を使用するために必要なアクティビティにこのインターフェイスを実装します。
次に、アダプター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();
}
}
});
できました。この呼び出しメカニズムを必要としないアクティビティにこのアダプターを使用する必要がある場合、コードは実行されません(チェックが失敗した場合)。
次の方法で実行できます。
インターフェースの宣言:
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();
私は現在の答えを理解していますが、より明確な例を必要としました。 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();
}
}
基本およびシンプル
アダプタでこれを使用します。
((YourParentClass) context).functionToRun();
もう1つの方法は次のとおりです。
アダプタにメソッドを書くと、public void callBack(){}と言えます。
これで、アクティビティ中のアダプターのオブジェクトを作成するときに、このメソッドをオーバーライドします。アダプターでメソッドを呼び出すと、オーバーライドメソッドが呼び出されます。
Myadapter adapter = new Myadapter() {
@Override
public void callBack() {
// dosomething
}
};
Kotlinの場合:
アダプタで、単に呼び出す
(context as Your_Activity_Name).yourMethod()
if (parent.getContext() instanceof yourActivity) {
//execute code
}
GroupView
のgetView()
メソッドからビューを要求するadapter
を持つアクティビティがyourActivity
である場合、この条件により何かを実行できます。
注:parent
はそのGroupViewです