Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/188.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用setFilterQueryProvider重新重复列_Android_Sqlite_Listview_Simplecursoradapter - Fatal编程技术网

Android 使用setFilterQueryProvider重新重复列

Android 使用setFilterQueryProvider重新重复列,android,sqlite,listview,simplecursoradapter,Android,Sqlite,Listview,Simplecursoradapter,我有一个列表视图有问题。我想用edittext实现经典搜索,我正在使用addTextChangedListener和TextWatcher()。Listview从数据库获取元素,因此我使用游标和simplecursoradapter,因此我必须使用setFilterQueryProvider。当我在编辑文本中写东西时,问题就出现了,如果我写产品的名称,它会改变列表中所有元素的名称,所以我不知道该怎么办。谢谢你的帮助 以下是我在listview中的java代码: public class List

我有一个列表视图有问题。我想用edittext实现经典搜索,我正在使用addTextChangedListener和TextWatcher()。Listview从数据库获取元素,因此我使用游标和simplecursoradapter,因此我必须使用setFilterQueryProvider。当我在编辑文本中写东西时,问题就出现了,如果我写产品的名称,它会改变列表中所有元素的名称,所以我不知道该怎么办。谢谢你的帮助

以下是我在listview中的java代码:

public class Lista_general extends ListActivity {

SimpleCursorAdapter adapter;
ListView list;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.lista_general);


     list = getListView();


    EditText edit =(EditText)findViewById(R.id.edit);


    // open database
    AdminSQLiteOpenHelper dbhelper = new AdminSQLiteOpenHelper(
            getBaseContext());
    SQLiteDatabase db = dbhelper.getReadableDatabase();

    // array for SimpleCursorAdapter
        String columns[] = new String[] { "PRODUCTO._id",  
       "nombre","category","CATEGORIAS._id","categoryid" };


    String orderBy = "category";


          // query database

       Cursor c = db.query("PRODUCTO, CATEGORIAS WHERE CATEGORIAS._id = categoryid  ", 
       columns,null,null, null, null, orderBy);


    c.moveToFirst();

    // array for SimpleCursorAdapter
    String from[] = new String[] { "nombre", "category", };
    //String from[] = new String[] { "nombre", "categoria", };

    int to[] = new int[] { R.id.name, R.id.cate, };

    // Adapter
    adapter = new SimpleCursorAdapter(getBaseContext(),
            R.layout.productos, c, from, to,
            SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

    setListAdapter(adapter);


    list.setTextFilterEnabled(true);

    //Listener edit text
    edit.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                    int count) {

        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {


        }

        @Override
        public void afterTextChanged(Editable s) {

            adapter.getFilter().filter(s.toString());  

        }
    });


    adapter.setFilterQueryProvider(new FilterQueryProvider() {

        @Override
        public Cursor runQuery(CharSequence constraint) {
            // TODO Auto-generated method stub

            AdminSQLiteOpenHelper dbhelper = new AdminSQLiteOpenHelper(
                    getBaseContext());
            SQLiteDatabase db = dbhelper.getReadableDatabase();


             Cursor mCursor = null;
              if (constraint == null  || constraint.length () == 0)  {


              mCursor = db.query("PRODUCTO, CATEGORIAS", new String[] { 
                      "PRODUCTO._id", "nombre","CATEGORIAS._id","category"}, 
              null, null, null, null, null);


              }
              else {



               mCursor = db.query(true,"PRODUCTO, CATEGORIAS", new String[] 
                      {"PRODUCTO._id", "nombre", "category","CATEGORIAS._id"}, 
              "nombre" + " like '%" + constraint + "%'", null,                      
                      null, null, null, null);
              }
              if (mCursor != null) {
               mCursor.moveToFirst();
              }



            return mCursor;
        }
    });
}
以下是我的错误的视觉效果:

首先,我的正常列表:

在我写完之后:

FilterQueryProvider
中生成的查询似乎没有正确地连接表,因此您最终得到了
PRODUCTO
CATEGORIAS
的所有可能组合(然后通过
PRODUCTO.nombre
进行过滤,以给人留下所有名称都已更改的印象)

直接在查询中插入
约束也存在潜在的安全风险,这为SQL注入攻击打开了大门。我不确定这在Android应用程序的上下文中有多严重,但在例如PHP web应用程序中,这将允许任何人通过输入精心编制的
约束来执行他们想要的任何SQL


从对它的回答来看,使用SQL
JOIN
需要调用
rawQuery()
,因此我将更改您的查询如下

对于无过滤器的查询(即在
onCreate()
中;以及在
runQuery()
中没有
约束的情况下):

对于使用筛选器进行查询:

String[] params = { constraint.toString() };
cursor = db.rawQuery("SELECT PRODUCTO._id, nombre, category, CATEGORIAS._id FROM PRODUCTO INNER JOIN CATEGORIAS ON PRODUCTO.categoryid = CATEGORIAS._id WHERE nombre LIKE ('%' || ? || '%')", params);

非常感谢你,这就是答案。只有少量的校正字符串[]params={(字符串)约束};我正在使用eclipse,它说我必须向字符串添加cast。好的一点是,整个
CharSequence
的事情一直让我感到困惑。使用
constraint.toString()
而不是强制转换更安全,我将编辑答案。
String[] params = { constraint.toString() };
cursor = db.rawQuery("SELECT PRODUCTO._id, nombre, category, CATEGORIAS._id FROM PRODUCTO INNER JOIN CATEGORIAS ON PRODUCTO.categoryid = CATEGORIAS._id WHERE nombre LIKE ('%' || ? || '%')", params);