Reputation: 1858
Here is the view class that I have created.
public class WorkoutView extends LinearLayout implements View.OnClickListener {
public Spinner spinnerDifficulty, spinnerTime, spinnerMuscleGroup, spinnerSets, spinnerReps;
public EditText etWorkoutName;
public Button btnRemoveWorkout;
String workoutName, muscleGroup, sets, reps;
LayoutInflater inflater;
Context mContext;
ButtonPressInterface buttonPressCallback;
public WorkoutView(Context context) {
super(context);
Log.e("WORKOUTVIEW", "1");
mContext = context;
}
public WorkoutView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
Log.e("WORKOUTVIEW", "2");
}
public WorkoutView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
Log.e("WORKOUTVIEW", "3");
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
init();
}
public interface ButtonPressInterface {
void buttonWasPressed();
}
public void init() {
spinnerDifficulty = (Spinner) findViewById(R.id.spinnerDifficulty);
spinnerReps = (Spinner) findViewById(R.id.spinnerReps);
spinnerSets = (Spinner) findViewById(R.id.spinnerSets);
spinnerMuscleGroup = (Spinner) findViewById(R.id.spinnerWorkoutGroup);
spinnerTime = (Spinner) findViewById(R.id.spinnerTime);
etWorkoutName = (EditText) findViewById(R.id.etWorkoutName);
btnRemoveWorkout = (Button) findViewById(R.id.btnRemoveWorkout);
btnRemoveWorkout.setOnClickListener(this);
buttonPressCallback = (ButtonPressInterface) getContext();
}
public String getReps() {
reps = spinnerReps.getSelectedItem().toString();
return reps;
}
public String getWorkoutName() {
workoutName = etWorkoutName.getText().toString().trim();
return workoutName;
}
public String getMuscleGroup() {
muscleGroup = spinnerMuscleGroup.getSelectedItem().toString();
return muscleGroup;
}
public String getSets() {
sets = spinnerSets.getSelectedItem().toString();
return sets;
}
public SingleWorkout getAll() {
//to be designed
return null;
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnRemoveWorkout:
buttonPressCallback.buttonWasPressed();
Log.e("DID THIS WORK?", "BUTTON PRESSED");
break;
}
}
}
How can I remove this view when pressing the btnRemoveWorkout? Is there a way to implement an interface? This view is being added correctly and all the other methods work perfectly.
Here is the error I am receiving when trying to add the view programmatically, this was possible before I attempted to implement an interface for a callback to the Activity.
03-06 23:30:30.352 6986-6986/com.modup.app E/WORKOUTVIEW﹕ 2
03-06 23:30:30.372 6986-6986/com.modup.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.modup.app, PID: 6986
java.lang.ClassCastException: com.modup.view.WorkoutView cannot be cast to com.modup.view.WorkoutView$ButtonPressInterface
at com.modup.view.WorkoutView.init(WorkoutView.java:70)
at com.modup.view.WorkoutView.onFinishInflate(WorkoutView.java:52)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:763)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at com.modup.fragment.CreateFragment.onClick(CreateFragment.java:197)
at android.view.View.performClick(View.java:4442)
at android.view.View$PerformClick.run(View.java:18473)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5105)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
at dalvik.system.NativeStart.main(Native Method)
03-06 23:31:21.972 7620-7620/com.modup.app E/WORKOUTVIEW﹕ 2
03-06 23:31:21.982 7620-7620/com.modup.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.modup.app, PID: 7620
java.lang.ClassCastException: com.modup.app.LeftMenusActivity cannot be cast to com.modup.view.WorkoutView$ButtonPressInterface
at com.modup.view.WorkoutView.init(WorkoutView.java:70)
at com.modup.view.WorkoutView.onFinishInflate(WorkoutView.java:52)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:763)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at com.modup.fragment.CreateFragment.onClick(CreateFragment.java:197)
at android.view.View.performClick(View.java:4442)
at android.view.View$PerformClick.run(View.java:18473)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5105)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
at dalvik.system.NativeStart.main(Native Method)
Inside the Fragment which I am expecting to respond to a callback
@Override
public void buttonWasPressed() {
workoutLayout.removeView(workoutView);
}
UPDATE:
I implemented
public void registerButtonPressInterface(ButtonPressInterface listener){
buttonPressCallback = listener;
}
this does not result in a crash when adding a view, but my button does not work still and leads to a NullPointerException.
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnRemoveWorkout:
buttonPressCallback.buttonWasPressed();
Log.e("DID THIS WORK?", "BUTTON PRESSED");
break;
}
}
This is how I am attempting to listen for the callback
workoutView.registerButtonPressInterface(new WorkoutView.ButtonPressInterface() {
@Override
public void buttonWasPressed() {
Log.e("BUTTON WAS PRESSED", "INTERFACE WORKED!");
}
});
workoutLayout.addView(workoutView);
Upvotes: 0
Views: 56
Reputation: 30985
According to your stack trace, this is the line that's causing the heartburn:
buttonPressCallback = (ButtonPressInterface) getContext();
You don't have the relevant code posted, but I'd bet that you think your activity is implementing this interface when it actually isn't. In fact, you say your last code snippet (which is the interface implementation) is from a Fragment.
Here is what I would recommend: Rather than casting the context to your interface, create a method
public void registerButtonPressListener(ButtonPressInterface listener)
on your view class and store a reference to the ButtonPressInterface
implementation. This will make your view class more flexible since your context won't be required to implement ButtonPressInterface
in order to use your view. Now the compiler will be able to tell you if what you are passing in does in fact implement the interface, and it will be easier for you to figure out what's wrong.
Upvotes: 1