Change ListItem View on Select in ListView

拈花ヽ惹草 提交于 2019-12-11 10:22:52

问题


I want to replace the view of a ListItem onItemClick. However, I have encountered redrawing problems when I do this:

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?


回答1:


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);
        }

}



来源:https://stackoverflow.com/questions/6973914/change-listitem-view-on-select-in-listview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!