【问题标题】:Can not interact correctly with buttons on custom listview layout after scrolling滚动后无法与自定义列表视图布局上的按钮正确交互
【发布时间】:2013-12-04 23:33:02
【问题描述】:

我有一个列表,每行显示多个项目。 两个按钮和四个文本视图。

我正在使用 ArrayAdapter 来整合我的自定义布局并填写每一行中的数据。

所有想要的条目都会显示出来,我可以与按钮进行交互。 (每个按钮都会改变其所在行的文本视图。)

一切正常,直到我再次向下和向上滚动。比什么都不起作用了。 所有项目仍然存在,但通过单击按钮,文本不再更改。

(我将所有创建的 TextViews 保存在 Vector 中,因为使用 getView 方法中的 position 属性,我得到了我在列表中单击的项目的位置,因此我可以从向量中选择特定的项目。它工作得很好,直到我写了,我滚动了列表)

这是我的 ArrayAdapter 的代码

public class LocationlistAdapter extends ArrayAdapter<Location> {

// GUI elements
private Button btnCheckin;
private Button btnExit;
private Vector<TextView> locationList = new Vector<TextView>();
private Vector<TextView> checkInList = new Vector<TextView>();
private Vector<TextView> checkOutList = new Vector<TextView>();
private Vector<TextView> lastVisitList = new Vector<TextView>();

private boolean checkedIn = false;
private int activeListPosition = -1; // selected ListView item

private static LocationTrackingDB mDBHandler;

public LocationlistAdapter(Context context, List<Location> locations) {
    super(context, R.layout.locationlistrow, locations);

    mDBHandler = LocationTrackingDB.getInstance(getContext());
}

@Override
public View getView(final int position, View view, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) parent.getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v = inflater.inflate(R.layout.locationlistrow, null);

    if (position % 2 == 0) {
        RelativeLayout layout = (RelativeLayout) v
                .findViewById(R.id.rowLayout);
        layout.setBackgroundColor(Color.DKGRAY);
    } else {
        RelativeLayout layout = (RelativeLayout) v
                .findViewById(R.id.rowLayout);
        layout.setBackgroundColor(Color.BLACK);
    }

    TextView txtLocationName = (TextView) v
            .findViewById(R.id.txtLocationName);
    TextView txtStartTime = (TextView) v.findViewById(R.id.txtStartTime);
    TextView txtEndTime = (TextView) v.findViewById(R.id.txtEndTime);
    TextView txtLastDate = (TextView) v.findViewById(R.id.txtLastDate);

    if (locationList.size() < mDBHandler.getAllLocations().size()) {
        locationList.add(txtLocationName);
        checkInList.add(txtStartTime);
        checkOutList.add(txtEndTime);
        lastVisitList.add(txtLastDate);
    }

    txtLocationName.setText(mDBHandler.getLocation(position + 1).getName());
    txtStartTime.setText(mDBHandler.getLocation(position + 1)
            .getStartTime());
    txtEndTime.setText(mDBHandler.getLocation(position + 1).getEndTime());
    txtLastDate
            .setText(mDBHandler.getLocation(position + 1).getLastVisit());

    btnCheckin = (Button) v.findViewById(R.id.btnCheckIn);
    btnExit = (Button) v.findViewById(R.id.btnExit);

    btnCheckin.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            if (!checkedIn && activeListPosition == -1) {
                checkedIn = true;
                activeListPosition = position;

                Location tmpLocation = mDBHandler.getLocation(position + 1);

                SimpleDateFormat time = new SimpleDateFormat("HH:mm:ss");
                SimpleDateFormat date = new SimpleDateFormat("dd/MM/yyyy");
                Date currentTime = new Date();
                checkInList.elementAt(position).setText(
                        time.format(currentTime));
                lastVisitList.elementAt(position).setText(
                        date.format(currentTime));
                checkOutList.elementAt(position).setText("waiting ...");

                tmpLocation.setStartTime(time.format(currentTime));
                tmpLocation.setLastVisit(date.format(currentTime));

                mDBHandler.updateLocation(tmpLocation);
            }
        }
    });

    btnExit.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            if (checkedIn && activeListPosition == position) {
                Location tmpLocation = mDBHandler.getLocation(position + 1);

                checkedIn = false;
                activeListPosition = -1;

                SimpleDateFormat time = new SimpleDateFormat("HH:mm:ss");
                SimpleDateFormat date = new SimpleDateFormat("dd/MM/yyyy");
                Date currentTime = new Date();
                checkOutList.elementAt(position).setText(
                        time.format(currentTime));

                tmpLocation.setEndTime(time.format(currentTime));
                tmpLocation.setLastVisit(date.format(currentTime));

                mDBHandler.updateLocation(tmpLocation);
            }
        }
    });
    return v;
    }
}

有人知道为什么会这样吗?或者我怎样才能以更好的方式做到这一点?

【问题讨论】:

    标签: android listview android-listview android-arrayadapter


    【解决方案1】:

    尝试使用 getView 函数参数中的 convertView(在您的情况下为视图),例如:

    @Override
    public View getView(final int position, View view, ViewGroup parent) {
    View v=view;
    if(v==null){
        LayoutInflater inflater = (LayoutInflater) parent.getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         v = inflater.inflate(R.layout.locationlistrow, null);
    }
    
    ...
    ...
    }
    

    也尝试使用这个适配器代码:

    public class LocationlistAdapter extends ArrayAdapter<Location> {
    
        // GUI elements
        private Button btnCheckin;
        private Button btnExit;
    
        private boolean checkedIn = false;
        private int activeListPosition = -1; // selected ListView item
    
        private static LocationTrackingDB mDBHandler;
    
        public LocationlistAdapter(Context context, List<Location> locations) {
            super(context, R.layout.locationlistrow, locations);
    
            mDBHandler = LocationTrackingDB.getInstance(getContext());
        }
    
        @Override
        public View getView(final int position, View view, ViewGroup parent) {
            View v = view;
            if (v == null) {
                LayoutInflater inflater = (LayoutInflater) parent.getContext()
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = inflater.inflate(R.layout.locationlistrow, null);
            }
            if (position % 2 == 0) {
                RelativeLayout layout = (RelativeLayout) v
                        .findViewById(R.id.rowLayout);
                layout.setBackgroundColor(Color.DKGRAY);
            } else {
                RelativeLayout layout = (RelativeLayout) v
                        .findViewById(R.id.rowLayout);
                layout.setBackgroundColor(Color.BLACK);
            }
    
            final TextView txtLocationName = (TextView) v
                    .findViewById(R.id.txtLocationName);
            final TextView txtStartTime = (TextView) v
                    .findViewById(R.id.txtStartTime);
            final TextView txtEndTime = (TextView) v.findViewById(R.id.txtEndTime);
            final TextView txtLastDate = (TextView) v
                    .findViewById(R.id.txtLastDate);
    
            txtLocationName.setText(mDBHandler.getLocation(position + 1).getName());
            txtStartTime.setText(mDBHandler.getLocation(position + 1)
                    .getStartTime());
            txtEndTime.setText(mDBHandler.getLocation(position + 1).getEndTime());
            txtLastDate
                    .setText(mDBHandler.getLocation(position + 1).getLastVisit());
    
            btnCheckin = (Button) v.findViewById(R.id.btnCheckIn);
            btnExit = (Button) v.findViewById(R.id.btnExit);
    
            btnCheckin.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    if (!checkedIn && activeListPosition == -1) {
                        checkedIn = true;
                        activeListPosition = position;
    
                        Location tmpLocation = mDBHandler.getLocation(position + 1);
    
                        SimpleDateFormat time = new SimpleDateFormat("HH:mm:ss");
                        SimpleDateFormat date = new SimpleDateFormat("dd/MM/yyyy");
                        Date currentTime = new Date();
                        txtLocationName.setText(time.format(currentTime));
                        txtLastDate.setText(date.format(currentTime));
                        txtEndTime.setText("waiting ...");
    
                        tmpLocation.setStartTime(time.format(currentTime));
                        tmpLocation.setLastVisit(date.format(currentTime));
    
                        mDBHandler.updateLocation(tmpLocation);
                    }
                }
            });
    
            btnExit.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    if (checkedIn && activeListPosition == position) {
                        Location tmpLocation = mDBHandler.getLocation(position + 1);
    
                        checkedIn = false;
                        activeListPosition = -1;
    
                        SimpleDateFormat time = new SimpleDateFormat("HH:mm:ss");
                        SimpleDateFormat date = new SimpleDateFormat("dd/MM/yyyy");
                        Date currentTime = new Date();
                        txtEndTime.setText(time.format(currentTime));
    
                        tmpLocation.setEndTime(time.format(currentTime));
                        tmpLocation.setLastVisit(date.format(currentTime));
    
                        mDBHandler.updateLocation(tmpLocation);
                    }
                }
            });
            return v;
        }
    }
    

    【讨论】:

    • 就是这样...如此简单且完全合乎逻辑...现在我问自己,为什么我开始使用这些向量...非常感谢:)
    猜你喜欢
    • 2011-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多