kbu
kbu

Reputation: 389

Android + Custom ListView

Could anybody explain me, how i can fix my problem:

I have custom ListViewenter image description here

Images changes by click on image, all works fine, but - when image (for example item10) was changed and then scroll down and again scroll up - image for item10 loses state (green image changes to red). The same problem with bottom images, which not in visible position on screen.

How i can save image state when works scroll?

Thx!

Upvotes: 0

Views: 209

Answers (2)

kbu
kbu

Reputation: 389

Fix for my problem

lvMain.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int i) {
                Log.d(LOG_TAG, "STATE CHANGED");

                saveImagesState();

            }

            @Override
            public void onScroll(AbsListView absListView, int i, int i2, int i3) {
                Log.d(LOG_TAG,"ONSCROLL");
            }
        });

Upvotes: 0

Marco Acierno
Marco Acierno

Reputation: 14847

Ok, i don't know your code so i can't help you with a "more specific solution" but you can create an array of boolean

boolean[] status;

Every item have an id in the array.

In the getView() method check if status == true put green image, red if false.

It's how you can do it, if you post your code i can help you with a more efficent solution if possible. But it's the basic idea.

Ah, if you use a class to put items in the ListView you can save his state as a field in the class.

And this video helped me a lot to understand how Android works with ListView

Wow, ok your code is a bit messy around and i don't understand why you do somethings.. Anyway save the "yes|no" in the imagetag is not a great idea for me..

You can edit your "Product" class and add a field called "selected" something like:

class Product
{
    public boolean userSelectedIt;
}

Then edit your getView to something like this:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // используем созданные, но не используемые view
    View view = convertView;
    if (view == null) {
        view = lInflater.inflate(R.layout.item, parent, false);
    }

    Product p = getProduct(position);
    final int pos = position;
    final String name = p.name;
    final boolean selected = p.userSelectedIt;

    // заполняем View в пункте списка данными из класса продукт: наименование, картинка и тег(используется для детекта картинки)
    // и картинка
    ((TextView) view.findViewById(R.id.tvDescr)).setText(p.name);
    ((ImageView) view.findViewById(R.id.ivImage)).setImageResource(p.image);
    ((ImageView) view.findViewById(R.id.ivImage)).setTag(p.tag);

    iv = ((ImageView) view.findViewById(R.id.ivImage));

    String temp = (String)iv.getTag();      //Получаю инфу, какая картинка у текущего элемента

    //Блок для определения какую картинку добавить в массив
    if (selected)
        iarr.add(new ImgArray(iv,pos,name,"yes"));
    else
        iarr.add(new ImgArray(iv,pos,name,"no"));

    //Обработчик нажатия на картинку

    iv.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            // Здесь можно писать в базу, в name содержится имя продукта по которому кликнули
            //
            // Log.d(LOG_TAG,"PRODUCT --- " + name);
            Log.d(LOG_TAG, "NAME ACTIVITY --- " + title);

            //Получаю картинку, которая была нажата
            LinearLayout ll = (LinearLayout) view.getParent();
            ImageView iv = (ImageView) ll.getChildAt(0);

            //String bufferTag = (String) iv.getTag();        //Получаю данные, какая картинка была перед нажатием

            //Блок для определения, какая картинка пришла и на какую ее изменить
            selected = !selected;
            if (selected) {
                iv.setImageResource(R.drawable.no);
                iarr.set(pos,new ImgArray(iv,pos,name,"no"));       //Заменяется картинка в массиве картинок. Замена происходит по позиции

            }
            else {
                iv.setImageResource(R.drawable.yes);
                iarr.set(pos,new ImgArray(iv,pos,name,"yes"));
            }
        }
    });

    return view;
}

Or, if you don't want to add a field to Product class you can edit your Adapter to look like this:

public class BoxAdapter extends BaseAdapter {
Context ctx;
LayoutInflater lInflater;
ArrayList<Product> objects;
ArrayList<boolean> userSelected; // Here i added a ArrayList of booleans to remember the user chooise
String title;
public ImageView iv;
public int counter;
public ArrayList<ImgArray> iarr = new ArrayList<ImgArray>();
public ArrayList<ImgArray> startIarr = new ArrayList<ImgArray>();
final String LOG_TAG = "myLogs";


BoxAdapter(Context context, ArrayList<Product> products, String curTitle) {
    ctx = context;
    objects = products;
    lInflater = (LayoutInflater) ctx
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    //Получаю название Activity
    title = curTitle;
}

// кол-во элементов
@Override
public int getCount() {
    return objects.size();
}

// элемент по позиции
@Override
public Object getItem(int position) {
    return objects.get(position);
}

// id по позиции
@Override
public long getItemId(int position) {
    return position;
}

// пункт списка
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // используем созданные, но не используемые view
    View view = convertView;
    if (view == null) {
        view = lInflater.inflate(R.layout.item, parent, false);
    }

    Product p = getProduct(position);
    final int pos = position;
    final String name = p.name;
    final boolean selected = userSelected.get(position);

    // заполняем View в пункте списка данными из класса продукт: наименование, картинка и тег(используется для детекта картинки)
    // и картинка
    ((TextView) view.findViewById(R.id.tvDescr)).setText(p.name);
    ((ImageView) view.findViewById(R.id.ivImage)).setImageResource(p.image);
    ((ImageView) view.findViewById(R.id.ivImage)).setTag(p.tag);

    iv = ((ImageView) view.findViewById(R.id.ivImage));

    //Блок для определения какую картинку добавить в массив
    if (selected)
        iarr.add(new ImgArray(iv,pos,name,"yes"));
    else
        iarr.add(new ImgArray(iv,pos,name,"no"));

    //Обработчик нажатия на картинку

    iv.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            // Здесь можно писать в базу, в name содержится имя продукта по которому кликнули
            //
            // Log.d(LOG_TAG,"PRODUCT --- " + name);
            Log.d(LOG_TAG, "NAME ACTIVITY --- " + title);

            //Получаю картинку, которая была нажата
            LinearLayout ll = (LinearLayout) view.getParent();
            ImageView iv = (ImageView) ll.getChildAt(0);

            //String bufferTag = (String) iv.getTag();        //Получаю данные, какая картинка была перед нажатием

            //Блок для определения, какая картинка пришла и на какую ее изменить
            userSelected.set(position, !selected);
            if (!selected) {
                iv.setImageResource(R.drawable.no);
                iarr.set(pos,new ImgArray(iv,pos,name,"no"));       //Заменяется картинка в массиве картинок. Замена происходит по позиции

            }
            else {
                iv.setImageResource(R.drawable.yes);
                iarr.set(pos,new ImgArray(iv,pos,name,"yes"));
            }

        }
    });

    return view;
}


// товар по позиции
Product getProduct(int position) {
    return ((Product) getItem(position));
}


//Функция для возврата информации о количестве элементов в массиве картинок(не используется)
public Object getV (View v,int position) {
    ListView lv = (ListView) v.findViewById(R.id.lvView);

    //Object o = lv.getItemAtPosition(position);
    Object o = iarr.size();

    return o;
}


//Функция для возврата элемента картинок
public ArrayList iFunc(){
    return iarr;
}

//не используется
public ArrayList sIarr(){
    return startIarr;
}

//не используется
public int C (View v) {
    ListView lv = (ListView) v.findViewById(R.id.lvView);
    return lv.getCount();
}



}

(Yeah i know, the code looks horrible here due to indentation sorry.) This code should work, if not say and i try to fix it.

Upvotes: 2

Related Questions