View.gettag返回null,我在ListView / ArrayAdapter设置中错过了什么?

时间:2014-03-27 01:46:16

标签: java android listview adapter

我有一个自定义类“Something”,它包含一些整数和字符串。我正在创建一个页面,允许用户查看每个当前的Something的描述,以及一个用于编辑或删除每个内容的按钮。

我已经在Something类中重写了toString(),因此它可以返回要放入TextView字段的描述。

list_task_edit.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin" 
android:orientation="vertical"
tools:context=".EditTaskList">
    ...
    <ListView 
android:id="@+id/edit_task_listview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>

    ...
</LinearLayout>

edit_task_list_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >

    <TextView
    android:id="@+id/edit_task_name"
    android:layout_weight="1"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    />

    <Button
    android:id="@+id/edit_task_edit"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/button_edittask"
    android:onClick=""
    />

    <Button
    android:id="@+id/edit_task_delete"
    android:layout_width="wrap_content"
    android:text="@string/button_delete_task"
    android:layout_height="wrap_content"
    android:onClick="deleteTask"
    />

</LinearLayout>

(我还没有为editTask设置方法,因为我不在那里)

public class EditTaskList extends Activity {

private static ArrayList<Something> list;

ArrayAdapter<Something> arrayAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.list_task_edit);
    list = MainActivity.getMasterList();

    arrayAdapter = new ArrayAdapter<Something>
    (this,
            R.layout.edit_task_list_item,
            R.id.edit_task_name,
            list);
    ListView listView = (ListView)findViewById(R.id.edit_task_listview);
    listView.setAdapter(arrayAdapter);
}

public void deleteTask(View view){
    Something thisItem = (Something)view.getTag();
    if(thisItem == null){
        System.out.println("Bad things");
    }
    arrayAdapter.remove(thisItem);
    arrayAdapter.notifyDataSetChanged();
}
    ...
}

我的诊断行检查thisItem == null是否每次都关闭。我错过了什么?我是否以某种方式声明ArrayAdapter错误?

2 个答案:

答案 0 :(得分:4)

更新后的工作代码。如果它对其他人有用:

public class EditTaskList extends Activity {

    private static ArrayList<Something> list;
private CustomAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_task_edit);
        ListView listView = (ListView)findViewById(R.id.edit_task_listview);
        list = MainActivity.getMasterList();
        adapter = new CustomAdapter(this, list);
        listView.setAdapter(adapter);
    }

    public void resetAdapter(){
        adapter.notifyDataSetChanged();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.edit_task_list, menu);
        return true;
    }

    public class CustomAdapter extends ArrayAdapter<Something>{
        private ArrayList<Something> things;
        private LayoutInflater inflater;

        class ViewHolder {
            public TextView text;
            public Button editButton;
            public Button deleteButton;
        }

        public CustomAdapter(Context context, ArrayList<Something> things) {
            super(context, R.layout.edit_task_list_item, things);
            inflater = LayoutInflater.from(context);
            this.things = things;
        }

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

            // reuse views
            ViewHolder viewHolder;
            if (convertView == null) {
                viewHolder = new ViewHolder();
                convertView = inflater.inflate(R.layout.edit_task_list_item, null);
                // configure view holder
                viewHolder.text = (TextView) convertView.findViewById(R.id.edit_task_name);
                viewHolder.editButton = (Button) convertView.findViewById(R.id.edit_task_edit);
                viewHolder.deleteButton = (Button) convertView.findViewById(R.id.edit_task_delete);
                convertView.setTag(viewHolder);
            }

            else {
                viewHolder = (ViewHolder) convertView.getTag();
            }

            viewHolder.text.setTag(position);
            viewHolder.text.setText(things.get(position).toString());
            viewHolder.deleteButton.setTag(position);
            viewHolder.editButton.setTag(position); //currently does nothing

            viewHolder.deleteButton.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View view) {
                int tag = (Integer)view.getTag();
                things.remove(tag);
                resetAdapter();
                }
            });

            return convertView;
        }
    }
}

答案 1 :(得分:1)

您的deleteTask事件不会返回您的列表项,而是返回按钮视图。

要获得所需的功能,您应该构建一个自定义适配器来跟踪列表项。为此,您需要扩展BaseAdapter。

有关详细信息,请参阅此回复:

How to add/remove item from listview in android when click button in item listview

关键是在GetView方法中,您可以在列表按钮上设置一个标记,表示容器项的位置。然后,这将允许您删除按钮的OnClickListener中该位置指定的项目。