机器人:混乱选择在ListView中机器人、混乱、ListView

2023-09-04 23:09:19 作者:几人

在我的应用程序有一个的ListView ArrayAdapter 。当我选择在的ListView某一个元素我可以看到也多几个选择的元素。

此外,当我在滚动的ListView元素(选择后),那么我的选择消失和元素是随机选择的。

code适配器:

最后ListAdapter适配器=新的ArrayAdapter< BinLocationsComponent>(活动,R.layout.simple_list_item_multiple_choice,locationComponents){     @覆盖     公共查看getView(INT位置,查看convertView,ViewGroup中父){         如果(convertView == NULL){             convertView = layoutInflater.inflate(layout.simple_test_layout_with_one_text_field,NULL);         }         返回convertView;     } };

看起来像一些参数进行设置。

能否请你帮我避免这个问题?

UPD1

最后ListAdapter适配器=新的ArrayAdapter< BinLocationsComponent>(活动,R.layout.simple_list_item_multiple_choice,locationComponents){     @覆盖     公共查看getView(INT位置,查看convertView,ViewGroup中父){         最后LocationsViewHolder viewHolder;         如果(convertView == NULL){             convertView = layoutInflater.inflate(layout.rp_bin_locations_block_element,父母,假);             viewHolder =新LocationsViewHolder();             viewHolder.init(convertView);             convertView.setTag(viewHolder);         } 其他 {             viewHolder =(LocationsViewHolder)convertView.getTag();         }         最后BinLocation binLocation = locationComponents.get(位置).getBinLocation();         如果(binLocation!= NULL){             viewHolder.provideValues​​(binLocation);         }         返回convertView;     }     类LocationsViewHolder {         TextView的工作站名称;         TextView的rackName;         TextView的BINNAME;         TextView的量;         NumberPicker numberOfItems;         公共无效的init(查看视图){             工作站名称=(TextView中)view.findViewById(id.ro_station_name);             rackName =(TextView中)view.findViewById(id.ro_rack_name);             BINNAME =(TextView中)view.findViewById(id.ro_bin_name);             体积=(TextView中)view.findViewById(id.ro_volume_value);             numberOfItems =(NumberPicker)view.findViewById(id.ro_number_of_items);         }         公共无效provideValues​​(BinLocation位置){             stationName.setText(location.getStationName());             rackName.setText(location.getRackName());             binName.setText(location.getBinName());             volume.setText(的valueOf(location.getVolume()));         }     } }; 智 信讲堂之 混乱环境中机器人的交互与操控 线上开讲

和simple_list_item_multiple_choice它的Andr​​oid SDK中的文件:

< CheckedTextView的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android     机器人:ID =@机器人:ID / text1中     机器人:layout_width =match_parent     机器人:layout_height =机器人:ATTR /列表preferredItemHeightSmall     机器人:textAppearance =机器人:ATTR / textAppearanceListItemSmall     机器人:重力=center_vertical     机器人:对号=机器人:ATTR / listChoiceIndicatorMultiple     机器人:paddingStart =机器人:ATTR /列表preferredItemPaddingStart     机器人:paddingEnd =机器人:ATTR /列表preferredItemPaddingEnd />

解决方案

哇,它在你的第一面的第一道关卡的ListView 。不要担心。首先了解如何的ListView 的作品,它的重要。否则,你不能掌握的ListView 。用最简单的一句话:的ListView 创建几行查看和利用他们的每一行。所以,如果你有在你的 ListView的50个元素则可能只有10倍 getView()被调用convertView是空值。因此,在短期,如果你没有为每个位置更新视图内状态getView()的方法,这将是一个真正的混乱。另外,请使用View持有人模式在的ListView 。这将大幅增加滚动,将利用更少的资源。更多关于查看持有人模式 http://www.jmanzano.es/blog/?p=166

更新:

我说:

  

因此​​,在短期,如果你不更新视图的状态 getView()方法中的每一个位置,这将是一个真正的混乱。

 私人SparseBooleanArray checkedPositions =新SparseBooleanArray(); //类变量


listView.setOnItemClickListener(新OnItemClickListener(){

        @覆盖
        公共无效onItemClick(适配器视图<>母公司视图中查看,
                INT位置,长的id){
             如果(checkedPositions.get(位置)){
                 checkedPositions.put(位置,假);
             }其他{
                 checkedPositions.put(位置,真正的);
             }
        }

    });
 

现在在你的 getView()

((CheckedTextView)convertView.findViewById(R.id.checkedTextView)).setChecked(checkedPositions.get(position));

根据您的需要调整此code。 或您可以有一个布尔在你的 BinLocation 来维护检查位置的变量。但要记住并理解维持在 getView状态的点()

In my application I have a ListView and ArrayAdapter. When I select some one element in ListView I can see also few more selected elements.

Furthermore, when I scroll elements in ListView (after selection) then my selection disappears and elements are selected randomly.

Code of adapter:

final ListAdapter adapter = new ArrayAdapter<BinLocationsComponent>(activity, R.layout.simple_list_item_multiple_choice, locationComponents) {
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if ( convertView == null ) {
            convertView = layoutInflater.inflate(layout.simple_test_layout_with_one_text_field, null);
        }
        return convertView;
    }
};

Looks like some parameters have to be set.

Could you please help me to avoid this problem?

UPD1

final ListAdapter adapter = new ArrayAdapter<BinLocationsComponent>(activity, R.layout.simple_list_item_multiple_choice, locationComponents) {
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final LocationsViewHolder viewHolder;
        if ( convertView == null ) {
            convertView = layoutInflater.inflate(layout.rp_bin_locations_block_element, parent, false);
            viewHolder = new LocationsViewHolder();
            viewHolder.init(convertView);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (LocationsViewHolder) convertView.getTag();
        }
        final BinLocation binLocation = locationComponents.get(position).getBinLocation();
        if ( binLocation != null ) {
            viewHolder.provideValues(binLocation);
        }
        return convertView;
    }

    class LocationsViewHolder {
        TextView stationName;
        TextView rackName;
        TextView binName;
        TextView volume;
        NumberPicker numberOfItems;

        public void init(View view) {
            stationName = (TextView) view.findViewById(id.ro_station_name);
            rackName = (TextView) view.findViewById(id.ro_rack_name);
            binName = (TextView) view.findViewById(id.ro_bin_name);
            volume = (TextView) view.findViewById(id.ro_volume_value);
            numberOfItems = (NumberPicker) view.findViewById(id.ro_number_of_items);
        }

        public void provideValues(BinLocation location) {
            stationName.setText(location.getStationName());
            rackName.setText(location.getRackName());
            binName.setText(location.getBinName());
            volume.setText(valueOf(location.getVolume()));
        }

    }
};

and simple_list_item_multiple_choice it's android sdk's file:

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="?android:attr/listPreferredItemHeightSmall"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:gravity="center_vertical"
    android:checkMark="?android:attr/listChoiceIndicatorMultiple"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
/>

解决方案

Wow, its the first hurdle you face in your first ListView. Don't worry. First of all understand how ListView works, its important. Otherwise you can't master ListView. In simplest word: ListView creates few row Views and utilizes them for every row. So if you have have 50 elements in your ListView then may be only 10 times getView() was called with convertView being null. So in short if you don't update the state of a view inside getView() method for every position, it will really be a chaos. Also please use View Holder Pattern in your ListView. It will drastically increase scrolling and will utilize less resources. More on View Holder Pattern http://www.jmanzano.es/blog/?p=166

UPDATE:

I said

So in short if you don't update the state of a view inside getView() method for every position, it will really be a chaos.

 private SparseBooleanArray checkedPositions = new SparseBooleanArray();// class variable


listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
             if(checkedPositions.get(position)){
                 checkedPositions.put(position, false);
             }else{
                 checkedPositions.put(position, true);
             }
        }

    });

now in your getView()

((CheckedTextView)convertView.findViewById(R.id.checkedTextView)).setChecked(checkedPositions.get(position));

adjust this code according to your need. OR you can have a boolean variable in your BinLocation to maintain checked positions. But remember and understand the point of maintaining state inside getView().

 
精彩推荐