2013-12-23 63 views
2

我想在创建特定按钮(操作)时更改行布局。更改自定义CursorAdapter的行布局

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

我怎样才能解决这个问题?

+0

我今天也遇到了CursorAdapter的一些问题。如果我想出任何提示,我一定会分享! – Matt

+0

谢谢@Matt,如果我在此期间找到任何解决方案,我将同时发布答案。 –

回答

5

这不是你应该如何管理项目的布局变化。您应该使用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()方法是用于绑定您收到的数据行的看法,我不明白你为什么要建该项目的行再次在那里。

+0

这正是我所做的:D ...当我发布的答案我没有看到你的:) ...我仍然会投票你的答案是正确的。 –

+0

@IonutNegru我迟到了10秒,在写作时我没有看到你的答案。 – Luksprog

+0

我可以为不同类型的编号充气相同类型的布局吗? – deadfish

3

我想我用压倒一切的getItemViewType方法解决了该问题:

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

@Override 
public int getViewTypeCount() { 
    return 2; 
} 

我也将更新的代码。