Search code examples
androidandroid-arrayadapter

Saved item's state in simple list item


I am a new android developer and I need your help. I created a simple listview. User can add some item in listview (type in EditText and click on Button "OK"). When user made onItemClick , the app will strike out text and set background green.

But then , when I add one more item,I see that it applies that strike out and background option from previously item.

Can you advise me what I need to do in this situation? How to improve it?

package com.example.boytsov.foodbasketapp;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Boytsov on 23.07.2015.
 */
public class ProductList extends Activity implements View.OnClickListener,AdapterView.OnItemClickListener,AdapterView.OnItemLongClickListener,TextView.OnEditorActionListener {
    EditText myText;

    ListView lvMain;
    ArrayList<String> catnames;
    ArrayAdapter<String> adapter;
    Button button;
    DataBase db;
    final String LOG_TAG = "myLogs";
    @Override

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.productlist);
        db = new DataBase(this);
        myText = (EditText)findViewById(R.id.editText);
        lvMain = (ListView) findViewById(R.id.lvMain);
        button=(Button)findViewById(R.id.button);

        catnames= new ArrayList<String>();
        // создаем адаптер
        adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, catnames);

        // присваиваем адаптер списку
        lvMain.setAdapter(adapter);
        lvMain.setOnItemClickListener(this);
        lvMain.setOnItemLongClickListener(this);
        // Прослушиваем нажатия клавиш
        button.setOnClickListener(this);
        //слушаем edittext
        myText.setOnEditorActionListener(this);



    }

    @Override
    public void onClick(View view) {

        switch (view.getId()){
            case R.id.button : {
                //TextView myText = (TextView) view;
                catnames.add(0, myText.getText().toString());
                adapter.notifyDataSetChanged();

                //myText.setBackgroundColor(Color.TRANSPARENT);
                //myText.setPaintFlags(0);
                Log.d("Insert: ", "Inserting ..");
                db.addProduct(new Product(myText.getText().toString()));

                myText.setText("");
                Log.d("Reading: ", "Reading all contacts..");
                List<Product> products = db.getAllProducts();

                for (Product cn : products) {
                    String log = "Id: "+cn.getID_product()+" ,Name: " + cn.getName_product();
                    // Writing Contacts to log
                    Log.d("Name: ", log);
                }
            }

        break;

            }

    }



    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

        TextView textview= (TextView) view;
        if (textview.getPaintFlags() != 16){
            textview.setPaintFlags(16);
            textview.setBackgroundColor(Color.parseColor("#77dd77"));
            Toast.makeText(this, "Куплено", Toast.LENGTH_SHORT).show();
            adapter.notifyDataSetChanged();
            Log.d(LOG_TAG, "itemClick: position = " + i + ", id = "
                    + l);
         } else {
            textview.setPaintFlags(0);
            textview.setBackgroundColor(Color.TRANSPARENT);
            Toast.makeText(this, "Не куплено", Toast.LENGTH_SHORT).show();
                }
    }

    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
        catnames.remove(position);
        adapter.notifyDataSetChanged();
        Toast.makeText(this, "Удалено", Toast.LENGTH_SHORT).show();

        Log.d(LOG_TAG, "onItemClick: position = " + position + ", id = "
                + id);
        return true;
    }


    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        boolean handled = false;
        if (actionId == EditorInfo.IME_ACTION_SEND) {
            Log.d(LOG_TAG, "onItemClick: position = " + actionId + ", id = "
                    + event);
            handled = true;
        }
        return handled;
    }
}

enter image description here


Solution

  • You apply your changes on the view at position 0. When you add your item you also add it to position 0, hence the entire list is pushed down by 1 and the new item get the already changed view.

    Edited Answer
    Sorry, I was short on time, but now I can address it more thoroughly.

    One important thing you must understand is that the view which shows your data in the list view DOES NOT NECESSARILY correspond with your data.

    If you click on an item in your list and change it's views attributes, it doesn't change the state for the item or object which represents the data, but the view itself.

    For example if you click on item at position 0 it will change the view's background at position 0. Then, in your example, you add an item at the top of the list, which puts the newly created object at position 0 (with the already modified view) and pushes THE REST OF THE ALREADY CREATED DATA by one, And you end up with an already changed view at position 0 with new data at position 0.

    What you should do is as follows:
    1)Make sure your object has a boolean member which states if item is "strike out" or not. like for example mIsStrikeOut.
    2)create a custom adapter from any android adapter, like from ArrayAdapter.
    3)Override it's getView method, for example:

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View view = convertView;
    
        if (view == null)
        {
          view = (LinearLayout) inflater.inflate(R.layout. simple_list_item_1, parent, false);
        }
    
        TextView textview = (TextView) view.findViewById(R.id.text1);
    
        if (catnames.get(position).isStrikeOut())
        {
            textview.setPaintFlags(16);
            textview.setBackgroundColor(Color.parseColor("#77dd77"));
            Toast.makeText(this, "Куплено", Toast.LENGTH_SHORT).show();
            Log.d(LOG_TAG, "itemClick: position = " + i + ", id = "
                    + l);
        }
        else
        {
            textview.setPaintFlags(0);
            textview.setBackgroundColor(Color.TRANSPARENT);
            Toast.makeText(this, "Не куплено", Toast.LENGTH_SHORT).show();
        }
     return view;
    

    }

    Side note: When you query your data from your DB make sure the order is correct, I would suggest ORDER BY id dec or something like that.