I have an Android activity with a list. Each item can be clicked and when that happens a new layout is displayed below the text with some buttons.
I wanted to set the selected item to the center when clicked, because when the last one is clicked the menu is lost and you need to scroll, which is very confusing.
My code saves the position of the last selected item, so when another one is clicked, it can hide the edit menu for that item.
When I use setSelection this behavior breaks, it seems like the positions in the listView changes, because that logic doesn’t work anymore. All options remain visible, different rows are reacting instead of the one clicked, and if I click a row below the selected one, it throws a NullPointerException.
I’ve tried to do this in many different ways, storing the view instead of the position, using scrollTo instead of setSelection, etc… but it always seems to break. This is the code in question, do you guys have any ideas? Thanks a lot.
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
RelativeLayout itemView = (RelativeLayout) mListView.getChildAt(position);
LinearLayout showItemOptionsView = (LinearLayout) itemView.findViewById(R.id.itemOptionsView);
showItemOptionsView.setVisibility(View.VISIBLE);
// Sets previous to GONE
if (mPreviouslySelectedItemPosition != -1) {
itemView = (RelativeLayout) mListView.getChildAt(mPreviouslySelectedItemPosition);
showItemOptionsView = (LinearLayout) itemView.findViewById(R.id.itemOptionsView);
showItemOptionsView.setVisibility(View.GONE);
}
mListView.setSelection(position);
mPreviouslySelectedItemPosition = position;
}
this is the layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="@+id/groceryListName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="20dp" />
<LinearLayout
android:id="@+id/addItemView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/groceryListName"
android:gravity="center_vertical"
android:orientation="horizontal" >
<EditText
android:id="@+id/itemName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="textAutoComplete" />
<Button
android:id="@+id/addItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right|center_vertical"
android:onClick="addItem"
android:text="@string/addItem" />
</LinearLayout>
<TextView
android:id="@+id/clickOnItemToEdit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/addItemView"
android:layout_marginBottom="5dp"
android:text="@string/clickOnItemToEdit"
android:textSize="10dp" />
<Button
android:id="@+id/shop"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:onClick="startShoppingActivity"
android:text="@string/startShopping" />
<ListView
android:id="@+id/items"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@id/shop"
android:layout_below="@id/clickOnItemToEdit" />
</RelativeLayout>
and this is the row’s layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/showItemView"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="@+id/itemId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />
<TableRow
android:id="@+id/itemTable"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:stretchColumns="3" >
<Button
android:id="@+id/itemQuantityLess"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:focusable="false"
android:focusableInTouchMode="false"
android:onClick="lessQuantityHandler"
android:text="@string/itemQuantityLess" />
<TextView
android:id="@+id/itemQuantity"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:textSize="20sp" />
<Button
android:id="@+id/itemQuantityMore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|center_vertical"
android:focusable="false"
android:focusableInTouchMode="false"
android:onClick="moreQuantityHandler"
android:text="@string/itemQuantityMore" />
<TextView
android:id="@+id/itemProductName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|center_vertical"
android:textSize="20sp" />
</TableRow>
<LinearLayout
android:id="@+id/itemOptionsView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_below="@id/itemTable"
android:gravity="center|right"
android:orientation="horizontal"
android:visibility="gone" >
<Button
android:id="@+id/editItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right|center_vertical"
android:onClick="editItem"
android:text="@string/editItem" />
<Button
android:id="@+id/removeItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right|center_vertical"
android:onClick="removeItem"
android:text="@string/removeItem" />
</LinearLayout>
</RelativeLayout>
This is the code from the adapter
@Override
public void bindView(View view, Context context, Cursor cursor) {
int idIndex = cursor.getColumnIndexOrThrow(ItemAndroidDAO._ID);
String id = cursor.getString(idIndex);
TextView idView = (TextView) view.findViewById(R.id.itemId);
idView.setText(id);
int productIdIndex = cursor.getColumnIndexOrThrow(ItemAndroidDAO.PRODUCT_ID_COLUMN);
String productId = cursor.getString(productIdIndex);
Product product = productFacade.findById(Long.parseLong(productId));
// The product must exist, otherwise it fails.
AppException.assertNotNull(product, "The related product cannot be null.");
TextView productIdView = (TextView) view.findViewById(R.id.itemProductName);
productIdView.setText(product.getName());
int quantityViewIndex = cursor.getColumnIndex(ItemAndroidDAO.QUANTITY_COLUMN);
int quantity = cursor.getInt(quantityViewIndex);
TextView quantityView = (TextView) view.findViewById(R.id.itemQuantity);
quantityView.setText(Integer.toString(quantity));
}
and the newView() (it's in a superclass)
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View listView = (View) layoutInflater.inflate(getLayoutResource(), null);
bindView(listView, context, cursor);
return listView;
}
API Level is 7 (2.1).
I don’t know if I understood what’s happening with your code(or what you are trying to do) but you could try another approach. Instead of trying to work with your selected row in the
onItemClick()method make your adapter have a field:then in the
onItemClick()will simply have:then in the
bindView()method of your adapter, besides what you do, see if theselectedPositionis equal to the cursor row ID. If that is the case then search for theLinearLayoutand make it visible: