Android vustom SimpeCursorAdapater中错误组件上的ViewHolder

Android vustom SimpeCursorAdapater中错误组件上的ViewHolder,android,button,simplecursoradapter,Android,Button,Simplecursoradapter,我在DialogFragment中有一个自定义的SimpleCursorAdapter,我在理解setTag和getTag的用法时遇到了困难。从我的LogCat输出来看,似乎我正在线性布局上设置标签,并试图从按钮检索标签。我如何定位正确的组件以访问ClickListener中的标记 @Override public View getView(final int position, View convertView, final ViewGroup parent) {

我在DialogFragment中有一个自定义的SimpleCursorAdapter,我在理解setTag和getTag的用法时遇到了困难。从我的LogCat输出来看,似乎我正在线性布局上设置标签,并试图从按钮检索标签。我如何定位正确的组件以访问ClickListener中的标记

    @Override
    public View getView(final int position, View convertView, final ViewGroup parent) {
        if (mCursor.moveToPosition(position)) {
            ViewHolder holder;
            final String label;
            final int label_index = mCursor.getColumnIndex(ProfilesColumns.USERNAME);
            label = mCursor.getString(label_index);

            if (convertView == null) {
                convertView = mInflater.inflate(layout, null);

                holder = new ViewHolder();
                holder.name = (Button) convertView.findViewById(R.id.title);
                holder.logout = (Button) convertView.findViewById(R.id.logout);
                holder.id = getItemId(position);
                convertView.setTag(holder);
                Log.d(DEBUG_TAG, "getView view " + convertView);//Returns LinearLayout
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            holder.logout.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(final View v) {
                    ViewHolder holder;
                    if (v == null) {
                        Log.d(DEBUG_TAG, "logout view null ");
                    } else {
                        Log.d(DEBUG_TAG, "logout view " + v);//Returns Button
                        holder = (ViewHolder) v.getTag();
                        if (holder == null) {
                            Log.d(DEBUG_TAG, "logout holder null ");
                        } else {
                            Log.d(DEBUG_TAG, "logout holder.id   " + holder.id);
                            String[] argument = { "" + holder.id };
                            ContentResolver cr = getActivity().getContentResolver();
                            int count = cr.delete(ProfileProvider.URI_LOADEDPROFILETABLE, CommonDatabaseHelper._ID
                                    + "=?", argument);
                            Log.d(DEBUG_TAG, "logout count       " + count);
                        }
                    }
                }
            });
        }
        return convertView;

    }
以下是布局、配置文件和选择列表项:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="0dp" >

<Button
    android:id="@+id/title"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1" />

<Button
    android:id="@+id/logout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/logout" />

</LinearLayout>

简单的回答是,您没有在按钮上使用
setTag()
,只在其父级LinearLayout上使用它。因此,在您的OnClickListener中,请更改以下内容:

holder = (ViewHolder) v.getTag();
致:

此外,这一行:

holder.id = getItemId(position);
更改每行,而OnClickListener不更改。如果(convertView==null)将上述行移到
之外,并将OnClickListener移到里面


较长的答案
您正在扩展CursorAdapter,它们有三个很棒的方法
newView()
bindView()
,和
getView()

  • newView()
    创建新视图。重写此方法并将所有
    if(convertView==null){…}
    代码移到此处

  • bindView()
    可以直接访问光标。似乎SimpleCrsorAdapter的默认方法为您解决了这个问题

  • 由于
    newView()
    bindView()
    的强大性,重写
    getView()
    并不总是必要的


简单的回答是,您没有在按钮上使用
setTag()
,只在其父级LinearLayout上使用它。因此,在您的OnClickListener中,请更改以下内容:

holder = (ViewHolder) v.getTag();
致:

此外,这一行:

holder.id = getItemId(position);
更改每行,而OnClickListener不更改。如果(convertView==null)
将上述行移到
之外,并将OnClickListener移到里面


较长的答案
您正在扩展CursorAdapter,它们有三个很棒的方法
newView()
bindView()
,和
getView()

  • newView()
    创建新视图。重写此方法并将所有
    if(convertView==null){…}
    代码移到此处

  • bindView()
    可以直接访问光标。似乎SimpleCrsorAdapter的默认方法为您解决了这个问题

  • 由于
    newView()
    bindView()
    的强大性,重写
    getView()
    并不总是必要的


查看之前:无需在onClick中检查视图是否为空。。必须存在一个视图才能触发onClick,因此它永远不会为null。在查看之前有一点提示:不需要在onClick中检查视图是否为null。。必须存在一个视图才能触发onClick,因此它永远不会为null。只是一点点谢谢你。回答得很好,我对bindView/newView有了新的了解,但不确定是否要在SimpleCorsorAdapter中使用它们。碎片的工作原理与预期一致!非常感谢你。回答得很好,我对bindView/newView有了新的了解,但不确定是否要在SimpleCorsorAdapter中使用它们。碎片的工作原理与预期一致!