So I'm creating this app that allows users to search for recipes by ingredients, categories, and preparation time.
Initially, I had 3 activities:
However, it was such a hassle this way as I had to pass the data the user chose with an Intent to the next activity with a next button, and it was a mess always getting and adding extras until I got to the last activity, plus I wanted to be able to move freely between the 3 "pages", and not be restricted to going through them one by one.
This didn't seem efficient to me so I decided to change those activities into fragments and use a ViewPager to display them in tabs in a host activity (MainActivity), but it seems it's a different kind of hassle now.
I have a Search button in the MainActivity, and I'm having difficulty getting the data the user chose from all 3 fragments all at once when the Search button is clicked. I read about interfaces, but I'm not sure if it's the solution. I thought maybe I could define an OnSearchClickListener
interface in all 3 fragments, but can I implement one interface for 3 fragments, with each fragment returning different data?
Did I make a mistake transitioning to fragments? However, it seemed the most efficient way to do it... How can I get all the data from the fragments when the search button is clicked?
答案 0 :(得分:1)
Note: updated upon clarifications in comments
I would do the following:
In each of the three fragments, implement method getSearchCriteria
, with each returning value specific to that fragment.
Implement one OnClickListener
for the search
button - at the activity level.
Inside that listener, call getSearchCriteria
on each of the fragments - and do whatever you need to do with all the collated results, something like this:
findViewById(R.id.button_search).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
List<String> ingredients = ingredientFragment.getSearchCriteria();
List<String> categories = categoryFragment.getSearchCriteria();
int maxMinutes = timeFragment.getSearchCriteria();
// now you have all three things together - do what you need to with them
}
});
答案 1 :(得分:1)
如果每次更新条件时都通知MainActivity,您可以更新各自的标准并在搜索时使用它们(请参阅onSearchClicked)
IngredientFragment.java
public class IngredientFragment extends Fragment {
EditText editText;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_ingredient, container, false);
editText = (EditText)view.findViewById(R.id.edit_text);//assuming user type in the criteria in an edit box
return view;
}
public void onClick(View view){//user interaction to signal criteria updated. Replace this with onItemClickListener etc, if you are using ListView
if (mListener != null) {
mListener.onIngredientCriteriaUpdated(String.valueOf(editText.getText()));
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnIngredientFragmentListener) {
mListener = (OnIngredientFragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnIngredientFragmentListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnIngredientFragmentListener {
// TODO: Update argument type and name
void onIngredientCriteriaUpdated(String criteria);
}
}
CategoryFragment.java
public class CategoryFragment extends Fragment {
EditText editText;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_category, container, false);
editText = (EditText)view.findViewById(R.id.edit_text);//assuming user type in the criteria in an edit box
return view;
}
public void onClick(View view){//user interaction to signal criteria updated. Replace this with onItemClickListener etc, if you are using ListView
if (mListener != null) {
mListener.onCategoryCriteriaUpdated(String.valueOf(editText.getText()));
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnCategoryFragmentListener) {
mListener = (OnCategoryFragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnCategoryFragmentListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnCategoryFragmentListener {
// TODO: Update argument type and name
void onCategoryCriteriaUpdated(String criteria);
}
}
TimeFragment.java
public class TimeFragment extends Fragment {
EditText editText;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_category, container, false);
editText = (EditText)view.findViewById(R.id.edit_text);//assuming user type in the criteria in an edit box
return view;
}
public void onClick(View view){//user interaction to signal criteria updated
if (mListener != null) {
mListener.onTimeCriteriaUpdated(String.valueOf(editText.getText()));
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnTimeFragmentListener) {
mListener = (OnTimeFragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnTimeFragmentListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnTimeFragmentListener {
// TODO: Update argument type and name
void onTimeCriteriaUpdated(String criteria);
}
}
MainActivity.java(部分代码)
public class MainActivity extends AppCompatActivity implements
IngredientFragment.OnIngredientFragmentListener,
CategoryFragment.OnCategoryFragmentListener,
TimeFragment.OnTimeFragmentListener {
private String ingredientCriteria;
private String categoryCriteria;
private String timeCriteria;
:
:
:
@Override
public void onIngredientCriteriaUpdated(String criteria) {
ingredientCriteria = criteria;
}
@Override
public void onCategoryCriteriaUpdated(String criteria) {
categoryCriteria = criteria;
}
@Override
public void onTimeCriteriaUpdated(String criteria) {
timeCriteria = criteria;
}
public void onSearchClicked(View view){//handler for your search button
//do search using value of ingredientCriteria + categoryCriteria + timeCriteria
}
}