Изменить представление ListItem на Select в ListView - PullRequest
1 голос
/ 07 августа 2011

Я хочу заменить представление 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 Ответ

2 голосов
/ 20 сентября 2011

Я уверен, что есть несколько способов сделать это. Я окружаю макеты строк моего адаптера фреймом, который действует как граница, а затем просто меняю форму фона на фрейме в getView (....), если выбран элемент.

Если вы присоединяете onClickListener, переданное представление имеет класс Frame. Затем вы можете использовать v.findViewById (...), чтобы найти любой другой вид в макете строки адаптера и изменить его. Я просто использую v.invalidate (), чтобы вызвать перерисовку этой конкретной строки адаптера, если я не изменяю данные адаптера. По определению, если вы получаете попадание onClickListener, этот конкретный вид адаптера является видимым и раздутым, поэтому вы можете управлять представлением независимо от адаптера ... при условии, что вы находитесь в потоке пользовательского интерфейса.

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

}

...