androidcheckboxtextviewandroid-listfragment

ListFragment with checkbox onListItemClick never gets called


I've read some SO questions like this and this but still couldn't figure out whats wrong with my code. I have a ListFragment, and each row has a TextView and a CheckBox. Clicking the CheckBox is working, but clicking on the TextView does nothing, and OnListItemClick doesn't get called. I've also tried to dynamically add an OnClickListener, which make it work, but it's not the correct way to do it, and it also lacks the GUI feedback of the click (item being "highlighted" for a sec).

This is my textview_with_checkbox.XML I'm using for each item:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:focusable="true"
    android:gravity="left"
    android:descendantFocusability="blocksDescendants"
    android:orientation="horizontal" >
<TextView
    android:id="@+id/textview_event_name"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:paddingLeft="3dp"
    android:paddingTop="5dp"
    android:focusable="true"
    android:singleLine="false" />

<CheckBox
    android:id="@+id/checkbox_for_event_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="0.05"
    android:focusable="false"
    android:clickable="false" />

</LinearLayout>

now the code:

@Override
public void onActivityCreated(Bundle savedInstanceState) 
{
    super.onActivityCreated(savedInstanceState);
    displayEventsLogFiles();
}

@Override
public void onListItemClick(ListView l, View v, int position, long id) 
{
    super.onListItemClick(l, v, position, id);

    String chosenItem = (String) getListAdapter().getItem(position);
    mCallBack.onEventItemSelected(chosenItem);

}

static class myCustomAdapterViewHolder
{
    public TextView eventName;
    public CheckBox eventCheckBox;
}

private class myCustomAdapter extends ArrayAdapter<String>
{   
    private ArrayList<String> sortedList;
    private Context m_oContext;
    List<String> m_oValues = null;

    public myCustomAdapter(Context cont, int viewResId, List<String> objects) 
    {
        super(cont, viewResId, objects);
        m_oContext = cont;
        m_oValues = objects;
        sortedList = new ArrayList<String>();
        for (String str : objects)
            sortedList.add(str);
        java.util.Collections.sort(sortedList);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View l_oRowView = convertView;
        myCustomAdapterViewHolder l_oInitializedViewHolder = null;
        final int l_nPosition = position;
        // Use convertView if possible, otherwise inflate a view:
        if (l_oRowView == null)
        {
            LayoutInflater inflater = (LayoutInflater) m_oContext
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            l_oRowView = inflater.inflate(R.layout.textview_with_checkbox, parent, false);

            // PlaceHolder pattern:
            final myCustomAdapterViewHolder l_oViewHolder = new myCustomAdapterViewHolder();
            l_oViewHolder.eventName = (TextView) l_oRowView.findViewById(R.id.textview_event_name);
            l_oViewHolder.eventCheckBox = (CheckBox) l_oRowView.findViewById(R.id.checkbox_for_event_name);

            l_oViewHolder.eventCheckBox.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    CheckBox cb = (CheckBox)v;
                    //cb.setChecked(!cb.isChecked());

                    String l_sFilename = l_oViewHolder.eventName.getText().toString();
                    if (cb.isChecked())
                    {
                        if (!m_lstSelectedFilenames.contains(l_sFilename))
                            m_lstSelectedFilenames.add(l_sFilename);
                    }
                    else
                    {
                        if (m_lstSelectedFilenames.contains(l_sFilename))
                            m_lstSelectedFilenames.remove(l_sFilename);
                    }
                }
            });
            l_oViewHolder.eventCheckBox.setFocusable(false);
            //l_oViewHolder.eventCheckBox.setClickable(false);
            // "Add" the viewHolder as a tag:
            l_oRowView.setTag(l_oViewHolder);
            l_oInitializedViewHolder = l_oViewHolder;
        }
        else
            l_oInitializedViewHolder = (myCustomAdapterViewHolder) l_oRowView.getTag();

        // By now, the rowView is initialized, just get the viewHolder and then get the views from it, to update:
        //myCustomAdapterViewHolder l_oViewHolder = (myCustomAdapterViewHolder) l_oRowView.getTag();
        /*l_oInitializedViewHolder.eventName.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                mCallBack.onEventItemSelected((String)getListAdapter().getItem(l_nPosition));

            }
        });*/
        l_oInitializedViewHolder.eventName.setText(m_oValues.get(position));
        return l_oRowView;
        //return super.getView();
    }

    public myCustomAdapter(Context cont, int viewResId, String[] strings) 
    {
        this(cont, viewResId, Arrays.asList(strings));
    }

    @Override
    public String getItem(int position) 
    {
        return sortedList.get(position);
    }

    @Override
    public int getPosition(String item) 
    {
        return sortedList.indexOf(item);
    }

}

What am I doing wrong here? All I want is to be able to select "files" for deletion, using the CheckBoxes


Solution

  • Try only using only onclick for textview and checkbox, not onListItemClick -which you can remove- as well, so you should change some properties for the linear layout as well.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:clickable="false"
        android:focusable="false"
        android:gravity="left"
        android:orientation="horizontal" >
    <TextView
        android:id="@+id/textview_event_name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingLeft="3dp"
        android:paddingTop="5dp"
        android:focusable="true"
        android:singleLine="false" />
    
    <CheckBox
        android:id="@+id/checkbox_for_event_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="0.05"
        android:focusable="false"
        android:clickable="false" />
    
    </LinearLayout>
    

    Implement in the adapter

        // PlaceHolder pattern:
            final myCustomAdapterViewHolder l_oViewHolder = new myCustomAdapterViewHolder();
            l_oViewHolder.eventName = (TextView) l_oRowView.findViewById(R.id.textview_event_name);
    
    
             l_oViewHolder.eventCheckBox = (CheckBox) l_oRowView.findViewById(R.id.checkbox_for_event_name);
    
      l_oViewHolder.eventName.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                         // your code for textview click
                   }
               }
                l_oViewHolder.eventCheckBox.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        CheckBox cb = (CheckBox)v;
                        //cb.setChecked(!cb.isChecked());
    
                        String l_sFilename = l_oViewHolder.eventName.getText().toString();
                        if (cb.isChecked())
                        {
                            if (!m_lstSelectedFilenames.contains(l_sFilename))
                                m_lstSelectedFilenames.add(l_sFilename);
                        }
                        else
                        {
                            if (m_lstSelectedFilenames.contains(l_sFilename))
                                m_lstSelectedFilenames.remove(l_sFilename);
                        }
                    }
                });
                l_oViewHolder.eventCheckBox.setFocusable(false);