I have a activity with an container inside of it in which I display a list generated by a listFragment. Now I want handle clicks on list items by "forwarding" the onItemClick method via a pulic interface to the mainActivity. I did setOnItemClickLIstener and I also tried many solutions I found here and elsewhere e.g. setting android:focusable="false" android:focusableInTouchMode="false" in the xml file for my custom list items.
The fragment code looks like this (I will not post the whole code to keep it simple, if needed I will provide further parts of the code)
public class DishListFragment extends ListFragment implements ListView.OnItemClickListener {
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private static final String ARG_PARAM3 = "param3";
private static final String ARG_PARAM4 = "param4";
private static final String ARG_PARAM5 = "param5";
//List of Dishes to contain the dishes we get from the server
//Todo: fill with dynamic content
private ArrayList<DishListItem> dishes;
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
private ListView mListView;
private ListAdapter mAdapter;
public static DishListFragment newInstance(Date day, boolean soup, boolean meat,
boolean veggies, boolean sideDishes) {
DishListFragment fragment = new DishListFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, String.valueOf(day));
args.putString(ARG_PARAM2, String.valueOf(soup));
args.putString(ARG_PARAM3, String.valueOf(meat));
args.putString(ARG_PARAM4, String.valueOf(veggies));
args.putString(ARG_PARAM5, String.valueOf(sideDishes));
fragment.setArguments(args);
return fragment;
}
public DishListFragment() { }
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//dummy list of dishes addad for developing purposes
// Todo: implement dynamic server generated list content
// create this array to test the comment function
String[] commentDummy = new String[]{"gut", "lecker", "schlecht"};
dishes = new ArrayList<DishListItem>();
dishes.add(new DishListItem("Rigatonelli", commentDummy, 2.0f ,4));
dishes.add(new DishListItem("Spinatcremesuppe"));
dishes.add(new DishListItem("Hackbällchen"));
dishes.add(new DishListItem("Gemüsepfanne"));
dishes.add(new DishListItem("Reis"));
dishes.add(new DishListItem("Rumpsteak"));
dishes.add(new DishListItem("Rumpsteak"));
dishes.add(new DishListItem("Rumpsteak"));
dishes.add(new DishListItem("Rumpsteak"));
dishes.add(new DishListItem("Rumpsteak"));
dishes.add(new DishListItem("Rumpsteak"));
//end here
// set an adapter to the list and let it display the list
// Todo: implement custom list view elements for graphical UI
// Todo: implement custom adapter to handle user preferences (meat/ veggies/ soups/ sidedishes)
mAdapter = new DishListAdapter(getActivity(),dishes);
}
//create on click adapter to handle clicks on list items
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
DishListItem dishItem = this.dishes.get(position);
Toast.makeText(getActivity(), dishItem.getDishName() +" clicked!", Toast.LENGTH_SHORT).show();
mListener.onDishClicked(dishes, position);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_dishlist, container, false);
View header = inflater.inflate(R.layout.list_header_day_date, mListView ,false);
mListView = (ListView) view.findViewById(android.R.id.list);
mListView.addHeaderView(header);
mListView.setAdapter(mAdapter);
// Set OnItemClickListener so we can be notified on item clicks
mListView.setOnItemClickListener(this);
return view;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public void setEmptyText(CharSequence emptyText) {
View emptyView = mListView.getEmptyView();
if (emptyText instanceof TextView) {
((TextView) emptyView).setText(emptyText);
}
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onDishClicked(ArrayList<DishListItem> dishes, int position);
}
}
The main activity looks like this
public class CulinariumSpeiseplan extends ActionBarActivity
implements DishListFragment.OnFragmentInteractionListener
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_culinarium_speiseplan);
//add list fragment to the activity layout (put it into the container)
if(savedInstanceState == null){
getFragmentManager().beginTransaction()
.add(R.id.listDishesContainer, new DishListFragment())
.commit();
}
}
{
@Override
public void onDishClicked(ArrayList<DishListItem> dishes, int position) {
Toast.makeText(this, dishes.get(position).getDishName() +" clicked!", Toast.LENGTH_SHORT).show();
SingleDishEnhancedView singleDishEnhancedView = SingleDishEnhancedView.newInstance(dishes, position);
singleDishEnhancedView.show(getFragmentManager(), "DishDisplay");
}
}
the toasts are just for test purposes but they don't get displayed either. I hope I am not being completely stupid but I just can't seem to find an answer to that problem. Thank you for your time.
EDIT: I should also mention, that I do neither get an compilation error, nor does the app crash at any point. The list is scrollable and does behave as you would expect it, you can even see the little click animation as you click on one of the items.
EDIT2: I updated the code because the comments were pointing out some significant bits were missing. I hope the updated code makes it more clear.
The solution was fairly simple the onItemClick method has to use ListView instead of AdapterView, although I'm not really sure why this didn't cause a crash or at least some kind of warning. Either ways, the problem is solved. Thanks for the comments, they led me the right way.