滚动时ListView的项目发生变化

3

我正在填充一个列表视图,以下是代码:

ArrayAdapter<CharSequence> listAdapter1;
ListView toc;
toc=(ListView)findViewById(R.id.listView1);
listAdapter1=ArrayAdapter.createFromResource(Glossary.this,R.array.arabicalphabet,R.layout.glossarysimplerow);
toc.setAdapter(listAdapter1);

我在xml文件中设置了一个列表选择器,当点击列表中的任何项时,其颜色将变为蓝色以显示已选择。问题是,当我滚动列表视图时,选择将会改变,例如,如果我有一个从A到Z填充的列表,如果我选择字母"B"并多次滚动,则选择将切换到字母"M"......请帮忙解决。


添加适配器代码。您应该使用ViewHolder模式,或确保已定义if(something) - >将颜色更改为蓝色,并且else - >更改回您想要的任何默认颜色。 - Lior Iluz
2
请发布您的完整适配器代码。如果没有,请使用带有viewholder模式的BaseAdapter。 - droidd
我认为这是由于视图的回收造成的,为每个项目状态维护一个布尔值,表示它是否被选中。 - Pramod Yadav
伙计们,没有Java适配器代码,只有我发布的代码。 - Monzer Yaghi
你尝试过使用ArrayAdapter,布局android.R.layout.simple_list_item_multiple_choice并将选择模式设置为多选吗? - Bharatesh
3个回答

2
在Android中,像ListView这样的AdapterView的子项启用了缓存功能,因此当用户滚动时,屏幕上不可见的项目将从内存中移除,getView()方法将被调用以显示滚动后要显示在视图中的项目。
传递给getView()方法的View将被重用,并具有先前在ListView中可见的view的属性。这提高了ListView的性能,但也使得需要检查所有可能的条件并重置在getView()中接收到的视图的所有属性。
现在,您使用的通用ArrayAdapter没有实现按单击更改颜色的功能,也没有任何记录已单击视图的方式。因此,在滚动时会出现意外结果。
您可以按照下面所示的方式实现自己的Adapter类,它将解决您的问题:
public class MyAdapter extends ArrayAdapter<String> {
    Context context;
    List<String> lstStrings;
    List<Boolean> isClicked;

    public MyAdapter (Context context, int resource, List<String> lstStrings) {
        super(context, resource, lstStrings);
        this.context = context;
        lstStrings = lstStrings;
        isClicked = new ArrayList<>(Arrays.asList(new Boolean[lstStrings.length]));
        Collections.fill(isClicked, new Boolean(false));
    }   

    @Override
    public int getCount() {
        return lstStrings.size();
    }

    @Override
    public String getItem(int position) {
        return lstStrings.get(position);
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        if (convertView == null)
            convertView = LayoutInflater.from( context).inflate(R.layout.list_item, null);

        TextView txtTheText = (TextView) convertView.findViewById(R.id.txtTheText);

        txtTheText .setText(lstStrings.get(position));

        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                isClicked.set(!isClicked.get(position));
            }
        });

        if (isClicked.get(position))
            convertView.setBackgroundColor(Color.argb(255, 255, 0, 0));
        else
            convertView.setBackgroundColor(Color.argb(255, 0, 0, 255));

        return convertView;
    }
}

没有什么,只是一个打字错误,已经修复了。 - Kamran Ahmed

1

嗯,我一周前遇到了这个问题,原因是“当你滚动listview时,第一个显示的项目位置为0”,所以你改变视图会影响新项目。

我的解决方案是:

1). 使用ScrollView和内部的LinearLayout代替使用ListView

2). 在LinearLayout中添加数组TextView[]

代码:

布局:

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="2dp"
    android:layout_marginRight="2dp"
    android:layout_marginTop="5dp"
    android:layout_marginBottom="5dp">
    <LinearLayout
        android:id="@+id/ll_inflater"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </LinearLayout>
</ScrollView>

Java:

int prePos = -1;
int sdk = android.os.Build.VERSION.SDK_INT;
LinearLayout ll_inflater = (LinearLayout)findViewById(R.id.ll_inflater);
TextView[] tv_Subs = new TextView[array.size()];//arrary is arrayData
for(int i = 0; i < array.size(); i++){
    tv_Subs[i] = new TextView(getApplication());
    tv_Subs[i].setLines(3);
    tv_Subs[i].setTextColor(getResources().getColor(R.color.sub_color));
    tv_Subs[i].setGravity(Gravity.CENTER);

    if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
        //set default background color
    } else {
        //set default background color
    }

    tv_Subs[i].setText(array.get(i));
    ll_inflater.addView(tv_Subs[i], i, new  ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
    final int finalI = i;
    tv_Subs[i].setOnClickListener( new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(prePos !=-1){
                 //change background of preposition tv_Subs[prePost] to default color
            }
            //change background color here
            prePos = finalI;
        }
    });
}

问题是我必须使用一个列表视图,有没有办法解决? - Monzer Yaghi
我没有其他的解决方案。对此感到抱歉。 - Robust

0

我有一个解决方案。当您单击一个项目时,记录其位置。然后覆盖onConfigurationChanged(Configuration newConfig),并调用ListView.setSelection(position)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接