从数组列表联系人中删除项目到自定义列表视图,始终删除最新的项目

问题描述 投票:0回答:3

我有一个自定义列表视图,包含删除按钮和微调器(微调器包含 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: 经过更多调试后我发现我的问题是错误的。真正删除的行只是微调器值以某种方式更新它们的值。我无法关闭问题,因为它已经回答了。

android listview android-listview
3个回答
1
投票
((MyActivity) context).deleteUser(i);

此行将始终删除

ListView

中的第一个值

您可以使用CAB(上下文操作栏)

看看代码是否对您有帮助(它基本上是一个带有自定义适配器的

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;
        }

    }

}

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();
    }
});

0
投票
 getView(final int i,

不要将 i 定为最终的。您这样做是为了在 onClick() 中使用 i 。但这是不可能的。所以去掉最后一个。添加:

 holder.btnRemove.setTag(i);

并在 onClick 中:

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

也许你必须在某个地方投射一些东西..

备注:您必须始终设置标签。所以就在

return view;
之前做吧。

请勿使用 i 表示位置。

© www.soinside.com 2019 - 2024. All rights reserved.