RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 612345
Accepted
Вероника
Вероника
Asked:2020-01-09 04:53:59 +0000 UTC2020-01-09 04:53:59 +0000 UTC 2020-01-09 04:53:59 +0000 UTC

使用 CursorLoader 时过滤 ListView 数据

  • 772

有AutoCompleteTextView和的活动ListView。ListView数据通过其适配器输出。

如何使y方法执行onTextChanged时, in中的AutoCompleteTextView数据ListView变化如下: 即,ListView只有那些以我们输入的字符集开头的词AutoCompleteTextView?我知道您每次都需要更新游标的内容,但我不知道该怎么做。

DBHelper代码

public class DBHeler extends SQLiteOpenHelper {
    private static String DB_PATH = "/data/data/tests.mytest3/databases/";
    private static final String DATABASE_NAME = "dbase.db";
    private static final int DATABASE_VERSION = 1;
    public SQLiteDatabase database;
    private Context myContext;

    final String ruQuery = "SELECT * " + " FROM " + Contract.Entry.TABLE_RUEN;
    final String enQuery = "SELECT * " + " FROM " + Contract.Entry.TABLE_ENRU;

    public DBHeler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.myContext = context;
    }

    public Cursor getRuWords() {
        return database.rawQuery(ruQuery, null); 
    }

    public Cursor getEnWords() {
        return database.rawQuery(enQuery, null); 
    }

    public void createDataBase() throws IOException {
        boolean dbExist = checkDataBase();

        if(dbExist){
            //ничего не делать - база уже есть
        }else{
            //вызывая этот метод создаем пустую базу, позже она будет перезаписана
            this.getReadableDatabase();

            try {
                copyDataBase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }
    }

    private boolean checkDataBase(){
        SQLiteDatabase checkDB = null;
        try {
            String myPath = DB_PATH + DATABASE_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
        } catch(SQLiteException e){
            //база еще не существует
        }
        if(checkDB != null){
            checkDB.close();
        }
        return checkDB != null ? true : false;
    }

    private void copyDataBase() throws IOException{
        InputStream myInput = myContext.getAssets().open(DATABASE_NAME);

        String outFileName = DB_PATH + DATABASE_NAME;

        OutputStream myOutput = new FileOutputStream(outFileName);

        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer))>0){
            myOutput.write(buffer, 0, length);
        }

        myOutput.flush();
        myOutput.close();
        myInput.close();
    }

    public void openDataBase() throws SQLException {
        String myPath = DB_PATH + DATABASE_NAME;
        database = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
    }

    @Override
    public synchronized void close() {
        if(database != null)
            database.close();
        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

合约类

    public class Contract {
        private Contract() {
        };

        public static final class Entry implements BaseColumns {
            public final static String TABLE_RUEN = "ruen";
            public final static String TABLE_ENRU = "enru";

            public final static String _ID = BaseColumns._ID;
            public final static String COLUMN_SLOVO = "word";
            public final static String COLUMN_PEREVOD = "translation";
            public final static String COLUMN_IZBRANNOE = "favorites";
        }
    }

适配器类

public class MySimpleCursorAdapter extends SimpleCursorAdapter {

    private int layout;

    public MySimpleCursorAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to, int flag) {
        super(context, layout, cursor, from, to, flag);
        this.layout = layout;
    }

    public static class ViewHolder {
        public TextView txtBukva;
        public TextView txtPerevod;
        public TextView txtSlovo;
        public ImageButton btnIzbrannoe;

        public ViewHolder(View view) {
            txtBukva = (TextView) view.findViewById(R.id.txtBukva);
            txtSlovo = (TextView) view.findViewById(R.id.txtSlovo);
            txtPerevod = (TextView) view.findViewById(R.id.txtPerevod);
            btnIzbrannoe = (ImageButton) view.findViewById(R.id.btnIzbrannoe);
        }
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(layout, parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
        view.setTag(viewHolder);
        return view;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        ViewHolder holder = (ViewHolder) view.getTag();

        String bukva = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_SLOVO)).substring(0, 1).toUpperCase();
        String slovo = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_SLOVO));
        String perevod = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_PEREVOD));
        String izbrannoe = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_IZBRANNOE));
        int _ID = cursor.getInt(cursor.getColumnIndex(Contract.Entry._ID));

        TextView txtBukva = (TextView) view.findViewById(R.id.txtBukva);
        TextView txtSlovo = (TextView) view.findViewById(R.id.txtSlovo);
        TextView txtPerevod = (TextView) view.findViewById(R.id.txtPerevod);
        ImageButton btnIzbrannoe = (ImageButton) view.findViewById(R.id.btnIzbrannoe);

        holder.txtBukva.setText(bukva);
        holder.txtSlovo.setText(slovo);
        holder.txtPerevod.setText(perevod);
        holder.btnIzbrannoe.setFocusable(false);

        if (izbrannoe.equals("1")) {
            holder.btnIzbrannoe.setImageResource(R.drawable.icon_star_yellow);
        } else {
            holder.btnIzbrannoe.setImageResource(R.drawable.icon_star_outline_black);
        }

        holder.btnIzbrannoe.setTag(new Slovo(_ID,slovo, perevod,bukva,izbrannoe));
    }
}

主要活动

public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {

    private EditText txtSearch;
    private Spinner spinner;
    private ListView list;
    private ImageButton btnClear;

    DBHeler db;
    private MySimpleCursorAdapter cursorAdapter;

    final private static int LOADER_RUS = 0;
    final private static int LOADER_ENG = 1;

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

        db = new DBHeler(this);

        try {
            db.createDataBase();
            db.openDataBase();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        spinner = (Spinner) findViewById(R.id.spinner);
        txtSearch = (EditText) findViewById(R.id.txtSearch);
        list = (ListView) findViewById(R.id.list);
        btnClear = (ImageButton) findViewById(R.id.btnClear);

        ArrayAdapter<?> adapter = ArrayAdapter.createFromResource(this, R.array.types, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);

        String[] from = new String[] {Contract.Entry.COLUMN_SLOVO, Contract.Entry.COLUMN_SLOVO, Contract.Entry.COLUMN_PEREVOD, Contract.Entry.COLUMN_IZBRANNOE};
        int[] to = new int[] {R.id.txtBukva, R.id.txtSlovo, R.id.txtPerevod, R.id.btnIzbrannoe};

        cursorAdapter = new MySimpleCursorAdapter(this, R.layout.item, null, from, to, 0);

        list.setAdapter(cursorAdapter);

        // инициализируем оба загрузчика
        getSupportLoaderManager().initLoader(LOADER_RUS, null, this);
        getSupportLoaderManager().initLoader(LOADER_ENG, null, this);

        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int loadID, long l) {
                getSupportLoaderManager().getLoader(loadID).forceLoad(); // обновляем данные в курсоре
            }
            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();

        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Intent intent = new Intent(MainActivity.this, SlovoActivity.class);
                CharSequence strCharSequence = ((TextView)view.findViewById(R.id.txtSlovo)).getText();
                String str = strCharSequence.toString().toLowerCase().trim();
                String selectedItem = spinner.getSelectedItem().toString();
                if (selectedItem.equals("С русского на английский")) {
                    intent.putExtra("slovo", str);
                    intent.putExtra("type", "RU");
                    startActivity(intent);
                } else if (selectedItem.equals("С английского на русский")) {
                    intent.putExtra("slovo", str);
                    intent.putExtra("type", "EN");
                    startActivity(intent);
                }
            }
        });
    }

    public void onFavoriteClick(View view) {

        Slovo data = (Slovo)view.getTag();
        long id = data.id;
        String slovo = data.word;
        String perevod = data.perevod;
        String bukva = data.simbol;
        boolean izbrannoe = data.favorite;

        String selectedItem = spinner.getSelectedItem().toString();
        if (selectedItem.equals("С русского на английский")) {
            if (!izbrannoe) {
                ContentValues values = new ContentValues();
                values.put(Contract.Entry.COLUMN_IZBRANNOE, "1");

                // Вставляем новый ряд в базу данных и запоминаем его идентификатор
                long newRowId = db.database.update(Contract.Entry.TABLE_RUEN, values, Contract.Entry.COLUMN_SLOVO + "= ?", new String[]{slovo});
                //izbrannoe = true;
                // Выводим сообщение в успешном случае или при ошибке
                if (newRowId == -1) { // Если ID  -1, значит произошла ошибка
                    Toast.makeText(this, "Ошибка", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "Добавлено в избранное", Toast.LENGTH_SHORT).show();
                    getSupportLoaderManager().getLoader(LOADER_RUS).forceLoad();
                }
            } else if (izbrannoe) {
                ContentValues values = new ContentValues();
                values.put(Contract.Entry.COLUMN_IZBRANNOE, "0");

                // Вставляем новый ряд в базу данных и запоминаем его идентификатор
                long newRowId = db.database.update(Contract.Entry.TABLE_RUEN, values, Contract.Entry.COLUMN_SLOVO + "= ?", new String[]{slovo});
                //izbrannoe = true;
                // Выводим сообщение в успешном случае или при ошибке
                if (newRowId == -1) { // Если ID  -1, значит произошла ошибка
                    Toast.makeText(this, "Ошибка", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "Удалено из избранного", Toast.LENGTH_SHORT).show();
                    getSupportLoaderManager().getLoader(LOADER_RUS).forceLoad();
                }
            }
        } else if (selectedItem.equals("С английского на русский")) {
            if (!izbrannoe) {
                ContentValues values = new ContentValues();
                values.put(Contract.Entry.COLUMN_IZBRANNOE, "1");

                // Вставляем новый ряд в базу данных и запоминаем его идентификатор
                long newRowId = db.database.update(Contract.Entry.TABLE_ENRU, values, Contract.Entry.COLUMN_SLOVO + "= ?", new String[]{slovo});
                //izbrannoe = true;
                // Выводим сообщение в успешном случае или при ошибке
                if (newRowId == -1) { // Если ID  -1, значит произошла ошибка
                    Toast.makeText(this, "Ошибка", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "Добавлено в избранное", Toast.LENGTH_SHORT).show();
                    getSupportLoaderManager().getLoader(LOADER_ENG).forceLoad();
                }
            } else if (izbrannoe) {
                ContentValues values = new ContentValues();
                values.put(Contract.Entry.COLUMN_IZBRANNOE, "0");

                // Вставляем новый ряд в базу данных и запоминаем его идентификатор
                long newRowId = db.database.update(Contract.Entry.TABLE_ENRU, values, Contract.Entry.COLUMN_SLOVO + "= ?", new String[]{slovo});
                //izbrannoe = true;
                // Выводим сообщение в успешном случае или при ошибке
                if (newRowId == -1) { // Если ID  -1, значит произошла ошибка
                    Toast.makeText(this, "Ошибка", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "Удалено из избранного", Toast.LENGTH_SHORT).show();
                    getSupportLoaderManager().getLoader(LOADER_ENG).forceLoad();
                }
            }
        }
    }

    protected void onDestroy() {
        super.onDestroy();
        db.close();
    }

    static class MyCursorLoader extends CursorLoader {
        Cursor cursor;
        DBHeler dbHeler;
        final int loaderID;

        public MyCursorLoader(Context context, DBHeler dbHeler, int id) {
            super(context);
            this.dbHeler = dbHeler;
            loaderID = id;
        }

        @Override
        protected Cursor onLoadInBackground() {
            switch (loaderID) {
                case LOADER_RUS:
                    cursor = dbHeler.getRuWords();
                    break;
                case LOADER_ENG:
                    cursor = dbHeler.getEnWords();
                    break;
            }
            return cursor;
        }
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return new MyCursorLoader(this, db, id);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        cursorAdapter.swapCursor(data);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        cursorAdapter.swapCursor(null);
    }
}

斯洛沃班

public class Slovo {
    long id;
    String word;
    String perevod;
    String simbol;
    boolean favorite;

    public Slovo(long id, String word, String perevod, String simbol, String favorite) {
        this.id = id;
        this.word = word;
        this.perevod = perevod;
        this.simbol = simbol;
        this.favorite = (favorite.equals("1"))? true:false;
    }
}
java
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    pavlofff
    2020-01-10T12:18:13Z2020-01-10T12:18:13Z

    连接的一切看起来像这样。我用 imports给出代码,因为 API 和支持库中有重复的类 - 所以没有错误。

    Для реализации фильтра по данным списка, управляемого через CursorLoader нужно проделать всего две вещи:

    1. Получить строку для фильтрации
    2. Составить запрос в БД на получение данных по этой строке
    3. Уведомить загрузчик о изменениях

    Строку для фильтра можно вводить в EditText или SearchView. Подключаем слушатель, который позволяет получать текст по мере набора и делаем в БД запросы по этому набору. Для обновления списка используем метод менеджера загрузчиков restartLoader(), который уведомляет, что выборка из БД изменилась и надо обновить список.

    Запрос на выборку данных из БД по неполному соответствию (только начало слова) делаем через оператор SQL LIKE, который находит вхождение подстроки в строке. На SQL запрос выглядит так:

    SELECT * FROM table WHERE UPPER(column) LIKE substrig%
    

    что значит - выбрать все столбцы из таблицы table, где в столбце column встречается подстрока substring без учета регистра (с кириллическими символами к сожалению без мутных костылей это не работает).

    класс MainActivity. Здесь помимо реализации самого фильтра по списку много рефакторинга, улучшающего и оптимизирующего код, надеюсь вы сравните и примите на заметку в будущем:

    import android.content.ContentValues;
    import android.content.Context;
    import android.content.Intent;
    import android.database.Cursor;
    import android.os.Bundle;
    import android.support.v4.app.LoaderManager;
    import android.support.v4.content.Loader;
    import android.support.v4.content.CursorLoader;
    import android.support.v7.app.AppCompatActivity;
    import android.text.Editable;
    import android.text.TextWatcher;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.EditText;
    import android.widget.ImageButton;
    import android.widget.ListView;
    import android.widget.Spinner;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity implements  LoaderManager.LoaderCallbacks<Cursor> {
    
        private EditText txtSearch;
        private Spinner spinner;
        private ListView list;
        private ImageButton btnClear;
    
        DBHeler db;
        private MyCursorAdapter cursorAdapter;
        private int currentLoader;
        final private static int LOADER_RUS = 0;
        final private static int LOADER_ENG = 1;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            db = new DBHeler(this);
    
            spinner = (Spinner) findViewById(R.id.spinner);
            txtSearch = (EditText) findViewById(R.id.txtSearch);
            list = (ListView) findViewById(R.id.list);
            btnClear = (ImageButton) findViewById(R.id.btnClear);
    
            ArrayAdapter<?> adapter = ArrayAdapter.createFromResource(this, R.array.types, android.R.layout.simple_spinner_item);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            spinner.setAdapter(adapter);
    
            cursorAdapter = new MyCursorAdapter(this, R.layout.item, null, 0);
            list.setAdapter(cursorAdapter);
    
            // при старте выводим все данные (фильтр - пустая строка)
            Bundle bundle = new Bundle(1);
            bundle.putString("filter", "");
    
            getSupportLoaderManager().initLoader(LOADER_RUS, bundle, this);
            getSupportLoaderManager().initLoader(LOADER_ENG, bundle, this);
    
            spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> adapterView, View view, int loadID, long l) {                    
                    getSupportLoaderManager().getLoader(loadID).forceLoad();
                    currentLoader = loadID;
                    txtSearch.setText(null); // при смене языка очищаем поле поиска
                }
                @Override
                public void onNothingSelected(AdapterView<?> adapterView) {
                }
            });
    
            txtSearch.addTextChangedListener(new TextWatcher(){
                public void onTextChanged(CharSequence s, int start, int before, int count)
                {
                    // получаем строку по мере ввода
                    refreshCursor(s.toString());
                }
                @Override
                public void afterTextChanged(Editable text) {}
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
            });
        }
    
        private void refreshCursor(String str) {
            //передаем в загрузчик строку для фильтра и перезапускаем загрузчик для обновления списка
            Bundle bundle = new Bundle(1);
            bundle.putString("filter", str);
            getSupportLoaderManager().restartLoader(currentLoader, bundle, this);
        }
    
        @Override
        protected void onResume() {
            super.onResume();
    
            list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                    Intent intent = new Intent(MainActivity.this, SlovoActivity.class);
                    Cursor cursor = (Cursor) cursorAdapter.getItem(position);
                    String str = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_SLOVO)).toLowerCase().trim();
                    int selectedItem = spinner.getSelectedItemPosition();
                    intent.putExtra("slovo", str);
                    intent.putExtra("type", selectedItem == 0 ? "RU" : "EN");
                    startActivity(intent);
                }
            });
        }
    
        public void onFavoriteClick(View view) {
    
            Slovo data = (Slovo)view.getTag();
            long id = data.id;
            String slovo = data.word;
            String perevod = data.perevod;
            String bukva = data.simbol;
            boolean izbrannoe = data.favorite;
    
            String table;
            String fav;
            String toast;
            int currentLoader;
    
            if (spinner.getSelectedItemPosition() == 0) {
                table = Contract.Entry.TABLE_RUEN;
                currentLoader = LOADER_RUS;
            } else {
                table = Contract.Entry.TABLE_ENRU;
                currentLoader = LOADER_ENG;
            }
    
            if (izbrannoe) {
                fav = "0";
                toast = "Удалено из избранного";
            } else {
                fav = "1";
                toast = "Добавлено в избранное";
            }
    
            ContentValues values = new ContentValues();
            values.put(Contract.Entry.COLUMN_IZBRANNOE, fav);
            long newRowId = db.database.update(table, values, Contract.Entry.COLUMN_SLOVO + "= ?", new String[]{slovo});
            if (newRowId == -1) {
                  Toast.makeText(this, "Ошибка", Toast.LENGTH_SHORT).show();
            } else {
                  Toast.makeText(this, toast, Toast.LENGTH_SHORT).show();
                  getSupportLoaderManager().getLoader(currentLoader).forceLoad();
             }
        }
    
        protected void onDestroy() {
            super.onDestroy();
             // закрывать БД здесь не следует, так как это приводит к падениям при повороте
             // многие  склоняются к мысли, что БД вообще не следует закрывать
        }
    
        @Override
        public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
            String filter = bundle.getString("filter");
            return new MyCursorLoader(this, db, id, filter);
        }
    
        @Override
        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
              cursorAdapter.swapCursor(data);
        }
    
        @Override
        public void onLoaderReset(Loader<Cursor> loader) {
              cursorAdapter.swapCursor(null);
        }
    
        static class MyCursorLoader extends CursorLoader {
            Cursor cursor;
            DBHeler dbHeler;
            final int loaderID;
            String filter;
    
            public MyCursorLoader(Context context, DBHeler dbHeler, int id, String filter) {
                super(context);
                this.dbHeler = dbHeler;
                loaderID = id;
                this.filter = filter;
            }
    
            @Override
            protected Cursor onLoadInBackground() {
                switch (loaderID) {
                    case LOADER_RUS:
                        // выборка с учетом фильтра
                        cursor = dbHeler.getRuWords(filter);
                        break;
                    case LOADER_ENG:
                        cursor = dbHeler.getEnWords(filter);
                        break;
                }
                return cursor;
            }
        }
    }
    

    Информация о необходимости [не]закрытия базы данных. Для обработки клика на избранном используется такой способ.

    Класс MyCursorAdapter. Здесь тоже небольшой рефакторинг и оценив, что требуется от адаптера в вашем случае, решил отказаться от SimpleCursorAdapter, так как его возможности все равно не используются:

    import android.content.Context;
    import android.database.Cursor;
    import android.support.v4.widget.CursorAdapter;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageButton;
    import android.widget.TextView;
    
    public class MyCursorAdapter extends CursorAdapter {
    
        private int layout;
    
        public MyCursorAdapter(Context context, int layout, Cursor cursor, int flag) {
            super(context, cursor, flag);
            this.layout = layout;
        }
    
        public static class ViewHolder {
            public TextView txtBukva;
            public TextView txtPerevod;
            public TextView txtSlovo;
            public ImageButton btnIzbrannoe;
    
            public ViewHolder(View view) {
                txtBukva = (TextView) view.findViewById(R.id.txtBukva);
                txtSlovo = (TextView) view.findViewById(R.id.txtSlovo);
                txtPerevod = (TextView) view.findViewById(R.id.txtPerevod);
                btnIzbrannoe = (ImageButton) view.findViewById(R.id.btnIzbrannoe);
            }
        }
    
        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
            View view = inflater.inflate(layout, parent, false);
            ViewHolder viewHolder = new ViewHolder(view);
            view.setTag(viewHolder);
            return view;
        }
    
        @Override
        public void bindView(View view, Context context, Cursor cursor) {
    
            ViewHolder holder = (ViewHolder) view.getTag();
    
            String bukva = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_SLOVO)).substring(0, 1).toUpperCase();
            String slovo = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_SLOVO));
            String perevod = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_PEREVOD));
            String izbrannoe = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_IZBRANNOE));
            int _ID = cursor.getInt(cursor.getColumnIndex(Contract.Entry._ID));
    
            holder.txtBukva.setText(bukva);
            holder.txtSlovo.setText(slovo);
            holder.txtPerevod.setText(perevod);
            holder.btnIzbrannoe.setFocusable(false);
    
            // здесь получение ссылок на виджеты совершенно излишне и "убивает"
            // преимущество использования ViewHolder
    
            if (izbrannoe.equals("1")) {
                holder.btnIzbrannoe.setImageResource(R.drawable.icon_star_yellow);
            } else {
                holder.btnIzbrannoe.setImageResource(R.drawable.icon_star_outline_black);
            }
    
            holder.btnIzbrannoe.setTag(new Slovo(_ID,slovo, perevod,bukva,izbrannoe));
        }
    }
    

    класс DBhelper. Ваш вариант этого класса не захотел у меня копировать БД, предлагаю свой, не зависимый от имени приложения. Так же небольшой рефакторинг - в БД лучше отправлять не "сырые" запросы rawQuery()), а через метод query(), он более безопасен:

    public class DBHeler extends SQLiteOpenHelper {
        private static String DB_PATH;
        private static final String DATABASE_NAME = "dbase.db";
        private static final int DATABASE_VERSION = 1;
        public SQLiteDatabase database;
        private Context myContext;
    
        public DBHeler(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            this.myContext = context;
            try {
                //получаем путь до БД вместе с именем.
                DB_PATH = myContext.getDatabasePath(DATABASE_NAME).toString();
                createDataBase();
                openDataBase();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public Cursor getRuWords(String filter) {
            return database.query(Contract.Entry.TABLE_RUEN,
                    new String[] {"*"},
                    "UPPER(" + Contract.Entry.COLUMN_SLOVO + ")" + " LIKE ?",
                    new String[] {filter + "%"},
                    null, null, null);
        }
    
        public Cursor getEnWords(String filter) {
            return database.query(Contract.Entry.TABLE_ENRU,
                    new String[] {"*"},
                    "UPPER(" + Contract.Entry.COLUMN_SLOVO + ")" + " LIKE ?",
                    new String[] {filter + "%"},
                    null, null, null);
        }
    
        public void createDataBase() throws IOException {
    
            boolean dbExist = checkDataBase();
    
            if (!dbExist) {
                this.getReadableDatabase();
                try {
                    copyDataBase();
                }
                catch (IOException e) {
                    throw new Error("Error copying database");
                }
            }
        }
    
        private boolean checkDataBase(){
            SQLiteDatabase checkDB = null;
            try {
    
                checkDB = SQLiteDatabase.openDatabase(DB_PATH, null, SQLiteDatabase.OPEN_READONLY);
            }
            catch (SQLiteException e) {
                // база не существует
            }
            if (checkDB != null) {
                checkDB.close();
            }
            return checkDB != null;
        }
    
        private void copyDataBase() throws IOException {
            InputStream myInput = myContext.getAssets().open(DATABASE_NAME);
    
            String outFileName = DB_PATH;
    
            OutputStream myOutput = new FileOutputStream(outFileName);
    
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer))>0){
                myOutput.write(buffer, 0, length);
            }
    
            myOutput.flush();
            myOutput.close();
            myInput.close();
        }
    
        public void openDataBase() throws SQLException {
            database = SQLiteDatabase.openDatabase(DB_PATH, null, SQLiteDatabase.OPEN_READWRITE);
        }
    
        @Override
        public synchronized void close() {
            if(database != null)
                database.close();
            super.close();
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    
        }
    }
    

    Остальные классы без измений. Данные классы лучше копировать целиком, так как вносил много изменений в разных местах.

    • 8

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5