更改自定义游标适配器的行布局



我想在制作特定按钮(操作)时更改行布局。

public class DbCursorAdapter extends CursorAdapter {
private View selectedView;
private boolean isListSingleColumn = true;
private Cursor mCursor;
private final LayoutInflater mInflater;
private static final int TYPE_ITEM_SINGLE_COLUMN = 0;
private static final int TYPE_ITEM_MULTI_COLUMN = 1;
/**
 * DbCursorAdapter constructor
 * 
 * @param context
 *            - The context
 * @param cursor
 *            - The cursor used to make queries
 */
public DbCursorAdapter(Context context, Cursor cursor) {
    super(context, cursor, false);
    this.mContext = context;
    this.mCursor = cursor;
    this.mInflater = LayoutInflater.from(context);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
    final ViewHolder holder = (ViewHolder) view.getTag();
    String collection = mCursor.getString(mCursor
            .getColumnIndex(DatabaseHelper.COLUMN_COLLECTION));
    String fileName = mCursor.getString(mCursor
            .getColumnIndex(DatabaseHelper.COLUMN_FILE_NAME));
    holder.title.setText(fileName);
    if (collection.equals("true")) {
        // different folder icon for multi-column list
        holder.icon
                .setImageResource(isListSingleColumn ? R.drawable.ic_file_folder2
                        : R.drawable.ic_file_folder);
        holder.details.setText("");
    } else {
        String extension = fileName
                .substring(fileName.lastIndexOf(".") + 1);
        extension = extension.toLowerCase();
        String size = mCursor.getString(mCursor
                .getColumnIndex(DatabaseHelper.COLUMN_RESOURCE_LENGTH));
        String actualSize = MemoryManagerHelper.getInstance().getFileSize(
                Float.parseFloat(size));
        holder.icon.setImageResource(Utils.INSTANCE
                .getImageResourceForFileType(extension));
        holder.details.setText(actualSize);
    }
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
    /*
     * Inflates the item layout. Stores resource IDs in a in a ViewHolder
     * class to prevent having to look them up each time bindView() is
     * called.
     */
    final View itemView = mInflater.inflate(
            isListSingleColumn ? R.layout.explorer_row_single_column
                    : R.layout.explorer_row_multi_column, viewGroup, false);
    final ViewHolder holder = new ViewHolder();
    holder.title = (TextView) itemView.findViewById(R.id.rowtitle);
    holder.details = (TextView) itemView.findViewById(R.id.rowSubtitle);
    holder.icon = (ImageView) itemView.findViewById(R.id.icon);
    itemView.setTag(holder);
    return itemView;
}
@Override
public int getItemViewType(int position) {
    return isListSingleColumn ? TYPE_ITEM_SINGLE_COLUMN
            : TYPE_ITEM_MULTI_COLUMN;
}
@Override
public int getViewTypeCount() {
    return 2;
}
@Override
public void changeCursor(Cursor cursor) {
    super.changeCursor(cursor);
    this.mCursor = cursor;
}
/**
 * @return <b>true</b> if there is an item selected, <b>false</b> otherwise.
 */
public boolean getSelectedItemState() {
    return null == selectedView ? false : true;
}
/**
 * Set the selected item.
 * 
 * @param view
 *            The item which will be set as selected
 */
public void setSelectedItem(View view) {
    selectedView = view;
    view.setBackgroundResource(R.drawable.explorer_row_selected);
}
/**
 * If any item is selected we clear that item.
 */
public void clearSelectedItem() {
    if (null != selectedView) {
        selectedView.setBackgroundResource(android.R.color.transparent);
        // invalidate the selected item
        selectedView = null;
    }
}
private class ViewHolder {
    private TextView title;
    private TextView details;
    private ImageView icon;
}
public boolean isListSingleColumn() {
    return isListSingleColumn;
}
public void setListSingleColumn(boolean isListSingleColumn) {
    this.isListSingleColumn = isListSingleColumn;
}

问题是所有项目的布局都没有正确更改,有些显示布局已更改,有些则没有。此外,当滚动项目布局似乎发生变化时,有时它采用正确的布局,有时采用错误的布局。

我添加了一些解决方法,检测何时使用了错误的布局,并尝试手动创建正确的视图,但这似乎不起作用。

以下是我如何调用我的 CursorAdapter:

/**
     * Change the number of columns the list view will upgrade.
     * 
     * @param item
     *            - The menu action button for the toggle option
     */
    private void changeGridColumns(MenuItem item) {
        if (isListSingleColumn) {
            listview.setNumColumns(2);
            item.setIcon(R.drawable.ic_menu_listgrid2);
            mAdapter.setListSingleColumn(false);
            mAdapter.notifyDataSetChanged();
        } else {
            // Set to display list with only 1 column
            listview.setNumColumns(1);
            item.setIcon(R.drawable.ic_menu_listgrid);
            mAdapter.setListSingleColumn(true);
            mAdapter.notifyDataSetChanged();
        }
        isListSingleColumn = !isListSingleColumn;
        mAdapter.clearSelectedItem();
    }

如何解决此问题?

这不是管理项目布局更改的方式。应使用getItemViewType()getViewTypeCount方法:

public static final int SINGLE = 0;
public static final int MULTIPLE = 1;
@Override
public int getItemViewType(int position) {          
    return isListSingleColumn ? SINGLE : MULTIPLE; // call notifyDataSetChanged when you modify isListSingleColumn
}
@Override
public int getViewTypeCount() {     
    return 2;
}
// in the newView() method:
final int position = cursor.getPosition();
final int type = getItemViewType(position);
View itemView 
if (type == SINGLE) {
    itemView = mInflater.inflate(R.layout.explorer_row_single_column, viewGroup, false);
} else {
   itemView = mInflater.inflate(R.layout.explorer_row_multi_column, viewGroup, false);
}
// rest of the code

此外,顾名思义,bindView() 方法将用于将数据绑定到您收到的行视图,我不明白您为什么在那里再次构建该项目的行。

我想我通过使用覆盖getItemViewType方法解决了这个问题:

@Override
public int getItemViewType(int position) {
    return isListSingleColumn ? TYPE_ITEM_SINGLE_COLUMN
            : TYPE_ITEM_MULTI_COLUMN;
}
@Override
public int getViewTypeCount() {
    return 2;
}

我还将更新代码。

最新更新