0

I have ListView at my fragment where I try to select some items by LongClick. At my screen I can see 8 items ( on another smartphone I can see 6 items.) When I have a lot items in my ListView ( for example 23) and I LongClick on a first item as a result I see changed image, but if I scroll down I can see that 10 and 19 items has changed image too ( like they has been checked ). At the another smartphone after LongClick the first item I see change 8 and 16 too and etc). As you can see I get change ListView items images just after the same numbers of items as can present my smartphone. The real status of "additional" items not changed, only their image view. It's the strange behavior of ListView, which duplicate changing image of items view at each group ( group means the number ListView items a multiple the number of items which the smartphone can display simultaneously)

Whats wrong in my code or how to avoid this unexpected behavior of ListView? Thanx

import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;

import ru.someCode.R;

public class ListItems extends ListFragment {

    private ListView lv;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_list, null);
        lv = getListView();

        return  rootView;
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {

        super.onListItemClick(l, v, position, id);
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> adapter, View view,
                                           int position, long id) {

                Log.d("MY", "Checked");

                ImageView imageView = ((ImageView) view.findViewById(R.id.operImg));
                ImageView imageViewCheck = ((ImageView) view.findViewById(R.id.operImgCheck));

                if (lv.isItemChecked(position)) {

                    lv.setItemChecked(position, false);
                    imageView.setVisibility(View.VISIBLE);
                    imageViewCheck.setVisibility(View.GONE);


                } else {

                    lv.setItemChecked(position, true);
                    imageView.setVisibility(View.INVISIBLE);
                    imageViewCheck.setVisibility(View.VISIBLE);

                }
                return true;
            }
        });
    }
}

---- fragment_list.xml ----

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="6dp">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/listContainer">

            <ListView
                android:id="@android:id/list"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:dividerHeight="1dip"
                android:divider="@color/listDev"
                android:footerDividersEnabled="true"/>

            <TextView
                android:id="@id/android:empty"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:textSize="16sp"
                android:gravity="center" />

        </FrameLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/progressContainer"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:visibility="gone">

            <ProgressBar style="?android:attr/progressBarStyleLarge"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>

    </RelativeLayout>
</LinearLayout>

---- adapter code part ---

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;

        if (convertView == null) {

            LayoutInflater inflater = (LayoutInflater) mContext
                    .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.history_list_group, null);

            holder = findViewsById(convertView);
            convertView.setTag(holder);

            if (lv == null) {
                lv = (ListView) parent;
            }


        } else {

            holder = (ViewHolder) convertView.getTag();
        }

        SetDataView(holder, position);

        return convertView;
    }

---- history_list_group.xml --

 <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/circle"
            android:id="@+id/operImgLayout"
            android:layout_gravity="center_vertical"
            android:layout_margin="6dp">

            <ru.phone4pay.phone4pay.extlib.MLRoundedImageView
                android:id="@+id/operImg"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:src="@drawable/ic_action_1"/>

            <ImageView
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:id="@+id/operImgCheck"
                android:src="@drawable/ic_action_tick"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:visibility="gone"/>

        </RelativeLayout>

</LinearLayout>
koa73
  • 861
  • 2
  • 10
  • 27
  • Seems your getView is not properly coded. – Khizar Hayat Mar 21 '16 at 12:57
  • Show complete adapter code and setDataView code – Khizar Hayat Mar 21 '16 at 12:59
  • No need to downvote this question. @user5546244 You got issue with maintaining position you can check similar question and that will help also like http://stackoverflow.com/questions/11190390/checking-a-checkbox-in-listview-makes-other-random-checkboxes-checked-too .. Check given link and try and understand answer and match it with your code, if you found that you had same issue than, solve using that and delete your own question after successfully solving yours – MKJParekh Mar 21 '16 at 13:01
  • has added code of adapter – koa73 Mar 21 '16 at 13:03
  • what is the logic of this code if (lv == null) { lv = (ListView) parent; } – Khizar Hayat Mar 21 '16 at 13:08
  • see public void uncheckAllItems() { – koa73 Mar 21 '16 at 13:11
  • you need to keep track of which items in the data list has been selected (log-clicked), add a boolean selected to `Operation` class, and update this value of selected item when selected, chose which image to show (selected or not) based on this boolean flag – Yazan Mar 21 '16 at 13:20
  • @Yazan Ok I see I will think how to do it Thanx – koa73 Mar 21 '16 at 13:26

1 Answers1

0

ListView recycles views, so I was wrong code. My decisions

--- at ListFragment ---

private ListView lv;    
getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

                @Override
                public boolean onItemLongClick(AdapterView<?> adapter, View view,
                                               int position, long id) {

                    lv.setItemChecked(position, !lv.isItemChecked(position));
                    mAdapter.setCheckedItems(position, lv.isItemChecked(position));

                    return true;
                }
            });

--- at adapter --

    private boolean [] checkedItems;

      public void setCheckedItems(int position, boolean state){
            checkedItems[position] = state;
            notifyDataSetChanged();
        }

        public void unCheckAllItems(){
            for (int i=0; i<checkedItems.length; i++){
                checkedItems[i] = false;
            }
        }

private void SetDataView(ViewHolder holder, int position){

        if (checkedItems[position]){
            holder.operImgCheck.setVisibility(View.VISIBLE);
            holder.operImg.setVisibility(View.INVISIBLE);
        } else {
            holder.operImgCheck.setVisibility(View.INVISIBLE);
            holder.operImg.setVisibility(View.VISIBLE);
        }
}

Main reason of problem: I should change and rebuild adapter but don't change items from ListView !!! Don't use access to ListView items by ListView for changing them.

koa73
  • 861
  • 2
  • 10
  • 27