Java 所选列表项背景色在平板电脑上滚动列表后意外重复使用

Java 所选列表项背景色在平板电脑上滚动列表后意外重复使用,java,android,xml,android-5.0-lollipop,android-selector,Java,Android,Xml,Android 5.0 Lollipop,Android Selector,对于我在平板电脑上的列表视图,我试图让我选择的列表项在被选择时保持其状态,但不幸的是,我看到了一些奇怪的行为。出于某种原因,每当我在列表中滚动到所选项目不可见的点,然后滚动回所选项目可见的点时,背景色意外地被重复使用。我相信getView方法中需要做一些事情,但我不确定该如何处理这个方法。为了防止背景色被重复使用,必须采取什么措施 适配器类 public class VictoriaListAdapter extends BaseAdapter { private List<Vi

对于我在平板电脑上的列表视图,我试图让我选择的列表项在被选择时保持其状态,但不幸的是,我看到了一些奇怪的行为。出于某种原因,每当我在列表中滚动到所选项目不可见的点,然后滚动回所选项目可见的点时,背景色意外地被重复使用。我相信getView方法中需要做一些事情,但我不确定该如何处理这个方法。为了防止背景色被重复使用,必须采取什么措施

适配器类

public class VictoriaListAdapter extends BaseAdapter {

    private List<Victoria> mData;
    private LayoutInflater mInflater;

    public VictoriaListAdapter (List<Victoria> data, Context context) {
        mData = data;
        mData = new ArrayList(mData);
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

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

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.list_item_dualline, parent, false);
            holder = new ViewHolder();

            holder.title = (TextView) convertView.findViewById(R.id.item_station);
            holder.description = (TextView) convertView.findViewById(R.id.item_zone);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.title.setText(mData.get(position).getStation());
        holder.description.setText(mData.get(position).getZone());

        return convertView;
    }

    /**
     * View holder
     */
    static class ViewHolder {
        private TextView title;
        private TextView description;
    }
}
public class FragmentVictoriaLine extends ListFragment {

    private VictoriaListAdapter mAdapter;

    public FragmentVictoriaLine() {
    }

    /**
     * Whether or not the activity is in two-pane mode, i.e. running on a tablet
     * device.
     */
    public boolean mTwoPane;

    public static FragmentVictoriaLine newInstance() {
        return new FragmentVictoriaLine();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_victoria_line, container, false);
        initialize();
        return view;
    }

    List<Victoria> list = new ArrayList<>();
    private void initialize() {
        String[] items = getActivity().getResources().getStringArray(R.array.victoria_stations);
        String[] itemDescriptions = getActivity().getResources().getStringArray(R.array.victoria_zones);
        for (int n = 0; n < items.length; n++){
            Victoria victoria = new Victoria();
            victoria.setID();
            victoria.setStation(items[n]);
            victoria.setZone(itemDescriptions[n]);
            list.add(victoria);
        }

        mAdapter = new VictoriaListAdapter(list, getActivity());
        setListAdapter(mAdapter);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        View v = getView();

        mTwoPane = getActivity().findViewById(R.id.detail_container) != null;

        assert v != null;
        ListView lv = (ListView)v.findViewById(android.R.id.list);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            private Victoria selectedMain;
            private View selectedView;

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                VictoriaListAdapter adapter = (VictoriaListAdapter) parent.getAdapter();
                String station = adapter.getItem(position);

                if (mTwoPane) {
                    setItemNormal();
                    View rowView = view;
                    setItemSelected(rowView);

                    Fragment newFragment;
                    if (station.equals(view.getResources().getString(R.string.bho))) {
                        newFragment = new FragmentVictoriaBHO();
                    } else if (station.equals(view.getResources().getString(R.string.brx))) {
                        newFragment = new FragmentVictoriaBRX();
                    } else if (station.equals(view.getResources().getString(R.string.eus))) {
                        newFragment = new FragmentVictoriaEUS();
                    } else if (station.equals(view.getResources().getString(R.string.fpk))) {
                        newFragment = new FragmentVictoriaFPK();
                    } else if (station.equals(view.getResources().getString(R.string.green_park))) {
                        newFragment = new FragmentVictoriaGreenPark();
                    } else if (station.equals(view.getResources().getString(R.string.hhy))) {
                        newFragment = new FragmentVictoriaHHY();
                    } else if (station.equals(view.getResources().getString(R.string.kxsp))) {
                        newFragment = new FragmentVictoriaKXSP();
                    } else {
                        newFragment = new FragmentVictoriaBHO();
                    }
                    VictoriaLineActivity activity = (VictoriaLineActivity) view.getContext();
                    FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
                    transaction.setCustomAnimations(R.anim.fade_out, R.anim.fade_in);
                    transaction.replace(R.id.detail_container, newFragment);
                    transaction.commit();
                } else {
                    Intent intent;
                    if (station.equals(view.getResources().getString(R.string.bho))) {
                        intent = new Intent(getActivity(), VictoriaBHOActivity.class);
                    } else if (station.equals(view.getResources().getString(R.string.brx))) {
                        intent = new Intent(getActivity(), VictoriaBRXActivity.class);
                    } else if (station.equals(view.getResources().getString(R.string.eus))) {
                        intent = new Intent(getActivity(), VictoriaEUSActivity.class);
                    } else if (station.equals(view.getResources().getString(R.string.fpk))) {
                        intent = new Intent(getActivity(), VictoriaFPKActivity.class);
                    } else if (station.equals(view.getResources().getString(R.string.green_park))) {
                        intent = new Intent(getActivity(), VictoriaGreenParkActivity.class);
                    } else if (station.equals(view.getResources().getString(R.string.hhy))) {
                        intent = new Intent(getActivity(), VictoriaHHYActivity.class);
                    } else if (station.equals(view.getResources().getString(R.string.kxsp))) {
                        intent = new Intent(getActivity(), VictoriaKXSPActivity.class);
                    } else {
                        intent = new Intent(getActivity(), VictoriaBHOActivity.class);
                    }
                    startActivity(intent);
                }
            }

            public void setItemSelected(View view) {
                View rowView = view;
                view.setBackgroundColor(Color.parseColor("#868F98"));

                TextView tv0 = (TextView) rowView.findViewById(R.id.item_station);
                tv0.setTextColor(Color.WHITE);

                TextView tv1 = (TextView) rowView.findViewById(R.id.item_zone);
                tv1.setTextColor(Color.WHITE);
            }

            public void setItemNormal() {
                for (int i = 0; i < getListView().getChildCount(); i++) {
                    View v = getListView().getChildAt(i);
                    v.setBackgroundColor(Color.TRANSPARENT);

                    TextView tv0 = ((TextView) v.findViewById(R.id.item_station));
                    tv0.setTextColor(Color.WHITE);

                    TextView tv1 = ((TextView) v.findViewById(R.id.item_zone));
                    tv1.setTextColor(Color.parseColor("#B5B5B5"));
                }
            }
        });

        super.onActivityCreated(savedInstanceState);
    }
}
public class Victoria {
    public Victoria(){}

    private String station;
    private String zone;
    private boolean selected;

    public String getStation(){
        return station;
    }

    public void setStation(String item){
        this.station = item;
    }

    public String getZone(){
        return zone;
    }

    public void setZone(String zone){
        this.zone = zone;
    }

    private int _id;
    public void getID(int _id){
        this._id = _id;
    }

    public int setID(){
        return _id;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }
}

当您在列表中滚动时,
ListView
中的项目/视图将被重新使用以优化内存。因此,当您将选定状态设置为列表项时,您将在滚动时在多个列表项中看到该选定状态。防止这种情况发生的最佳方法是在数据模型中保留状态,并在
适配器的
getView
功能中设置状态

以下是你能做的-

 @Override
 public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
   VictoriaListAdapter adapter = (VictoriaListAdapter) parent.getAdapter();

   //reverse the selected state in data model
   for (int i = 0; i < adapter.getCount(); i++) {
     Victoria victoria = (Victoria)adapter.getItem(i);
     victoria.setSelected(i == position ? true : false);
   }
   Victoria victoria = (Victoria)adapter.getItem(position);

   ---
   ---

希望有帮助

这很简单,因为您使用的是ViewHolder模式,所以ViewHolder模式是一种设计器,它可以重用现有的行结构,而无需创建新的行结构。您必须自己显式设置所选行的颜色
获取红色下划线并返回此错误:
必需:com.packagename.data.Found:java.lang.Object
。在适配器中
adapter
In
Victoria=adapter.getItem(位置)
获取红色下划线,并返回此错误:
无法解析符号“适配器”
。您的解决方案不起作用,因为所选状态仍在重复使用中;编辑了答案。(
onItemClick
函数)错误现在出现
无法解析符号“victoria”
。顺便说一句,您应该比较站点,比如
victoria.getStation().equals(view.getResources().getString(R.string.bho))
等等
@Override
public Object getItem(int position) {
    //Return full object, coz we need to access other 
    //member variables too
    return mData.get(position);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolder holder;

    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.list_item_dualline, parent, false);
        holder = new ViewHolder();

        holder.title = (TextView) convertView.findViewById(R.id.item_station);
        holder.description = (TextView) convertView.findViewById(R.id.item_zone);

        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    Victoria victoria = (Victoria)getItem(position);
    holder.title.setText(victoria.getStation());
    holder.description.setText(victoria.getZone());
    if (victoria.isSelected()) {
        setItemSelected(convertView);
    } else {
        setItemNormal(convertView);
    }

    return convertView;
}

 public void setItemSelected(View view) {
    View rowView = view;
    view.setBackgroundColor(Color.parseColor("#868F98"));

    TextView tv0 = (TextView) rowView.findViewById(R.id.item_station);
    tv0.setTextColor(Color.WHITE);

    TextView tv1 = (TextView) rowView.findViewById(R.id.item_zone);
    tv1.setTextColor(Color.WHITE);
 }

public void setItemNormal(View v) {

    v.setBackgroundColor(Color.TRANSPARENT);

    TextView tv0 = ((TextView) v.findViewById(R.id.item_station));
    tv0.setTextColor(Color.WHITE);

    TextView tv1 = ((TextView) v.findViewById(R.id.item_zone));
    tv1.setTextColor(Color.parseColor("#B5B5B5"));

 }