每四个列表视图项目都会使用选择器进行标记,而不仅仅是选择一个 android

Every fourth list view item get marked by using selector instead of just the choosen one android

大家好,我现在正在做一个大学项目,遇到了一些我随机发现的问题。实际上,我必须为即将发生的事件创建一个应用程序 (android),用户可以在其中概览所有事件并标记他最喜欢的事件。

我有一个 listview 对象,它显示 List<> 中的所有项目 我想让用户有机会标记他最喜欢的事件,这些事件将出现在一个新的片段中,但我对不断变化的图标有疑问。当您标记列表中的第一项时,它还会另外标记列表中的每第四项。我不知道为什么,如果您能提供帮助,那就太好了! :)

图像视图的选择器

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_selected="true" android:drawable="@drawable/ic_bookmark_black_24dp_copy_3" />

    <item android:state_selected="false" android:drawable="@drawable/ic_bookmark_border_black_24dp_copy_3" />

    <item android:drawable="@drawable/ic_bookmark_black_24dp_copy_3" />
</selector>

适配器包含激活功能改变图标

public class CustomArrayAdapter extends BaseAdapter{

    private List<EventItem> listData;

    private LayoutInflater layoutInflater;

    private Context context;

    static class ViewHolder {
        TextView titleView;
        TextView descriptionView;
        TextView authorView;
        TextView reportedDateView;
        TextView locationView;
        ImageView favorite;
    }

    public CustomArrayAdapter(Context context, List<EventItem> listData) {
        this.context = context;
        this.listData = listData;
        Collections.sort(listData);
    }

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

    @Override
    public Object getItem(int position) {
        return listData.get(position);
    }

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

    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        if (convertView == null) {
            layoutInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.list_event_item, null);
            holder = new ViewHolder();

            holder.titleView = (TextView) convertView.findViewById(R.id.title);
            holder.authorView = (TextView) convertView.findViewById(R.id.author);
            holder.descriptionView = (TextView) convertView.findViewById(R.id.description);
            holder.locationView = (TextView) convertView.findViewById(R.id.location);
            holder.reportedDateView = (TextView) convertView.findViewById(R.id.time);

            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }
            holder.titleView.setText(listData.get(position).getTitle());
            holder.authorView.setText(listData.get(position).getAuthor());
            holder.descriptionView.setText(listData.get(position).getDescription());
            holder.locationView.setText(listData.get(position).getLocation());
            holder.reportedDateView.setText(getTime(position));

        holder.favorite = (ImageView) convertView.findViewById(R.id.bookmark);

        holder.favorite.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(view.isSelected()) {
                System.out.println("Position: ");
                view.setSelected(false);
            }else{
                view.setSelected(true);
            }
        }
    });

        return convertView;
    }

    private String getTime(int position) {

        Date start = listData.get(position).getStartTime();
        Date end = listData.get(position).getEndTime();
        String startTime = start.toString();
        String endTime = end.toString();

        return String.format("%1s%2s%3s", start.toString().substring(11, 19), " - ", end.toString().substring(11, 19));
    }
}

这里是 xml 文件中的我的图像视图,其中所有其他视图都设置了样式

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/description"
    app:layout_constraintBottom_toBottomOf="parent"
    android:layout_marginEnd="8dp"
    android:src="@drawable/bookmark_icon_selector"
    android:tint="@color/colorDhdPrimary"
    android:id="@+id/bookmark"
/>

这里是单独 XML 中的列表视图。

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:id="@+id/list_container">

<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/list_event"
    app:layout_constraintBottom_toBottomOf="@+id/list_container"
    app:layout_constraintLeft_toLeftOf="@+id/list_container"
    app:layout_constraintRight_toRightOf="@+id/list_container"
    app:layout_constraintTop_toTopOf="@+id/list_container"
    />

Android 出于性能目的回收列表项。如果您希望 ListView 平滑滚动,强烈建议重用它们。因此,如果您检查一次并滚动,则其他视图会重用这些视图并进行检查。

因此在 getView 中更改代码如下

holder.favorite = (ImageView) convertView.findViewById(R.id.bookmark);
if(checkCondition){
  holder.favorite.setSelected(true);
}else{
  holder.favorite.setSelected(false);
}
holder.favorite.setOnClickListener(new View.OnClickListener() {
....
....

解决方案可以是多个。一种方法是在 EventItem POJO 中添加一个布尔值。

 class EventItem{
    boolean isSelected;
}

现在切换这个布尔值 onClick

final int pos=position;
        holder.favorite.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                listData.get(pos).isSelected=!listData.get(posi).isSelected;
                notifyDataSetChanged();
            }
        });

并且在 onBindViewHolder 中检查布尔值。

if(listData.get(position).isSelected){
 holder.favorite.setSelected(true);
 }else{
 holder.favorite.setSelected(false);
}

我有同样的问题,回答 Thoriya Prahalad 提供帮助。

在您的适配器中覆盖此方法 class。

@Override
public int getItemViewType(int position) {
    return position;
}