ListView 的动态行布局

Dynamic row layout for ListView

我有一个 ListView,我使用 SimpleCursorAdapter 从数据库发送数据,但我需要动态行布局,因为每个 table 可以有不同数量的列。

假设我根据列数创建 TextViews

    public int getColumnNumbers() {
        int i = 0;

        cursor = db.rawQuery("PRAGMA table_info("+DATABASE_TABLE_NAME+")", null);

        if (cursor.moveToFirst()) {
            do {
                i++;
            } while (cursor.moveToNext());
        }
        cursor.close();

        return i;
    }

  ........

    int rowsNumber = getColumnNumbers();
    textViews = new TextView[rowsNumber];

    for(i = 0; i < rowsNumber; i++) {
        textViews[i] = new TextView(this);
        textViews[i].setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    }

我基本上在寻找的是一种将这些 TextViews 传递给 CursorAdapter 的(或其他适配器的)参数 int[] to

的方法

我对此很陌生,所以我将不胜感激任何帮助或建议。

编辑:

我正在添加 bindView 方法的实现,这是我借助此处提供的链接制作的,以防将来有人遇到类似问题。

    @Override
public void bindView(View view, Context context, Cursor cursor) {
    int i, count = myHelper.getColumnNumbers();
    String[] columnNames = myHelper.getColumnNamesString();
    String text;
    LinearLayout layout = (LinearLayout) view.findViewById(R.id.linear_layout_horizontal);

    for(i = 0; i < (count-1); i++) {
        TextView textView = new TextView(context);
        textView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
        text = cursor.getString(cursor.getColumnIndexOrThrow(columnNames[i+1]));
        textView.setText(text);

        layout.addView((TextView)textView);
    }
}

编辑 2:

我昨天发现上面提到的实现在你需要滚动之前一直有效。滚动后,ListView 变形。 因此,如果有人想做类似的事情,我将添加我的整个适配器 class.

public class DatabaseCursorAdapter extends CursorAdapter {
private DatabaseHelper myHelper;
private int count;
private String[] columnNames;

public DatabaseCursorAdapter(Context context, Cursor cursor) {
    super(context, cursor, 0);
    myHelper = new DatabaseHelper(context);

    count = myHelper.getColumnNumbers();
    columnNames = myHelper.getColumnNamesString();
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    View view = LayoutInflater.from(context).inflate(R.layout.text_select, parent, false);
    LinearLayout layout = (LinearLayout) view.findViewById(R.id.linear_layout_horizontal);
    int i;

    for(i = 0; i < count; i++) {
        TextView textView = new TextView(context);
        textView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1f));
        textView.setTag(Integer.valueOf(i));
        layout.addView(textView);
    }

    return view;
}

@Override
public void bindView(View view, Context context, Cursor cursor) {
    int i;
    String text;

    for(i = 0; i < count; i++) {
        TextView textView = (TextView) view.findViewWithTag(Integer.valueOf(i));
        text = cursor.getString(cursor.getColumnIndexOrThrow(columnNames[i]));
        textView.setText(text);
    }
}
}

和大多数问题一样,解决方案非常简单。技术几乎与使用静态布局相同,除了不使用 findViewById,您只需标记布局的元素并使用 findViewWithTag 方法。

你需要看看好的教程,一个link是 Populating a ListView with a CursorAdapter。该网页有一些很好的解释。

查看 TodoCursorAdapterbindView 方法以检查数据库中可用的 column/data。教程中的代码片段:

@Override
  public void bindView(View view, Context context, Cursor cursor) {
      // Find fields to populate in inflated template
      TextView tvBody = (TextView) view.findViewById(R.id.tvBody);
      // Extract properties from cursor
      String body = cursor.getString(cursor.getColumnIndexOrThrow("body"));
      // Populate fields with extracted properties
      tvBody.setText(body);
  }

我认为这是一个简单的代码设计。 网页中用于将数据填充到 Listview 的代码:

// Find ListView to populate
ListView lvItems = (ListView) findViewById(R.id.lvItems);
// Setup cursor adapter using cursor from last step
TodoCursorAdapter todoAdapter = new TodoCursorAdapter(this, todoCursor);
// Attach cursor adapter to the ListView 
lvItems.setAdapter(todoAdapter);

您可以实现 ArrayAdapter 而不是 CursorAdapter。如果您的应用程序不持续与数据库交互,这是有意义的。 link 是 Using an ArrayAdapter with ListView 。这是同一个网站。 在这种情况下,请查看 getView 方法而不是类似的 bindView.