从Array List中删除项目自定义列表视图始终删除最新项目

时间:2014-10-06 07:25:45

标签: android listview android-listview

我有一个自定义列表视图,包含删除按钮和微调器(微调器包含A-E字符)。 我在从自定义列表视图中删除真行时遇到问题。

自定义列表视图代码:

public class customListView extends BaseAdapter
{
    public Activity context;
    ArrayList<MyActivity.UserProperties> userPropertieses;
    public String[] spinnerValues;
    public LayoutInflater inflater;

    public  customListView(Activity context, ArrayList<MyActivity.UserProperties> userPropertieses, String[] spinnerArray)
    {
        super();
        this.context = context;
        this.userPropertieses = userPropertieses;
        spinnerValues = spinnerArray;
        this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

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

    @Override
    public Object getItem(int i) { return null; }

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

    class ViewHolder
    {
        Button btnRemove;
        Spinner spinner;
    }

    @Override
    public View getView(final int i, View view, ViewGroup viewGroup)
    {
        final ViewHolder holder;
        if (view == null)
        {
            holder = new ViewHolder();
            view = inflater.inflate(R.layout.custom_layout, null);

            holder.spinner = (Spinner) view.findViewById(R.id.spinner);
            holder.btnRemove = (Button) view.findViewById(R.id.bu_Remove);

            // populate spinner
            ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>
                    (view.getContext(), android.R.layout.simple_spinner_item, spinnerValues);
            dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            holder.spinner.setFocusable(true);
            holder.spinner.requestFocus();
            holder.spinner.setAdapter(dataAdapter);

            view.setTag(holder);

            // remove user implementation
            holder.btnRemove.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Log.i("custom list view debug", "i = " + i);  // debug. verify i value is correct
                    ((MyActivity) context).deleteUser(i);
                }
            });

        }
        else
            holder = (ViewHolder) view.getTag();

        return view;
    }
}

我的主要活动代码如下所示:

public class MyActivity extends Activity
{
    ListView listView;
    ArrayList<UserProperties> userProperties = new ArrayList<UserProperties>();
    customListView adapter;
    SensorManager sensorManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

        for (int i = 0; i<5; i++) {
            userProperties.add(new UserProperties());
        }

        listView = (ListView) findViewById(R.id.listView);
        String[] spinnerValues = new String[] {"A", "B", "C", "D", "E"};
        adapter = new customListView(MyActivity.this, userProperties, spinnerValues);
        listView.setAdapter(adapter);
    }

    public void deleteUser (int index)
    {
        Log.i("debug", "Removing item " + index); // the index is really true and the true node deleting from the ArrayList but somehow the latest delete from the UI
        userProperties.remove(index);
        adapter.notifyDataSetChanged();
    }
}

当我点击使用正确索引调用的Remove按钮deleteUser方法时。但是在notiftDataSetChanged之后,以某种方式从userProperties ArrayList删除的正确节点仍处于活动状态 和最新的节点删除。

那么,我怎样才能删除正确的节点/行(来自ArrayList和UI ......)

谢谢!

修改 为了清楚起见,i变量包含真正的索引。从ArrayList中删除的真节点。但在我调用notify方法之后附加了一些东西。 我更愿意留在BaseAdapter而不是ArrayAdapter。谢谢!

编辑2: 经过更多的调试,我发现我的问题是错的。真正删除的行只是微调器值以某种方式更新它们的值。我无法解决这个问题,因为它已经回答了。感谢。

3 个答案:

答案 0 :(得分:1)

((MyActivity) context).deleteUser(i);

此行始终会删除ListView

中的第一个值

您可以使用CAB (contextual action bar)

查看代码是否对您有帮助(它基本上是ListActivity,带有自定义适配器来保存已检查项目的状态(+不同背景)):

public class CABSelection extends ListActivity {

    private ArrayList<String> mItems = new ArrayList<String>();
    private SelectionAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        for (int i = 0; i < 24; i++) {
            mItems.add("Name" + i);
        }
        // R.layout.adapters_cabselection_row is a LinearLayout(with green
        // background(#99cc00)) that wraps an ImageView and a TextView
        mAdapter = new SelectionAdapter(this,
                R.layout.adapters_cabselection_row, R.id.the_text, mItems);
        setListAdapter(mAdapter);
        getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
        getListView().setMultiChoiceModeListener(new MultiChoiceModeListener() {

            private int nr = 0;

            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                MenuInflater inflater = getMenuInflater();
                inflater.inflate(R.menu.cabselection_menu, menu);
                return true;
            }

            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                return false;
            }

            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                StringBuilder sb = new StringBuilder();
                Set<Integer> positions = mAdapter.getCurrentCheckedPosition();
                for (Integer pos : positions) {
                    sb.append(" " + pos + ",");
                }               
                switch (item.getItemId()) {
                case R.id.edit_entry:
                    Toast.makeText(CABSelection.this, "Edited entries: " + sb.toString(),
                            Toast.LENGTH_SHORT).show();
                    break;
                case R.id.delete_entry:
                    Toast.makeText(CABSelection.this, "Deleted entries : " + sb.toString(),
                            Toast.LENGTH_SHORT).show();
                    break;
                case R.id.finish_it:
                    nr = 0;
                    mAdapter.clearSelection();
                    Toast.makeText(CABSelection.this, "Finish the CAB!",
                            Toast.LENGTH_SHORT).show();
                    mode.finish();
                }
                return false;
            }

            @Override
            public void onDestroyActionMode(ActionMode mode) {
                nr = 0;
                mAdapter.clearSelection();
            }

            @Override
            public void onItemCheckedStateChanged(ActionMode mode,
                    int position, long id, boolean checked) {
                if (checked) {
                    nr++;
                    mAdapter.setNewSelection(position, checked);                    
                } else {
                    nr--;
                    mAdapter.removeSelection(position);                 
                }
                mode.setTitle(nr + " rows selected!");

            }

        });
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        l.setItemChecked(position, !mAdapter.isPositionChecked(position));
    }

    private class SelectionAdapter extends ArrayAdapter<String> {

        private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>();

        public SelectionAdapter(Context context, int resource,
                int textViewResourceId, List<String> objects) {
            super(context, resource, textViewResourceId, objects);
        }

        public void setNewSelection(int position, boolean value) {
            mSelection.put(position, value);
            notifyDataSetChanged();
        }

        public boolean isPositionChecked(int position) {
            Boolean result = mSelection.get(position);
            return result == null ? false : result;
        }

        public Set<Integer> getCurrentCheckedPosition() {
            return mSelection.keySet();
        }

        public void removeSelection(int position) {
            mSelection.remove(position);
            notifyDataSetChanged();
        }

        public void clearSelection() {
            mSelection = new HashMap<Integer, Boolean>();
            notifyDataSetChanged();
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = super.getView(position, convertView, parent);//let the adapter handle setting up the row views
            v.setBackgroundColor(Color.parseColor("#99cc00")); //default color
            if (mSelection.get(position) != null) {
                v.setBackgroundColor(Color.RED);// this is a selected position so make it red
            }
            return v;
        }

    }

}

答案 1 :(得分:0)

另一种方式

adapter = new MyListAdapter(this);
lv = (ListView) findViewById(android.R.id.list);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
    AlertDialog.Builder adb=new AlertDialog.Builder(MyActivity.this);
    adb.setTitle("Delete?");
    adb.setMessage("Are you sure you want to delete " + position);
    final int positionToRemove = position;
    adb.setNegativeButton("Cancel", null);
    adb.setPositiveButton("Ok", new AlertDialog.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            MyDataObject.remove(positionToRemove);
            adapter.notifyDataSetChanged();
        }});
    adb.show();
    }
});

答案 2 :(得分:0)

 getView(final int i,

不要让我最后。你这样做是为了在onClick()中使用i。但这是不可能的。所以删除最后一个。添加:

 holder.btnRemove.setTag(i);

在onClick上:

 int position = v.getTag(); 
 ..deleteUser(position);

也许你必须在某处施展......

备注:您必须始终设置标记。所以在return view;之前就这样做。

请不要使用i作为职位。