Search code examples
androidandroid-listviewandroid-cursoradapteronclicklistener

Getting the selected View from ListView


I am using a CursorAdapter to handle my ListActivity:

public class Mclass extends ListActivity{
...
TheAdapter mAdapter;
public static HashMap<Long, Boolean> shown = new HashMap<Long, Boolean>();
...

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
         Boolean tmp = shown.get(id); 
        if (tmp == null) { // if null we don't have this key in the hashmap so we added with the value true
            shown.put(id, true);
        } else {
            shown.put(id, !tmp.booleanValue()); // if the value exists in the map then inverse it's value
        }
    mAdapter.notifyDataSetChanged();
         }

}

and my adapter class that extends CursorAdapter and overrides bindView:

@Override
public void bindView(View view, Context context, Cursor cursor) {
    String listText= cursor
            .getString(cursor
                    .getColumnIndexOrThrow(DataHandler.MY_TEXT));

long id = cursor.getLong(cursor.getColumnIndexOrThrow(DataHandler.ROW_ID)); 
    if (Mclass.shown.get(id) != null) {
        TextView m_text = (TextView) view
                .findViewById(R.id.my_text);
        if (m_text != null) {
            m_text.setVisibility(Mclass.shown.get(id)? View.VISIBLE:
                     View.GONE);

            if (m_text.isShown())
                m_text.setText("STRING");
   }
}

My list item layout is defined in a xml file list_item.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#DDDDDD"
android:orientation="horizontal" >

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/my_image"
        android:layout_width="wrap_content"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:paddingRight="1dip"
        android:paddingTop="1dip"
</LinearLayout>

/*
 *I want to toggle this text view's visibility
 */
<TextView
    android:id="@+id/my_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="gone"//VISIBILITY defined here
    android:paddingBottom="2dip"
    android:paddingLeft="4dip"
    android:paddingRight="4dip"
    android:paddingTop="5dip" />
 </LinearLayout>

How can I toggle the visibility of the TextView in my layout within onListItemClick? I've tried:

TextView mTextView = (TextView) v.findViewById(R.id.my_text);
mTextView.setVisibility(mTextView.isShown()? View.GONE: View.VISIBLE);
mAdapter.notifyDataSetChanged();

but it seems to be choosing which list items to toggle at random, regardless of the one I click.


Solution

  • You'll have to store the id's of the rows you'll hide. You could make a field in your activity to store those ids:

    HashMap<Long, Boolean> positionHide = new HashMap<Long, Boolean>();
    

    where the key is the long id of the row and the boolean object represents the status of the TextView(false- it is gone, true it is visible). In the onListItemClick() add the ids of the clicked rows to that field:

        @Override
        protected void onListItemClick(ListView l, View v, int position, long id) {
             Boolean tmp = positionHide.get(id); 
            if (tmp == null) { // if null we don't have this key in the hashmap so we added with the value true
                status.put(id, true);
            } else {
                status.put(id, !tmp.booleanValue()); // if the value exists in the map then inverse it's value
            }
            mAdapter.notifyDataSetChanged();
        }
    

    also modify the bindView() method:

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        String listText = cursor.getString(cursor
                .getColumnIndexOrThrow(DataHandler.MY_TEXT));
        long pos = cursor.getLong(cursor.getColumnIndex(DataHandler.ID)); // DataHandler.ID will point to the column _id
    TextView m_text = (TextView) view.findViewById(R.id.my_text);
    
        if(status.get(pos) == null) {
    //id is not yet in the hashmap so the value is 
    //by default false, the TextView is invisible
        m_text.setVisibility(View.GONE);
    
        } else {
            // we have the value in the
            // Hashmap so see what it is and set the
        // textview visibility from this value
    
            if (tmp.booleanValue()) {
              m_text.setVisibility(View.VISIBLE);
                 } else {
                     m_text.setVisibility(View.GONE);
                       }
              }
        if (m_text != null)
         m_text.setText(listText);  
    
    }
    

    For this to work you'll need to have in your database the column _id INTEGER PRIMARY KEY AUTOINCREMENT(and also added to the query).