在 ListView 中选择时更改 ListItem 视图

发布于 2024-11-28 11:27:28 字数 767 浏览 3 评论 0原文

我想替换 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;  
}

我应该这样做吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

九命猫 2024-12-05 11:27:28

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

如果附加 onClickListener,则传入的 View 属于 Frame 类。然后,您可以使用 v.findViewById(...) 定位适配器行布局中的任何其他视图
并修改它。如果我不更改适配器数据,我只是使用 v.invalidate() 来重绘该特定适配器行。根据定义,如果您获得 onClickListener 命中,则该特定适配器视图
是可见且膨胀的,因此只要您位于 UI 线程上,您就可以独立于 Adapter 来操作 View。

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 (intposition...) 中更改边框的代码的一部分。由于 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);
        }

}

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

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文