I have implemented a very basic call back pattern in Android. Below is my code
Interface:
public interface OnCustomEventListener{
public void onEvent(); //method, which can have parameters
}
In class B
private OnCustomEventListener mListener; //listener field
//setting the listener
public void setCustomEventListener(OnCustomEventListener eventListener) {
this.mListener=eventListener;
}
// When an event fires -
public void someEventFiringMethod(){
mListener.onEvent();
}
and from class A -
classB.setCustomEventListener(new OnCustomEventListener(){
public void onEvent(){
//do whatever you want to do when the event is performed.
}
});
This works pretty well and there is no issue, I however, feel there is a flaw with this design - in this case - class B defines the listener, which would mean that any class that wants to listen to the event has to create a new object of B and then has to call the method. eg - from class A -->
B b = new B();
b.setCustomEventListener(this);
similarly from class D/class E
B b = new B();
b.setCustomEventListener(this);
Is there a way this can be avoided???
And also assume -> B could be dependent on several other objects and to create B this would only make it more complex for object creation of B
I know dagger 2 could be a solution to resolve dependency creation - but in my case, class B is an Adapter and class A is an Activity in Android. What would be the best solution to resolve the above case? Should I be injecting an adapter into an Activity - is that a good way to do so, I think not.
Update --
public class FoodItemRecyclerView extends RecyclerView.Adapter<FoodItemRecyclerView.ViewHolder> {
private List<FoodItem> foodList;
private OnFoodItemEnteredListener foodItemInterface;
private Context mContext;
private static final String TAG = "FoodItemRecyclerView";
public FoodItemRecyclerView(List<FoodItem> foodList, Context context) {
this.foodList = foodList;
this.mContext = context;
}
public interface OnFoodItemEnteredListener {
void onFoodItemEntered(String foodItem, int position);
}
public void setInterfaceListener(OnFoodItemEnteredListener foodItemInterface){
this.foodItemInterface = foodItemInterface;
}
@NonNull
@Override
public FoodItemRecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_row, parent, false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull final FoodItemRecyclerView.ViewHolder holder, final int position) {
holder.edtFoodName.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
InputMethodManager imm = (InputMethodManager)mContext.getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(holder.edtFoodName.getWindowToken(), 0);
foodItemInterface.onFoodItemEntered(v.getText().toString(),position);
return true;
}
});
}
@Override
public int getItemCount() {
return foodList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private EditText edtFoodName;
public ViewHolder(@NonNull View itemView) {
super(itemView);
edtFoodName = itemView.findViewById(R.id.edtFoodName);
}
}
public void notifyData(List<FoodItem> newFoodList) {
this.foodList = newFoodList;
notifyItemInserted(foodList.size() - 1);
}
}
This is my class B, and the callback return to Activity class A, but what if I want the callback to return to the ViewModel? in this case I do not want to create a new object of adapter in my ViewModel class.