简体   繁体   English

片段ListView奇怪的行为

[英]Fragment ListView strange behavior

I have ListView at my fragment where I try to select some items by LongClick. 我的片段中有ListView,在这里我尝试通过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 ). 在我的屏幕上,我可以看到8个项目(在另一个智能手机上,我可以看到6个项目。)当ListView中有很多项目(例如23)并且我对第一个项目进行LongClick时,看到的图像已更改,但是如果我向下滚动,可以看到10和19个项目也改变了图像(就像它们已被选中一样)。 At the another smartphone after LongClick the first item I see change 8 and 16 too and etc). 在LongClick之后的另一部智能手机上,我看到第一个项目也更改了8和16,依此类推。 As you can see I get change ListView items images just after the same numbers of items as can present my smartphone. 如您所见,我得到的更改ListView项目图像紧随可以显示智能手机的项目数量之后。 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) 这是ListView的奇怪行为,它在每个组上复制项目视图的变化图像(组表示ListView项目数是智能手机可以同时显示的项目数的倍数)

Whats wrong in my code or how to avoid this unexpected behavior of ListView? 我的代码有什么问题,或者如何避免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 ---- ---- 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 -- ---- 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>

ListView recycles views, so I was wrong code. ListView回收视图,所以我写错了代码。 My decisions 我的决定

--- at ListFragment --- -在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 !!! 问题的主要原因:我应该更改并重建适配器,但是不要从ListView中更改项目! Don't use access to ListView items by ListView for changing them. 不要使用ListView对ListView项目的访问权限来更改它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM