如果我从DB返回ArrayList <customclass>并使用SimpleAdapter </customclass>,ListView不会显示查询的正确结果

时间:2014-09-08 21:01:39

标签: android android-asynctask android-sqlite simplecursoradapter simpleadapter

抱歉,如果我在这里傻瓜,但我尝试使用 LIKE 运算符查找表CLIENTE(CUSTOMER)中包含的所有记录字符串。

这是我使用的代码:

   public Cursor searchClienteByRazonSocial(String razon) {
        String where = CLIENTE_RAZONSOCIAL + " LIKE ? AND " + CLIENTE_ATENDIDO + " =?"; 
        String[] whereArgs = { "%" + razon + "%" , "0" };           

        this.openReadableDB();
        Cursor cursor = db.query(CLIENTE_TABLE, null, where, whereArgs, null,
                null, null);

        if (cursor != null) {
            cursor.moveToFirst();
        }
        this.closeDB();
        return cursor;

    }

模式有效,但是当我指定中间带有空格的名称时会出现问题,例如:

"Juan Carlos"
"Maria de Fatima"

"Juan ""Maria "会匹配并返回,但"Juan C""Maria d"不会返回任何内容。

我已尝试使用单引号"'%" + name.trim() + "%'",但它也没有用。

在此link中,您可以找到我的数据库副本(QuickOrder.db) 在该数据库中,我要查询的表格称为: Cliente 和列 razon_social

这是我尝试从Android制作的查询示例:

 SELECT * FROM cliente WHERE razon_social LIKE '%jose l%' 

我在这里错过了什么吗?

******** EDIT **********

这很奇怪,我想我有点解决这个问题,但我不明白为什么会这样。 这就是尝试做的事情

public class BuscarClientesActivity extends Activity implements
        OnQueryTextListener, OnItemClickListener {

    private ListView mResultsListView;
    private SearchView mSearchView;

    private QuickOrderDB mDB;
    private ClientesListAdapter mClientesAdapter;
    private ArrayList<Cliente> mClientes;

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

        //
        mClientes = new ArrayList<Cliente>();
        mResultsListView = (ListView) findViewById(R.id.resultadosClientesListView);
        mClientesAdapter = new ClientesListAdapter(BuscarClientesActivity.this,
                mClientes);

        mSearchView = (SearchView) findViewById(R.id.buscarClientesSearchView);
        mSearchView.setIconified(false);
        mSearchView.setOnQueryTextListener(this);

        mResultsListView.setOnItemClickListener(this);

        // get database
        mDB = new QuickOrderDB(getApplicationContext());

    }

    @Override
    public boolean onQueryTextChange(String newText) {
        if (!newText.isEmpty()) {
            displayResults(newText);
        } else {
            mResultsListView.setAdapter(mClientesAdapter);
        }
        return false;
    }

    @Override
    public boolean onQueryTextSubmit(String query) {
        displayResults(query);
        return false;
    }

    private void displayResults(String query) {
        new FiltrarClientes().execute(query);
    }
}

由于我不想在UI线程内查询数据库,因此我移动了所有用于将数据从DB提取到AsyncTask的代码,如下所示。 此AsyncTask被编码为上面显示的 BuscarClientesActivity 类中的内部类

class FiltrarClientes extends AsyncTask<String, Void, Cursor> {

        @Override
        protected Cursor doInBackground(String... params) {
            // get the query
            String query = params[0];
            Cursor resultados = BuscarClientesActivity.this.mDB
                    .searchClienteByRazonSocial(query);
            return resultados;
        }

        @Override
        protected void onPostExecute(Cursor result) {
            // create a List of Map<String,?> objects
            ArrayList<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();

            while (result.moveToNext()) {
                HashMap<String, String> map = new HashMap<String, String>();
                map.put("codigo","["+ String.valueOf(result.getInt(QuickOrderDB.CLIENTE_ID_COL))+ "]");
                map.put("razonSocial",result.getString(QuickOrderDB.CLIENTE_RAZONSOCIAL_COL));
                map.put("direccion",result.getString(QuickOrderDB.CLIENTE_DIRECCION_COL));
                data.add(map);
            }

            // close the cursor
            if (result != null) {
                result.close();
            }
            // create the resource, from, and to variables
            int resource = R.layout.resultados_clientes_item;
            String[] from = { "codigo", "razonSocial", "direccion" };
            int[] to = { R.id.itemCodClienteTextView,
                    R.id.itemRazonSocTextView, R.id.itemDireccionTextView };

            // create and set the adapter
            SimpleAdapter adapter = new SimpleAdapter(
                    BuscarClientesActivity.this, data, resource, from, to);
            mResultsListView.setAdapter(adapter);

        }
    }

如您所见,我使用 SimpleAdapter 在ListView中显示数据。这是给出这么糟糕时间的代码。然后,经过一些试验和错误,我意识到它不是SQLite问题,但是我使用的适配器类型存在问题,这是我不理解的部分,因为当我改变我的时候代码而不是SimpleAdapter我使用的SimpleCursorAdapter几乎按预期工作。

private void displayResults(String query) {
        // new FiltrarClientes().execute(query);
        Cursor resultados = mDB
                .searchClienteByRazonSocial(query);

        if (resultados != null) {

            String[] from = new String[] { QuickOrderDB.CLIENTE_ID,
                    QuickOrderDB.CLIENTE_RAZONSOCIAL,
                    QuickOrderDB.CLIENTE_DIRECCION };

            int[] to = new int[] { R.id.busqCodClienteTextView,
                    R.id.busqRazonSocTextView, R.id.busqDireccionTextView };

            @SuppressWarnings("deprecation")
            SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this,
                    R.layout.resultados_clientes_item, resultados, from, to);
            mResultsListView.setAdapter(cursorAdapter);
        }       
}

如上所示,我没有使用AsyncTask,而是在UI线程上运行此查询,现在我还使用了 SimpleCursorAdapter

现在这让我有两个问题:

  • 首先,当我使用 SimpleAdapter 时,我的代码无法正常工作的原因是什么?
  • 其次,您是否了解在不使用内容提供商的情况下查询数据库的任何有效方法。是否足以使用AsyncTask ??

再次感谢。

2 个答案:

答案 0 :(得分:0)

试试这个:

String[] whereArgs={"'%" + name.trim() + "%' OR " + "'% " + name.trim() + " %' OR " + "'% " + name.trim() + "%' OR " + "'%" + name.trim() + " %'"};

这将返回带过滤器的所有名称。

答案 1 :(得分:0)

尝试在WHERE子句模板中的占位符周围添加引号:

String where = CLIENTE_RAZONSOCIAL + " LIKE '?' AND " + CLIENTE_ATENDIDO + " =?";
String[] whereArgs = { "%" + razon + "%" , "0" };

如果您将引号放在whereArgs字符串中,那么当通过调用db.query()进行插值时,它们将被转义。