I try to transfer the data to the Activity method from this response . In the myStr array, the last element of the ListView now always appears.

My adapter code:

 public class MyCursorAdapter extends CursorAdapter { private int layout; //Π½ΡƒΠΆΠ΅Π½ для создания ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² класса View String[] myStr = new String[3]; //OnFavoriteListener callback; public MyCursorAdapter(Context context, int layout, Cursor c, int flags) { super(context, c, flags); this.layout = layout; } public static class ViewHolder { public TextView txtBukva; public TextView txtSlovo; public ImageButton btnIzbrannoe; public void setBtnIzbrannoe(ImageButton btnIzbrannoe) { this.btnIzbrannoe = 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); return view; } @Override public void bindView(View view, Context context, final Cursor cursor) { final ViewHolder holder = new ViewHolder(); String bukva = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_SLOVO)).substring(0, 1).toUpperCase(); final String slovo = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_SLOVO)); final String izbrannoe = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_IZBRANNOE)); int _ID = cursor.getInt(cursor.getColumnIndex(Contract.Entry._ID)); holder.txtBukva = (TextView) view.findViewById(R.id.txtBukva); holder.txtSlovo = (TextView) view.findViewById(R.id.txtSlovo); holder.btnIzbrannoe = (ImageButton) view.findViewById(R.id.btnIzbrannoe); holder.txtBukva.setText(bukva); holder.txtSlovo.setText(slovo); holder.btnIzbrannoe.setFocusable(false); if (izbrannoe.equals("1")) { holder.btnIzbrannoe.setImageResource(R.drawable.icon_star_yellow); } else if (izbrannoe.equals("0")) { holder.btnIzbrannoe.setImageResource(R.drawable.icon_star_outline_black); } myStr[0] = _ID + ""; myStr[1] = slovo; myStr[2] = izbrannoe; holder.btnIzbrannoe.setTag(myStr); } } 

How to transfer the data corresponding to the clicked item?

This is the code that turned out in MainActivity.

 public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> { private AutoCompleteTextView txtSearch; private Spinner spinner; private ListView list; private ImageButton btnClear; DBHeler db; private MySimpleCursorAdapter cursorAdapter; final private static int LOADER_RUS = 0; //0 - ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π² spinner ΠΏΠ΅Ρ€Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ id 0 final private static int LOADER_ENG = 1; //1 - ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π² spinner ΠΏΠ΅Ρ€Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ id 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 = (AutoCompleteTextView) 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() { /*ΠŸΡ€ΠΈ Π²Ρ‹Π±ΠΎΡ€Π΅ ΠΏΡƒΠ½ΠΊΡ‚Π° Π² спинСрС ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊΠ° происходит ΠΏΠΎ Π½Π°ΠΆΠ°Ρ‚ΠΎΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ (Π° Π½Π΅ ΠΏΠΎ содСрТимому ΠΏΡƒΠ½ΠΊΡ‚Π° списка) - Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ колбэка с ΠΈΠΌΠ΅Π½Π΅ΠΌ loadID Π² Π΄Π°Π½Π½ΠΎΠΌ ΠΊΠΎΠ΄Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΡƒΠ½ΠΊΡ‚Π°. ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ 0 ΠΈΠ»ΠΈ 1, ID Π½Π°ΡˆΠΈΡ… Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊΠΎΠ² Ρ‚Π°ΠΊ ΠΆΠ΅ 0 ΠΈΠ»ΠΈ 1 для русского ΠΈ английского Π½Π°Π±ΠΎΡ€Π° соотвСтствСнно.*/ @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); } } }); txtSearch.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 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(MainActivity.this, R.layout.item, null, from, to, 0); list.setAdapter(cursorAdapter); } @Override public void afterTextChanged(Editable editable) { } }); } 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; //System.out.println(id + " " + slovo + " " + perevod + " " + bukva + " " + izbrannoe); if (izbrannoe == false) { 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 == true) { 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(); } } } public void onClearBtnClick(View view) { txtSearch.setText(""); btnClear.setVisibility(View.INVISIBLE); } 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); } } 
  • That is, the correct data is displayed in a TextView , and in the myStr array they also appear from the last item? - pavlofff
  • Yes exactly. - Veronica
  • I'll finally get confused - Veronica
  • How to do it? In general, what should the adapter look like in my case? - Veronica
  • Good. I look at examples 6 and some sites are made as I did, some through a simplecursoradapter. But I have a button in the listview so it’s difficult because you need to implement a method for clicking this button. - Veronica

1 answer 1

Since you have all sorts of data (number and lines), it is more reasonable to use a model object for data transfer. In addition, specifically in your case, due to the restriction of the finished database, which stores the state of the selected as a string, we will perform a useful conversion - it is logical to represent this state as a boolean . The state is true - in favorites, false - not in favorites, it will greatly simplify the processing logic.

Create a class model (where there are activity classes, etc.):

 public class Data { long id; String word; String simbol; boolean favorite; public Data(long id, String word, String simbol, String favorite) { this.id = id; this.word = word; this.simbol = simbol; this.favorite = (favorite.equals("1"))? true:false; } } 

Now we fill in this model in the adapter and send it via a tag (only the code necessary for the demonstration from the adapter):

 public class MyCursorAdapter extends CursorAdapter { public static class ViewHolder { public TextView txtBukva; public TextView txtSlovo; public ImageButton btnIzbrannoe; public ViewHolder(View view) { txtBukva = (TextView) view.findViewById(R.id.txtBukva); txtSlovo = (TextView) view.findViewById(R.id.txtSlovo); 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, final Cursor cursor) { ViewHolder holder = (ViewHolder) view.getTag(); String bukva = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_SLOVO)).substring(0, 1).toUpperCase(); final String slovo = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_SLOVO)); final String izbrannoe = cursor.getString(cursor.getColumnIndex(Contract.Entry.COLUMN_IZBRANNOE)); long _ID = cursor.getLong(cursor.getColumnIndex(Contract.Entry._ID)); holder.txtBukva.setText(bukva); holder.txtSlovo.setText(slovo); 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); } // Ρ‡Π΅Ρ€Π΅Π· конструктор устанавливаСм значСния для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π² Activity holder.btnIzbrannoe.setTag(new Data(_ID,slovo,bukva,izbrannoe); } } 

We receive in Activity:

 public void onFavoriteClick(View view) { Data data = (Data)view.getTag(); long id = data.id; String slovo = data.word; String bukva = data.simbol; boolean izbrannoe = data.favorite; } 

If the data is planned to be used outside the clicker, then we place local variables in the class fields.

PS: Also fixed the use of the ViewHolder pattern. The purpose of the pattern is to cache the links to the objects of the item (you get these links every time you bind to the item and the holder is useless in this form). The point is that getting the link to the widget from the markup using the findViewById() method is quite a resource-intensive operation to perform when creating each item, so these links are obtained once when creating the markup, and then stored in the holder. The above methods are newView() and bindView() without code abbreviations.

PPS: the ID value from the database is recommended to be received in long (and not int ) since this number can be very large, I recommend correcting (in the example I made corrections).

  • But you said that it is better to inherit from SimpleCursorAdapter? And I redid the code a bit from the SimpleCursorAdapter - Veronica
  • @ Veronica does not change anything in the solution of your question - pavlofff
  • Ok, based on SimpleCursorAdapter done, it works in onFavoriteClick every time I get the necessary data. And such a question: now in the onFavoriteClick method I need to work with boolean izbrannoe in order to update the izbrannoe column in the database as well, for example? And let's say if you manage to add a word to your favorites, then the icon for the btnIzbrannoe button will automatically change in ListVew? - Veronica
  • and obviously change them so yes getSupportLoaderManager (). getLoader (loadID) .forceLoad () ;? - Veronica
  • It seems to work. In my question I will update the code. Look here please. - Veronica