从 android 中的另一个 class 调用 mainactivity 中的方法
calling method in mainactivity from another class in android
我有一个带有文本视图和三个图像按钮的列表视图。单击其中一个图像按钮时,我试图从主页调用方法。但是我得到了这个错误:
04-19 13:02:48.021 30996-30996/com.example.lama.audiotest E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.lama.audiotest, PID: 30996
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
at android.content.ContextWrapper.getResources(ContextWrapper.java:92)
at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:81)
at android.media.MediaPlayer.create(MediaPlayer.java:1007)
at android.media.MediaPlayer.create(MediaPlayer.java:990)
at com.example.lama.audiotest.Main3Activity.play(Main3Activity.java:35)
at com.example.lama.audiotest.CustomAdapter.onClick(CustomAdapter.java:83)
at android.view.View.performClick(View.java:5697)
at android.view.View$PerformClick.run(View.java:22526)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
我尝试移动这条线:
mp= MediaPlayer.create(Main3Activity.this,R.raw.alfatiha);
到onCreate();然后它起作用了,但是我想根据播放方法获得的字符串播放不同的音频。如何解决?
我的主要活动:
public class Main3Activity extends Activity {
private static final String TAG = Main3Activity.class.getSimpleName();
static MediaPlayer mp;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
ListView listView = (ListView) findViewById(R.id.list_data);
CustomAdapter customAdapter = new CustomAdapter();
listView.setAdapter(customAdapter);
}
public void play(String name){
if (name.equals("الفاتحه")){
mp= MediaPlayer.create(Main3Activity.this,R.raw.alfatiha);
mp.start();
}
}
public void pause(){
mp.pause();
}
public void stop(){
mp.stop();
}
}
我的列表适配器:
public class CustomAdapter extends BaseAdapter {
Main3Activity main= new Main3Activity();
private static final String TAG = CustomAdapter.class.getSimpleName();
ArrayList<DataModel> listArray;
public CustomAdapter() {
listArray = new ArrayList<DataModel>(5);
listArray.add(new DataModel("الفاتحه", 5, 1.8, "Java"));
listArray.add(new DataModel("البقرة", 10, 2.8, "Python"));
listArray.add(new DataModel("ال عمران", 15, 3.8, "Django"));
}
@Override
public int getCount() {
return listArray.size(); // total number of elements in the list
}
@Override
public Object getItem(int i) {
return listArray.get(i); // single item in the list
}
@Override
public long getItemId(int i) {
return i; // index number
}
@Override
public View getView(int index, View view, final ViewGroup parent) {
if (view == null) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
view = inflater.inflate(R.layout.list, parent, false);
}
final MediaPlayer mp;
final DataModel dataModel = listArray.get(index);
TextView textView = (TextView) view.findViewById(R.id.Itemname);
textView.setText(dataModel.getName());
ImageButton play = (ImageButton) view.findViewById(R.id.btnplay);
ImageButton pause = (ImageButton) view.findViewById(R.id.btnpause);
ImageButton stop = (ImageButton) view.findViewById(R.id.btnstop);
play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
main.play(dataModel.getName());
// Toast.makeText(parent.getContext(), "you clicked play for: " + dataModel.getName(), Toast.LENGTH_SHORT).show();
}
});
pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
main.pause();
// Toast.makeText(parent.getContext(), "you clicked pause for: " + dataModel.getName(), Toast.LENGTH_SHORT).show();
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
main.stop();
// Toast.makeText(parent.getContext(), "you clicked stop for: " + dataModel.getName(), Toast.LENGTH_SHORT).show();
}
});
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "string: " + dataModel.getName());
Log.d(TAG, "int: " + dataModel.getAnInt());
Log.d(TAG, "double: " + dataModel.getaDouble());
Log.d(TAG, "otherData: " + dataModel.getOtherData());
Toast.makeText(parent.getContext(), "view clicked: " + dataModel.getOtherData(), Toast.LENGTH_SHORT).show();
}
});
return view;
}
}
您需要能够从适配器引用外部 class。
我假设适配器是在Activityclass里面定义的。
然后你需要做的就是直接调用方法,不带前缀,它会找到它。
或者,为了清楚起见,您可以使用:
Main3Activity.this.play(xxxx)
在 onClickListener 内部。
在您的 CustomAdapter 中,您正在创建 Main3Activity 的新实例,而不是将您当前的 Main3Activity 实例作为参数传递给您的自定义适配器。因此,当您尝试访问 Main3Activity 方法时,您会收到空指针异常。
要解决您的问题,请修改您的 CustomAdapter 构造函数以允许 Main3Activity 作为参数:
public class CustomAdapter extends BaseAdapter {
Main3Activity main;
private static final String TAG = CustomAdapter.class.getSimpleName();
ArrayList<DataModel> listArray;
public CustomAdapter(Main3Activity main) {
this.main = main;
listArray = new ArrayList<DataModel>(5);
listArray.add(new DataModel("الفاتحه", 5, 1.8, "Java"));
listArray.add(new DataModel("البقرة", 10, 2.8, "Python"));
listArray.add(new DataModel("ال عمران", 15, 3.8, "Django"));
}
然后,返回到您的 Main3Activity.class,将 activity 实例传递给 CustomAdapter:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
ListView listView = (ListView) findViewById(R.id.list_data);
CustomAdapter customAdapter = new CustomAdapter(this);
listView.setAdapter(customAdapter);
}
在您的适配器 class 中,您正在创建一个 Main3Activity 的新实例,这是一个不同的实例,这就是您获得 NullPointerException 的原因。您需要做的就是下面给出的。
在您的适配器中创建一个接口 class。
public interface ItemActionListener{
void onpause(DataModel model);
void onStop(DataModel model);
void onPlay(DataModel model);
}
private ItemActionListener onItemActionlListener;
为此接口创建一个setter
public void setOnItemActionlListener(ItemActionListener onItemActionlListener) {
this.onItemActionlListener = onItemActionlListener;
}
在您的 activity class 中使用此界面,如下所示。
CustomAdapter customAdapter = new CustomAdapter();
customAdapter.setOnItemActionlListener(onItemActionListener);
listView.setAdapter(customAdapter);
private CustomAdapter .ItemActionListener onItemActionListener=new CustomAdapter .ItemActionListener() {
@Override
public void onpause(DataModel model) {
//Call your pause() method written in activity class
pause();
}
@Override
public void onStop(DataModel model) {
//Call your stop() method written in activity class
stop();
}
@Override
public void onPlay(DataModel model) {
//Call your play() method written in activity class
play();
}
};
In your adapter class
pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(onItemActionlListener !=null){
onItemActionlListener.onpause(dataModel);
}
}
});
我有一个带有文本视图和三个图像按钮的列表视图。单击其中一个图像按钮时,我试图从主页调用方法。但是我得到了这个错误:
04-19 13:02:48.021 30996-30996/com.example.lama.audiotest E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.lama.audiotest, PID: 30996
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
at android.content.ContextWrapper.getResources(ContextWrapper.java:92)
at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:81)
at android.media.MediaPlayer.create(MediaPlayer.java:1007)
at android.media.MediaPlayer.create(MediaPlayer.java:990)
at com.example.lama.audiotest.Main3Activity.play(Main3Activity.java:35)
at com.example.lama.audiotest.CustomAdapter.onClick(CustomAdapter.java:83)
at android.view.View.performClick(View.java:5697)
at android.view.View$PerformClick.run(View.java:22526)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
我尝试移动这条线:
mp= MediaPlayer.create(Main3Activity.this,R.raw.alfatiha);
到onCreate();然后它起作用了,但是我想根据播放方法获得的字符串播放不同的音频。如何解决?
我的主要活动:
public class Main3Activity extends Activity {
private static final String TAG = Main3Activity.class.getSimpleName();
static MediaPlayer mp;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
ListView listView = (ListView) findViewById(R.id.list_data);
CustomAdapter customAdapter = new CustomAdapter();
listView.setAdapter(customAdapter);
}
public void play(String name){
if (name.equals("الفاتحه")){
mp= MediaPlayer.create(Main3Activity.this,R.raw.alfatiha);
mp.start();
}
}
public void pause(){
mp.pause();
}
public void stop(){
mp.stop();
}
}
我的列表适配器:
public class CustomAdapter extends BaseAdapter {
Main3Activity main= new Main3Activity();
private static final String TAG = CustomAdapter.class.getSimpleName();
ArrayList<DataModel> listArray;
public CustomAdapter() {
listArray = new ArrayList<DataModel>(5);
listArray.add(new DataModel("الفاتحه", 5, 1.8, "Java"));
listArray.add(new DataModel("البقرة", 10, 2.8, "Python"));
listArray.add(new DataModel("ال عمران", 15, 3.8, "Django"));
}
@Override
public int getCount() {
return listArray.size(); // total number of elements in the list
}
@Override
public Object getItem(int i) {
return listArray.get(i); // single item in the list
}
@Override
public long getItemId(int i) {
return i; // index number
}
@Override
public View getView(int index, View view, final ViewGroup parent) {
if (view == null) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
view = inflater.inflate(R.layout.list, parent, false);
}
final MediaPlayer mp;
final DataModel dataModel = listArray.get(index);
TextView textView = (TextView) view.findViewById(R.id.Itemname);
textView.setText(dataModel.getName());
ImageButton play = (ImageButton) view.findViewById(R.id.btnplay);
ImageButton pause = (ImageButton) view.findViewById(R.id.btnpause);
ImageButton stop = (ImageButton) view.findViewById(R.id.btnstop);
play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
main.play(dataModel.getName());
// Toast.makeText(parent.getContext(), "you clicked play for: " + dataModel.getName(), Toast.LENGTH_SHORT).show();
}
});
pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
main.pause();
// Toast.makeText(parent.getContext(), "you clicked pause for: " + dataModel.getName(), Toast.LENGTH_SHORT).show();
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
main.stop();
// Toast.makeText(parent.getContext(), "you clicked stop for: " + dataModel.getName(), Toast.LENGTH_SHORT).show();
}
});
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "string: " + dataModel.getName());
Log.d(TAG, "int: " + dataModel.getAnInt());
Log.d(TAG, "double: " + dataModel.getaDouble());
Log.d(TAG, "otherData: " + dataModel.getOtherData());
Toast.makeText(parent.getContext(), "view clicked: " + dataModel.getOtherData(), Toast.LENGTH_SHORT).show();
}
});
return view;
}
}
您需要能够从适配器引用外部 class。
我假设适配器是在Activityclass里面定义的。 然后你需要做的就是直接调用方法,不带前缀,它会找到它。
或者,为了清楚起见,您可以使用:
Main3Activity.this.play(xxxx)
在 onClickListener 内部。
在您的 CustomAdapter 中,您正在创建 Main3Activity 的新实例,而不是将您当前的 Main3Activity 实例作为参数传递给您的自定义适配器。因此,当您尝试访问 Main3Activity 方法时,您会收到空指针异常。
要解决您的问题,请修改您的 CustomAdapter 构造函数以允许 Main3Activity 作为参数:
public class CustomAdapter extends BaseAdapter {
Main3Activity main;
private static final String TAG = CustomAdapter.class.getSimpleName();
ArrayList<DataModel> listArray;
public CustomAdapter(Main3Activity main) {
this.main = main;
listArray = new ArrayList<DataModel>(5);
listArray.add(new DataModel("الفاتحه", 5, 1.8, "Java"));
listArray.add(new DataModel("البقرة", 10, 2.8, "Python"));
listArray.add(new DataModel("ال عمران", 15, 3.8, "Django"));
}
然后,返回到您的 Main3Activity.class,将 activity 实例传递给 CustomAdapter:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
ListView listView = (ListView) findViewById(R.id.list_data);
CustomAdapter customAdapter = new CustomAdapter(this);
listView.setAdapter(customAdapter);
}
在您的适配器 class 中,您正在创建一个 Main3Activity 的新实例,这是一个不同的实例,这就是您获得 NullPointerException 的原因。您需要做的就是下面给出的。
在您的适配器中创建一个接口 class。
public interface ItemActionListener{
void onpause(DataModel model);
void onStop(DataModel model);
void onPlay(DataModel model);
}
private ItemActionListener onItemActionlListener;
为此接口创建一个setter
public void setOnItemActionlListener(ItemActionListener onItemActionlListener) {
this.onItemActionlListener = onItemActionlListener;
}
在您的 activity class 中使用此界面,如下所示。
CustomAdapter customAdapter = new CustomAdapter();
customAdapter.setOnItemActionlListener(onItemActionListener);
listView.setAdapter(customAdapter);
private CustomAdapter .ItemActionListener onItemActionListener=new CustomAdapter .ItemActionListener() {
@Override
public void onpause(DataModel model) {
//Call your pause() method written in activity class
pause();
}
@Override
public void onStop(DataModel model) {
//Call your stop() method written in activity class
stop();
}
@Override
public void onPlay(DataModel model) {
//Call your play() method written in activity class
play();
}
};
In your adapter class
pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(onItemActionlListener !=null){
onItemActionlListener.onpause(dataModel);
}
}
});