-2

我开始了一个小的Android项目来重新学习一点Android开发,我已经卡住了......

我不知道如何执行删除我的一个元素ListView

这是项目:https ://github.com/gdurelle/Listify

现在它旨在显示元素列表的列表。

我使用自定义CursorAdapter来显示我的元素列表,并且我已经有一个(丑陋的)销毁按钮,但我不知道如何让它从列表(和数据库)中删除一个实际元素。

我使用ActiveAndroidActiveRecord的方式管理数据库。

另外:我不确定是否使用getView(), bindView(), 和/或newView()...

我创建了一个问题来记住这一点并在此处引用此问题:https ://github.com/gdurelle/Listify/issues/1

public class ListifyCursorAdapter extends CursorAdapter {
  public String content;
  public ListifyCursorAdapter(Context context, Cursor cursor) {
    super(context, cursor, 0);
  }
  // The newView method is used to inflate a new view and return it, you don't bind any data to the view at this point.
  @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
      return LayoutInflater.from(context).inflate(R.layout.element_line, parent, false);
    }
  // The bindView method is used to bind all data to a given view such as setting the text on a TextView.
  @Override
  public void bindView(View view, Context context, Cursor cursor) {
  // Find fields to populate in inflated template
    TextView tvBody = (TextView) view.findViewById(R.id.element_content);
    // Extract properties from cursor
    content = cursor.getString(cursor.getColumnIndexOrThrow("content"));
    // Populate fields with extracted properties
    tvBody.setText(content);
  }
}

在我的 MainActivity 中:

 Cursor cursor = ListifyElement.fetchResultCursor();
 adapter = new ListifyCursorAdapter(this, cursor);
 listView.setAdapter(adapter);

我可能在想一个:

Button delete_button = (Button) listView.findViewById(R.id.delete_button);

类似于ListifyElement.load(ListifyElement.class, the_id_of_the_element).delete();where the_id_of_the_element将是从用户界面中单击它的 delete_button 以某种方式检索的元素的 DB id ...

更新

@Override
public void bindView(View view, Context context, final Cursor cursor) {
    // Find fields to populate in inflated template
    TextView tvBody = (TextView) view.findViewById(R.id.element_content);
    // Extract properties from cursor
    content = cursor.getString(cursor.getColumnIndexOrThrow("content"));
    // Populate fields with extracted properties
    tvBody.setText(content);

    Button delete_button = (Button) view.findViewById(R.id.delete_button);
    delete_button.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            System.out.println(cursor.getColumnName(0)); // Id
            System.out.println(cursor.getColumnName(1)); // ListifyContainer
            System.out.println(cursor.getColumnName(2)); // content
            System.out.println(cursor.getColumnIndexOrThrow("Id")); // 0
            ListifyElement.load(ListifyElement.class, cursor.getColumnIndexOrThrow("Id")).delete();
            notifyDataSetChanged();
        }
    });

单击删除按钮时出现此错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'void com.gdurelle.listify.models.ListifyElement.delete()' on a null object reference
4

5 回答 5

0

让我们从头开始,为什么需要使用 ActiveAndroid?我建议避免这样的事情,恕我直言。你已经混合了你的逻辑,适配器不应该改变你的数据库。为适配器设置一个监听器(即 IDeleteListener 与单一方法 onDeleteRequested(long rowId))。接下来,您需要传递 rowId,例如:

delete_button.setTag(cursor.getLong(0));
delete_button.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            listener.onDeleteRequested((Long)v.getTag());
        }
    });

在您的片段/活动类中,您应该为适配器设置一个侦听器并使用您的数据库。我建议您使用 LoaderManager 这将在删除时自动重新查询您的数据库并处理活动的生命周期。希望有帮助!

于 2015-02-09T16:05:43.500 回答
0

使用下面的代码来执行这个——

ListView lv;
ArrayList<String> arr = new ArrayList<String>();
ArrayAdapter adapter;
int position;

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

    for(int i=0;i<5;i++)arr.add("Hi @ "+i);

    lv = (ListView) findViewById(R.id.listViewBirthday);
    lv.setOnItemLongClickListener(this);
    adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, arr);
    lv.setAdapter(adapter);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
    // TODO Auto-generated method stub
    super.onCreateContextMenu(menu, v, menuInfo);
    MenuItem it1=menu.add("Delete");
}

@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int p, long arg3) 
{
    position = p;
    registerForContextMenu(lv);
    return false;
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    // TODO Auto-generated method stub
    if(item.getTitle().equals("Delete"))
    {
        arr.remove(position);
        adapter.notifyDataSetChanged();
        Toast.makeText(getBaseContext(), "deleted", Toast.LENGTH_SHORT).show();
    }
    return true;
}
于 2015-02-04T10:52:12.403 回答
0

我建议你改用一个ArrayAdapter。然后,您只需使用一个ArrayList(或任何其他数组)并对其进行编辑,然后调用adapter.notifyDataSetChanged();,其内容ListView就会更新。

像这样声明ArrayAdapter

ArrayAdapter<String> adapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, yourStringArray);

其中被调用的变量yourStringArray只是sArrayList中的一个String

然后,将适配器添加到 中ListView,如下所示:

yourListView.setAdapter(adapter);

然后,您可以修改列表的内容,方法是编辑yourStringArray列表并调用adapter.notifyDataSetChanged();. 这是一个简单的例子:

list.add("Hello!");
adapter.notifyDataSetChanged();

最后,要在单击按钮时删除所选项目,您可以执行以下操作:

int selectedItemIndex = 0;

yourArrayList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        selectedItemIndex = position;
     }
});

yourDestroyButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        yourStringArray.remove(selectedItemIndex);
        adapter.notifyDataSetChanged();
    }
});

整个onCreate方法看起来像这样:

// Called when the activity is created
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ArrayList<String> yourStringArray = new ArrayList<>();

    ArrayAdapter<String> adapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, yourStringArray);

    int selectedItemIndex = 0;

    ListView yourListView = (ListView) findViewById(R.layout.yourListViewID);
    yourListView.setAdapter(adapter);
    yourListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectedItemIndex = position;
        }
    });

    yourDestroyButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            yourStringArray.remove(selectedItemIndex);
            adapter.notifyDataSetChanged();
        }
    });
}
于 2015-02-09T16:16:56.890 回答
0

如果你想Button在每一行中添加一个,你应该将它添加到你xmlnewView(). 之后,您应该设置OnClickListener到您的Button内部bindView()。像这样的东西:

public void bindView(View view, Context context, Cursor cursor) {
 // Find fields to populate in inflated template
TextView tvBody = (TextView) view.findViewById(R.id.element_content);
Button delete_button = (Button) view.findViewById(R.id.delete_button);
delete_button.setOnClickListener(new OnClickListener(){
     @Override
     public void onClick(View v){
       //As you're using ActiveAndroid
       new Delete().from(ListfyElement.class).where("yourCondition=?",yourCondition).execute();
       notifyDataSetChanged();

     } 
});
// Extract properties from cursor
content = cursor.getString(cursor.getColumnIndexOrThrow("content"));
// Populate fields with extracted properties
tvBody.setText(content);

}

于 2015-02-02T18:51:41.203 回答
0

在列表视图上实现上下文菜单相对简单。它(上下文菜单)在长按该项目时被激活。我的提示是向菜单项添加一个意图,这样您就可以从您的自定义适配器中保留项目 id 并使用它来执行您想要的任何操作。

public class MainActionBarTabListFragment extends ListFragment {

@Override
public void onActivityCreated(Bundle savedState) {
    super.onActivityCreated(savedState);
    registerForContextMenu(getListView());
}


@Override
public void onCreateContextMenu(ContextMenu menu, View v,
        ContextMenuInfo menuInfo) {

    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
        String name = adapter2.getItem(info.position).get_name();
        menu.setHeaderTitle(name);
        MenuInflater inflater = this.getActivity().getMenuInflater();
        inflater.inflate(R.menu.menulistitem, menu);
        MenuItem mi = menu.findItem(R.id.action_context_delete);
        Intent i = new Intent();
        i.putExtra("id", adapter2.getItem(info.position).get_id());
        mi.setIntent(i);
    }
}

@Override
public boolean onContextItemSelected(MenuItem item) {

    switch (item.getItemId()) {
    case R.id.action_context_delete:
        Intent i = item.getIntent();
        if (i != null) {
            Bundle b = i.getExtras();
            if (b != null) {
                int id = b.getInt("id");
                Uri deleteIdUri = ContentUris.withAppendedId(
                        RidesDatabaseProvider.CONTENT_URI, id);
                context.getContentResolver()
                        .delete(deleteIdUri, null, null);
                return true;
            }
        }
    }
    return super.onContextItemSelected(item);
}

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:yourapp="http://schemas.android.com/apk/res-auto" >

    <item
        android:id="@+id/action_context_delete"
        android:icon="@drawable/action_about"
        android:orderInCategory="100"
        android:showAsAction="ifRoom"
        android:title="delete"
        yourapp:showAsAction="ifRoom"/>

</menu>
于 2015-02-04T15:22:32.847 回答