开发者

Change ListItem View on Select in ListView

I want to replace the view of a ListItem onItemClick. However, I have encountered redrawing problems when I do thi开发者_StackOverflow社区s:

public void onItemClick (AdapterView<?> parent, View view, int position, long id) {
    hlistAdapter.selected = position;
}

And then in the adapter:

public View getView (int position, View convertView, ViewGroup parent) {
    View retval;
    if (position == selected)
        retval = LayoutInflater.from(parent.getContext()).inflate(R.layout.new_list_item_selected, null);
    else
        retval = LayoutInflater.from(parent.getContext()).inflate(R.layout.new_list_item, null);

    TextView title = (TextView) retval.findViewById (R.id.location);  
    title.setText (dataObjects[position]);

    return retval;  
}

How should I do this?


I'm sure there are multiple ways to do this. I surround my adapter row layouts with a Frame that acts as a border, and then just change the background shape on the Frame in getView (....) if the item is selected.

If you attach an onClickListener, the View passed in is of the Frame class. You can then use v.findViewById(...) to locate any other View in the adapter row layout and modify it. I just use v.invalidate() to cause a redraw of that particular adapter row if I don't change the adapter data. By definition, if you get a onClickListener hit, that particular adapter view is visible and inflated, so you can manipulate the View independent of the Adapter...so long as you are on the UI thread.

ListView only inflates visible or about to be visible adapter rows, so you have to make sure the Frame view is visible before manipulating it. For that, you use ListView.getFirstVisiblePosition() and ListView.getLastVisiblePosition(), which tell you which adapter rows are currently being displayed.

Here's an example of an adapter row layout that has an icon on the left and two rows of text to the right of the icon:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/AdapterRowAccounts_Border" 
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:padding="3dip"
    android:background="@drawable/shape_adapterrowborder"    
>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/AdapterRowAccounts_Content"
    android:paddingTop="1dip"
    android:background="@drawable/shape_listviewbackground"
    >
    <ImageView
        android:id="@+id/AdapterRowAccounts_Icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:tag="ic_subdirfolder"
        android:src="@drawable/ic_accountedit" 
        android:layout_marginRight="3dip"
        android:scaleType="centerInside"
    />
    <TextView
        android:id="@+id/AdapterRowAccounts_Text1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/AdapterRowAccounts_Icon"
        android:textColor="#000"
        android:text="test1"
        android:textColorHighlight="#FFF"
        android:singleLine="true"
        android:ellipsize="middle" 
    />
    <TextView
        android:id="@+id/AdapterRowAccounts_Text2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/AdapterRowAccounts_Text1"
        android:layout_alignLeft="@id/AdapterRowAccounts_Text1"
        android:text="test2"
        android:textColor="#000"
        android:textColorHighlight="#FFF"
        android:singleLine="true"
        android:ellipsize="middle" 
        android:textSize="10dip"
    />
</RelativeLayout>
</FrameLayout>

And this is a stitch of the code from getView (int position...) that changes the border. Since the Frame is the outermost element in the layout, the "v" passed in by getView() is of class Frame.

if (mPosition >= 0 && mPosition < this.getCount()) {
        mBundle = this.getItem(mPosition);
        // If it is the currently selected row, change the background
        ImageView mIcon = (ImageView) v.findViewById(R.id.AdapterRowAccounts_Icon);
        if (mPosition == mSelectedPosition) {
            v.setBackgroundResource(R.drawable.shape_adapterrowborder);
            mIcon.setImageResource(R.drawable.ic_accountedit);
        } else {
            v.setBackgroundResource(R.drawable.shape_adapterrow);
            mIcon.setImageResource(R.drawable.ic_account);
        }

}

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜