在ListView中选择更改ListItem视图

时间:2011-08-07 16:05:30

标签: android listview adapter

我想替换ListItem onItemClick的视图。但是,当我这样做时,我遇到了重绘问题:

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

然后在适配器中:

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

我该怎么做?

1 个答案:

答案 0 :(得分:2)

我确信有多种方法可以做到这一点。我用适合作为边框的Frame环绕我的适配器行布局,然后在getView(....)中更改框架的背景形状(如果选择了该项目。)

如果附加onClickListener,则传入的View属于Frame类。然后,您可以使用v.findViewById(...)在适配器行布局中查找任何其他View 并修改它。如果我不更改适配器数据,我只是使用v.invalidate()来重新绘制该特定适配器行。根据定义,如果你得到一个onClickListener命中,那个特定的适配器视图 是可见的和膨胀的,所以你可以独立于适配器操纵视图......只要你在UI线程上。

ListView只会膨胀可见或即将可见的适配器行,因此在操作之前必须确保Frame视图可见。为此,您使用ListView.getFirstVisiblePosition()和ListView.getLastVisiblePosition()来告诉您当前正在显示哪些适配器行。

这是一个适配器行布局的示例,左侧有一个图标,图标右侧有两行文本:

<?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>

这是一个改变边框的getView(int position ...)代码。由于Frame是布局中最外层的元素,因此getView()传入的“v”属于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);
        }

}