【问题标题】:simplecursoradapter updates views randomlysimplecursoradapter 随机更新视图
【发布时间】:2013-07-15 21:40:47
【问题描述】:

我在活动中有一个 ListView。 ListView 的数据是使用 SimpleCursorAdapter 从联系人中填充的。 ListView 所在行的布局是两个 TextView,分别代表人名和数字,以及一个 ImageView,其可见性设置为不可见。

我有适配器的自定义 ViewBinder,它检查 ImageView 是否应该可见。问题是图像是随机可见的。我猜问题出在 SimleCursorAdapter 的实现与 newView 和 bindView 一起使用的 ViewHolder 模式中。

是否可以不编写自定义光标适配器来解决问题?

来源如下:

list_row.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <TextView
        android:id="@+id/contact_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginRight="10dp"
        android:drawableLeft="@drawable/directory_pushed"
        android:drawablePadding="10dp"
        android:text="contact name" />

    <TextView
        android:id="@+id/contact_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/contact_name"
        android:text="093797888" />

    <ImageView
        android:id="@+id/selected"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:src="@drawable/icon_phone"
        android:visibility="gone" />

</RelativeLayout>

Contacts.java

public class Contacts extends Activity implements
        AdapterView.OnItemClickListener, ViewBinder {

    private ListView mContactList;
    private SimpleCursorAdapter mAdapter;
    private List<String> contacts;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.contacts);

        Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
        String[] projection = new String[] { Phone._ID, Phone.DISPLAY_NAME,
                Phone.NUMBER };
        String selection = Phone.TYPE + "=?";
        String[] selectionArgs = new String[] { String
                .valueOf(Phone.TYPE_MOBILE) };
        String sortOrder = Phone.DISPLAY_NAME + " ASC";

        contacts = LoginInfo.getContacts(this);

        Cursor managedCursor = getContentResolver().query(uri, projection,
                selection, selectionArgs, sortOrder);

        mContactList = (ListView) findViewById(R.id.contacts_list);

        mAdapter = new SimpleCursorAdapter(this, R.layout.contacts_row,
                managedCursor, new String[] { Phone.DISPLAY_NAME, Phone.NUMBER,
                        Phone.NUMBER }, new int[] { R.id.contact_name,
                        R.id.contact_number, R.id.selected }, 0);

        mAdapter.setViewBinder(this);

        mContactList.setOnItemClickListener(this);

        mContactList.setAdapter(mAdapter);
    }

    @Override
    protected void onPause() {
        super.onPause();

        LoginInfo info = LoginInfo.getLoginInfo(this);
        info.contacts = null;
        info.contacts = contacts;

        LoginInfo.updateCache(this, info);
    }

    @Override
    public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
        if (view.getId() == R.id.selected) {
            String number = cursor.getString(columnIndex);

            if (isSelected(number)) {
                view.setVisibility(View.VISIBLE);
            }

            return true;
        }

        return false;
    }

    private boolean isSelected(String number) {
        int index = contacts.indexOf(number);
        return !(index == -1);
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {

        Cursor c = (Cursor) mAdapter.getItem(position);

        String number = c.getString(c.getColumnIndex(Phone.NUMBER));

        contacts.add(number);
    }

}

【问题讨论】:

    标签: android listview simplecursoradapter


    【解决方案1】:

    在我看来,创建自定义适配器更简单,但如果你想保持这种方式,试试这个

    @Override
    public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
        if (view.getId() == R.id.selected) {
            String number = cursor.getString(columnIndex);
    
            if (isSelected(number)) {
                view.setVisibility(View.VISIBLE);
            }
            else {
                view.setVisibility(View.GONE);
            }
    
            return true;
        }
    
        return false;
    }
    

    【讨论】:

    • 感谢您的建议,它有效。在 Contacts.java 中,我添加了一行 mAdapter.notifyDataSetChanged() 以立即查看更改。在这种情况下,我也不认为为 CursorAdapter 创建自定义实现是好的设计。不喜欢有很多不可重复使用的精华,如果你明白我的意思的话。 :D
    • 很高兴能提供帮助。至于自定义适配器,如果您更喜欢这种方式,请使用它。我更喜欢编写自己的适配器,因为它将列表的视图逻辑保存在单独的文件中,并使活动类代码更清晰。只有当我的列表元素可能有不同的视图时才会出现这种情况。
    • 好吧,我不知道它是否正确,“android 方式”,但我更喜欢使用内置插件直到最后。因为我是新手,如果我是对的,你能告诉我吗?我的意思是,它是否是好的设计。如果框架提供了某些东西,我为什么要覆盖它,我为什么要重新发明轮子?
    • 我不知道这种情况下众所周知的良好做法,我并不是说你的做法是错误的。编写自定义适配器不是重新发明轮子,而是扩展/升级它。如果你想知道我的个人意见,我在博客上写了一篇关于 writing custom adapter 的帖子。
    猜你喜欢
    • 1970-01-01
    • 2016-01-16
    • 1970-01-01
    • 2017-03-09
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    相关资源
    最近更新 更多