Search code examples
androidandroid-listfragmentonitemclicklistenerevent-listener

(ListFragment) What exactly should the OnItemClickListener attach to?


I'm currently writing an app that has a main Activity with a fragment-container (programmatically added when in portrait view, and two Fragment views created from the XML layout when in landscape view) and a ListFragment fragment that has a List View with a bunch of items (put into the view via an Adapter). The main Activity implements the ListFragment's callback interface.

I'm having trouble getting the ListFragment's onListItemClick() to work. From reading and working through other examples online, it seems like that should be enough, but it doesn't work. I've tried adding event listeners to both the ListView and the individual list items, but neither seem to work; actually, I'm not sure where those should even go. I've tried putting them in both onCreateView() and 'onActivityCreated(). I've also made sure that the Views are set withandroid:clickable = "true"` in the XML files, and that no other View objects were stealing focus from the ListView items.

What am I missing here?

ListFragment Activity:

public class IdeaListFragment extends ListFragment {    
    /** various methods and variables **/
  @Override
    // Makes sure the container Activity has implemented the callback interface
    public void onAttach(Context context) {
        super.onAttach(context);
        try {
            mCallback = (OnIdeaSelectedListener) context;
        } catch(ClassCastException cce) {
            Log.e(TAG, "OnIdeaSelectedListener not implemented: ", cce);
            throw new ClassCastException(context.toString()
                    + " must implement OnIdeaSelectedListener");
        }
    }

    @Override
    public void onListItemClick(ListView l, View v, int pos, long id) {
        super.onListItemClick(l, v, pos, id);
        mCallback.onIdeaSelected(mBucket.getIdeaAt(pos));
        getListView().setItemChecked(pos, true);
    }
}

Main Activity:

public class MainIdeasListViewActivity extends AppCompatActivity
    implements IdeaListFragment.OnIdeaSelectedListener,
    IdeaDetailFragment.OnIdeaUpdatedListener {
    /** various methods and variables **/
    public void onIdeaSelected(IdeaItem idea) {
    IdeaDetailFragment ideaDetailFrag = (IdeaDetailFragment)
            getSupportFragmentManager().findFragmentById(
                    R.id.idea_detail_fragment);

    if(ideaDetailFrag != null)
        ideaDetailFrag.newInstance(idea);
    else {
        IdeaDetailFragment newDetailFrag = new IdeaDetailFragment();
        Bundle args = new Bundle();
        args.putString(UUIDKEY, idea.getUUID().toString());
        newDetailFrag.setArguments(args);
        FragmentTransaction transaction = getSupportFragmentManager()
                                            .beginTransaction();
        transaction.replace(R.id.fragment_container, newDetailFrag);
        transaction.addToBackStack(null);
        transaction.commit();
        }
    }
}

listitem XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
              android:clickable = "true"
              android:longClickable = "true"
              android:orientation = "vertical"
              android:layout_width = "match_parent"
              android:layout_height = "wrap_content"
              android:descendantFocusability="blocksDescendants">

    <LinearLayout
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:orientation = "horizontal"
        style = "@style/ListItem">

        <ImageView
            android:id = "@id/icon_idea_item_status"
            android:contentDescription = ""
            style = "@style/ListMainIcon" />

        <LinearLayout style = "@style/ListItemBody">
            <TextView
                android:id = "@id/text_idea_title"
                style = "@style/ListItemBodyTitle" />

            <TextView
                android:id = "@id/text_idea_description"
                style = "@style/ListItemBodySubtitle"/>
        </LinearLayout>

        <ImageView
            android:id = "@id/icon_idea_item_submenu"
            android:focusableInTouchMode = "true"
            android:contentDescription = "@string/list_idea_submenu"
            style = "@style/ListSubmenuIcon"
            android:clickable = "true"/>

    </LinearLayout>

    <View style = "@style/divider" />

</LinearLayout>

ListView fragment XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
              xmlns:tools = "http://schemas.android.com/tools"
              android:orientation = "vertical"
              android:layout_width = "match_parent"
              android:layout_height = "wrap_content"
              tools:context = ".IdeaListFragment"
              style = "@style/AppMain">

    <ListView
        android:id = "@android:id/list"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:clickable = "true"/>
</LinearLayout>

Solution

  • remove android:clickable = "true" from listview fragment XML
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
                  xmlns:tools = "http://schemas.android.com/tools"
                  android:orientation = "vertical"
                  android:layout_width = "match_parent"
                  android:layout_height = "wrap_content"
                  tools:context = ".IdeaListFragment"
                  style = "@style/AppMain">
    
        <ListView
            android:id = "@android:id/list"
            android:layout_width = "match_parent"
            android:layout_height = "wrap_content"
            />
    </LinearLayout>
    
    
    
    
    Add  focusable and clickable false to each child item in listitem XML
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
    
                  android:orientation = "vertical"
                  android:layout_width = "match_parent"
                  android:layout_height = "wrap_content"
                  android:descendantFocusability="blocksDescendants">
    
        <LinearLayout
            android:layout_width = "match_parent"
            android:layout_height = "wrap_content"
            android:orientation = "horizontal"
            style = "@style/ListItem"
            android:focusable="false"
            android:clickable="false">
    
            <ImageView
                android:id = "@id/icon_idea_item_status"
                android:contentDescription = ""
                style = "@style/ListMainIcon" 
                android:focusable="false"
                android:clickable="false"/>
    
            <LinearLayout style = "@style/ListItemBody"
             android:focusable="false"
             android:clickable="false">
                <TextView
                    android:id = "@id/text_idea_title"
                    style = "@style/ListItemBodyTitle" 
                     android:focusable="false"
                      android:clickable="false"/>
    
                <TextView
                    android:id = "@id/text_idea_description"
                    style = "@style/ListItemBodySubtitle"
                     android:focusable="false"
                       android:clickable="false"/>
            </LinearLayout>
    
            <ImageView
                android:id = "@id/icon_idea_item_submenu"
                android:focusableInTouchMode = "true"
                android:contentDescription = "@string/list_idea_submenu"
                style = "@style/ListSubmenuIcon"
                android:focusable="false"
                android:clickable="false"/>
    
        </LinearLayout>
    
        <View style = "@style/divider" 
        android:focusable="false"
         android:clickable="false"/>
    
    </LinearLayout>