长按删除列表项(在主从中使用片段)
Posted
技术标签:
【中文标题】长按删除列表项(在主从中使用片段)【英文标题】:LongClick to Delete List Item (Using Fragments in Master-Detail) 【发布时间】:2015-01-16 03:56:10 【问题描述】:我已经创建了一个 Master-Detail Flow 应用程序,并且我正在使用 Eclipse/android 创建的所有默认文件。我使用模板创建了一个项目,并没有修改其中的任何内容,除了添加下面讨论的删除项目的方法。
我需要实现一个 onItemLongClickListener 以便当我长按列表中的一个项目时,该项目会被删除。我不想要警报或确认或选择多个项目,我只想让我长按的那个消失。
我找到了几个关于这个主题的教程,但我的问题是他们没有使用片段,所以我对哪些方法去哪里有点困惑。 (这是我最常使用的:AndroidForBeginners)
如果我理解正确,我应该只使用 ItemListActivity 和 ItemListFragment。我理解Fragment中的方法会在Activity中被调用(比如模板自带的默认onItemSelected)。我了解 removeItemFromList 方法(来自链接教程)从数组中删除项目并通知适配器更新列表。我的问题是,我不知道数组和适配器在 Master-Detail 片段和活动中的位置。 DummyContent 中有一个 ArrayList,所以我想如果我在片段中调用 removeItem,然后将其发送到 Activity,然后从 DummyContent 类调用它就可以了。但它没有,我被困住了。
任何建议将不胜感激!
根据要求,这是我目前正在使用的代码。正如我所说,只是默认的 android 模板。
ItemListActivity.java
package Andrea.deletelistitem;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
/**
* An activity representing a list of Items. This activity
* has different presentations for handset and tablet-size devices. On
* handsets, the activity presents a list of items, which when touched,
* lead to a @link ItemDetailActivity representing
* item details. On tablets, the activity presents the list of items and
* item details side-by-side using two vertical panes.
* <p>
* The activity makes heavy use of fragments. The list of items is a
* @link ItemListFragment and the item details
* (if present) is a @link ItemDetailFragment.
* <p>
* This activity also implements the required
* @link ItemListFragment.Callbacks interface
* to listen for item selections.
*/
public class ItemListActivity extends FragmentActivity
implements ItemListFragment.Callbacks
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
*/
private boolean mTwoPane;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_list);
if (findViewById(R.id.item_detail_container) != null)
// The detail container view will be present only in the
// large-screen layouts (res/values-large and
// res/values-sw600dp). If this view is present, then the
// activity should be in two-pane mode.
mTwoPane = true;
// In two-pane mode, list items should be given the
// 'activated' state when touched.
((ItemListFragment) getSupportFragmentManager()
.findFragmentById(R.id.item_list))
.setActivateOnItemClick(true);
// TODO: If exposing deep links into your app, handle intents here.
/**
* Callback method from @link ItemListFragment.Callbacks
* indicating that the item with the given ID was selected.
*/
@Override
public void onItemSelected(String id)
if (mTwoPane)
// In two-pane mode, show the detail view in this activity by
// adding or replacing the detail fragment using a
// fragment transaction.
Bundle arguments = new Bundle();
arguments.putString(ItemDetailFragment.ARG_ITEM_ID, id);
ItemDetailFragment fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment)
.commit();
else
// In single-pane mode, simply start the detail activity
// for the selected item ID.
Intent detailIntent = new Intent(this, ItemDetailActivity.class);
detailIntent.putExtra(ItemDetailFragment.ARG_ITEM_ID, id);
startActivity(detailIntent);
ItemListFragment.java
package Andrea.deletelistitem;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import Andrea.deletelistitem.dummy.DummyContent;
/**
* A list fragment representing a list of Items. This fragment
* also supports tablet devices by allowing list items to be given an
* 'activated' state upon selection. This helps indicate which item is
* currently being viewed in a @link ItemDetailFragment.
* <p>
* Activities containing this fragment MUST implement the @link Callbacks
* interface.
*/
public class ItemListFragment extends ListFragment
/**
* The serialization (saved instance state) Bundle key representing the
* activated item position. Only used on tablets.
*/
private static final String STATE_ACTIVATED_POSITION = "activated_position";
/**
* The fragment's current callback object, which is notified of list item
* clicks.
*/
private Callbacks mCallbacks = sDummyCallbacks;
/**
* The current activated item position. Only used on tablets.
*/
private int mActivatedPosition = ListView.INVALID_POSITION;
/**
* A callback interface that all activities containing this fragment must
* implement. This mechanism allows activities to be notified of item
* selections.
*/
public interface Callbacks
/**
* Callback for when an item has been selected.
*/
public void onItemSelected(String id);
/**
* A dummy implementation of the @link Callbacks interface that does
* nothing. Used only when this fragment is not attached to an activity.
*/
private static Callbacks sDummyCallbacks = new Callbacks()
@Override
public void onItemSelected(String id)
;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public ItemListFragment()
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
// TODO: replace with a real list adapter.
setListAdapter(new ArrayAdapter<DummyContent.DummyItem>(
getActivity(),
android.R.layout.simple_list_item_activated_1,
android.R.id.text1,
DummyContent.ITEMS));
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
// Restore the previously serialized activated item position.
if (savedInstanceState != null
&& savedInstanceState.containsKey(STATE_ACTIVATED_POSITION))
setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
@Override
public void onAttach(Activity activity)
super.onAttach(activity);
// Activities containing this fragment must implement its callbacks.
if (!(activity instanceof Callbacks))
throw new IllegalStateException("Activity must implement fragment's callbacks.");
mCallbacks = (Callbacks) activity;
@Override
public void onDetach()
super.onDetach();
// Reset the active callbacks interface to the dummy implementation.
mCallbacks = sDummyCallbacks;
@Override
public void onListItemClick(ListView listView, View view, int position, long id)
super.onListItemClick(listView, view, position, id);
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
@Override
public void onSaveInstanceState(Bundle outState)
super.onSaveInstanceState(outState);
if (mActivatedPosition != ListView.INVALID_POSITION)
// Serialize and persist the activated item position.
outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
/**
* Turns on activate-on-click mode. When this mode is on, list items will be
* given the 'activated' state when touched.
*/
public void setActivateOnItemClick(boolean activateOnItemClick)
// When setting CHOICE_MODE_SINGLE, ListView will automatically
// give items the 'activated' state when touched.
getListView().setChoiceMode(activateOnItemClick
? ListView.CHOICE_MODE_SINGLE
: ListView.CHOICE_MODE_NONE);
private void setActivatedPosition(int position)
if (position == ListView.INVALID_POSITION)
getListView().setItemChecked(mActivatedPosition, false);
else
getListView().setItemChecked(position, true);
mActivatedPosition = position;
DummyContent.java
package Andrea.deletelistitem.dummy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Helper class for providing sample content for user interfaces created by
* Android template wizards.
* <p>
* TODO: Replace all uses of this class before publishing your app.
*/
public class DummyContent
/**
* An array of sample (dummy) items.
*/
public static List<DummyItem> ITEMS = new ArrayList<DummyItem>();
/**
* A map of sample (dummy) items, by ID.
*/
public static Map<String, DummyItem> ITEM_MAP = new HashMap<String, DummyItem>();
static
// Add 3 sample items.
addItem(new DummyItem("1", "Item 1"));
addItem(new DummyItem("2", "Item 2"));
addItem(new DummyItem("3", "Item 3"));
private static void addItem(DummyItem item)
ITEMS.add(item);
ITEM_MAP.put(item.id, item);
/**
* A dummy item representing a piece of content.
*/
public static class DummyItem
public String id;
public String content;
public DummyItem(String id, String content)
this.id = id;
this.content = content;
@Override
public String toString()
return content;
这是教程中的方法:
protected void removeItemFromList(int position)
final int deletePosition = position;
AlertDialog.Builder alert = new AlertDialog.Builder(
MainActivity.this);
alert.setTitle("Delete");
alert.setMessage("Do you want delete this item?");
alert.setPositiveButton("YES", new OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
// TOD O Auto-generated method stub
// main code on after clicking yes
arr.remove(deletePosition);
adapter.notifyDataSetChanged();
adapter.notifyDataSetInvalidated();
);
alert.setNegativeButton("CANCEL", new OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
// TODO Auto-generated method stub
dialog.dismiss();
);
alert.show();
这是我修改后的方法,用于删除确认警报:
protected void removeItemFromList(int position)
arr.remove(position);
adapter.notifyDataSetChanged();
adapter.notifyDataSetInvalidated();
在这种方法中,我认为 DummyContent 中的 ITEMS 将替换 arr 数组,因为它是一个 ArrayList。不过,我不确定适配器。
【问题讨论】:
你能发布你目前拥有的代码吗? 本教程将 LongClickListener 设置为它的 ListView,但由于片段的原因,我不知道这适用于我的代码的什么地方。 现在想来,如果我理解正确的话,我使用Activity从ListFragment发送一些东西到DetailFragment。在这种情况下,我根本没有触及细节,那么我什至需要使用 ListActivity 吗?一切都应该只在 ListFragment 中完成吗? 【参考方案1】:在任何 Fragment 上都有一个名为 onActivityCreated
的方法,您想 @Override 该方法。
然后,在其中使用getListView()
,您可以附加一个onLongItemClickListener()
。
像这样:
getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
//Here you implement your code. Basically delete an item from
// the underlying data structure of your adapter, and then...
setListAdapter(.....); //re-set the list adapter.
return false;
);
【讨论】:
以上是关于长按删除列表项(在主从中使用片段)的主要内容,如果未能解决你的问题,请参考以下文章