ListView があるので、ユーザーは項目を長押ししてコンテキストメニューを取得できます。私が抱えている問題は、長押ししたListItem
を決定することです。私はこれを試しました:
myListView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
@Override public void onCreateContextMenu(ContextMenu menu, final View v, ContextMenuInfo menuInfo) {
menu.add("Make Toast")
.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override public boolean onMenuItemClick(MenuItem item) {
String toastText = "You clicked position " + ((ListView)v).getSelectedItemPosition();
Toast.makeText(DisplayScheduleActivity.this, toastText, Toast.LENGTH_SHORT).show();
return true;
}
});
}
});
ただし、 [〜#〜] anr [〜#〜] がポップアップするまでハングします。メニューが作成された後、ListItem
が選択されなくなったと思われます。
クリックまたはロングクリックを監視し、クリックされたアイテムをそこに記録できるようです:
mArrivalsList.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
// record position/id/whatever here
return false;
}
});
しかし、それは私にとって非常に厄介です。誰もこれに対してより良い解決策がありますか?
私はまさにこれを行います。 onCreateContextMenu(...)
メソッドで、_ContextMenu.ContextMenuInfo
_を_AdapterView.AdapterContextMenuInfo
_にキャストしました。そこからtargetViewを取得し、ウィジェットに再度キャストします。完全なコードは HomeActivity.Java で利用可能です。onCreateContextMenu(...)
メソッドを探してください。
_@Override
public void onCreateContextMenu(ContextMenu contextMenu,
View v,
ContextMenu.ContextMenuInfo menuInfo) {
AdapterView.AdapterContextMenuInfo info =
(AdapterView.AdapterContextMenuInfo) menuInfo;
selectedWord = ((TextView) info.targetView).getText().toString();
selectedWordId = info.id;
contextMenu.setHeaderTitle(selectedWord);
contextMenu.add(0, CONTEXT_MENU_EDIT_ITEM, 0, R.string.edit);
contextMenu.add(0, CONTEXT_MENU_DELETE_ITEM, 1, R.string.delete);
}
_
選択したテキストと選択IDをプライベートフィールドに保存することに注意してください。 UIはスレッドに限定されているため、selectedWordフィールドとselectedWordIdフィールドは、後のアクションで正しくなることを知っています。
まず、View.setOnCreateContextMenuListener()
を使用して、少し複雑になりすぎているのではないかと思っています。 Activity.registerForContextMenu()
を使用すると、すべてのメニューイベントを処理するためにActivity.onCreateContextMenu()
とActivity.onContextItemSelected()
を使用できるため、物事がはるかに簡単になります。基本的に、すべてのイベントを処理するためにこれらすべての匿名内部クラスを定義する必要はありません。これらのコンテキストメニューイベントを処理するには、いくつかのActivityメソッドをオーバーライドするだけです。
第二に、現在選択されているアイテムを取得する簡単な方法が間違いなくあります。必要なことは、ListView
またはそれを設定するために使用されるAdapter
への参照を保持することだけです。 ContextMenuInfoをAdapterContextMenuInfoとして使用して、アイテムの位置を取得できます。その後、ListView.getItemAtPosition()
またはAdapter.getItem()
を使用して、クリックされたものに特にリンクされたObject
を取得できます。たとえば、Activity.onCreateContextMenu()
を使用しているとすると、これを行うことができます。
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
// Get the info on which item was selected
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
// Get the Adapter behind your ListView (this assumes you're using
// a ListActivity; if you're not, you'll have to store the Adapter yourself
// in some way that can be accessed here.)
Adapter adapter = getListAdapter();
// Retrieve the item that was clicked on
Object item = adapter.getItem(info.position);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
// Here's how you can get the correct item in onContextItemSelected()
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
Object item = getListAdapter().getItem(info.position);
}
これは、コンテキストメニューを作成する方法の別の方法ですnここで選択した項目を削除する方法はコード全体です
public class SimpleJokeList extends Activity {
public static final int Upload = Menu.FIRST + 1;
public static final int Delete = Menu.FIRST + 2;
int position;
ListView lv;
EditText jokeBox;
Button addJoke;
MyAdapter adapter;
private ArrayAdapter<String> mAdapter;
private ArrayList<String> mStrings = new ArrayList<String>();
String jokesToBeAdded;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simplejokeui);
lv=(ListView)findViewById(R.id.jokelist);
addJoke=(Button)findViewById(R.id.addjoke);
jokeBox=(EditText)findViewById(R.id.jokebox);
mAdapter = new ArrayAdapter<String>(this, Android.R.layout.simple_list_item_1, mStrings);
registerForContextMenu(lv);
listItemClicked();
addJokes();
private void addJokes() {
// TODO Auto-generated method stub
addJoke.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
jokesToBeAdded=jokeBox.getText().toString();
if(jokesToBeAdded.equals("")){
Toast.makeText(getApplicationContext(), "please enter some joke", Toast.LENGTH_LONG).show();
}
else{
lv.setAdapter(mAdapter);
mAdapter.add(jokesToBeAdded);
jokeBox.setText(null);
}
}
});
}
private void listItemClicked() {
// TODO Auto-generated method stub
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
position=arg2;
return false;
}
});
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
// TODO Auto-generated method stub
super.onCreateContextMenu(menu, v, menuInfo);
populateMenu(menu);
menu.setHeaderTitle("Select what you wanna do");
}
private void populateMenu(ContextMenu menu) {
// TODO Auto-generated method stub
menu.add(Menu.NONE, Upload, Menu.NONE, "UPLOAD");
menu.add(Menu.NONE, Delete, Menu.NONE, "DELETE");
}
@Override
public boolean onContextItemSelected(MenuItem item)
{
return (applyMenuChoice(item) || super.onContextItemSelected(item));
}
private boolean applyMenuChoice(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId())
{
case Delete:
String s=mAdapter.getItem(position);
mAdapter.remove(s);
// position--;
Toast.makeText(getApplicationContext(),"Congrats u HAve Deleted IT", Toast.LENGTH_LONG).show();
return (true);
}
return false;
}
そしてこれを置くことを忘れないでください
registerForContextMenu(listview);
onCreate
メソッドで、コンテキストメニューを表示します。
ビュー引数は、実際に選択された行のビューではありませんか、またはここで質問がありませんか?
ListView lv;
private OnItemLongClickListener onLongClick = new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
lv.showContextMenuForChild(arg1);
lv.showContextMenu();
return false;
}
};
私たちは成功して使用しました:
@Override
public boolean onContextItemSelected
(
MenuItem item
)
{
if (!AdapterView.AdapterContextMenuInfo.class.isInstance (item.getMenuInfo ()))
return false;
AdapterView.AdapterContextMenuInfo cmi =
(AdapterView.AdapterContextMenuInfo) item.getMenuInfo ();
Object o = getListView ().getItemAtPosition (cmi.position);
return true;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
View TargetV=(View) info.targetView;
text1 = (String) ((TextView) TargetV.findViewById(R.id.textView1)).getText();
text2 = (String) ((TextView) TargetV.findViewById(R.id.textView2)).getText();
if(List3Ok){
text3 = (String) ((TextView) TargetV.findViewById(R.id.textView3)).getText();
}
selectedWord = text1 + "\n" + text2 + "\n" + text3;
selectedWordId = info.id;
menu.setHeaderTitle(selectedWord);
MenuInflater inflater = this.getActivity().getMenuInflater();
inflater.inflate(R.menu.list_menu, menu);
}
SimpleCursorAdapder
を使用している場合、次のようにできます
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
getActivity().getMenuInflater().inflate(R.menu.project_list_item_context, menu);
// Getting long-pressed item position
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
int position = info.position;
// Get all records from adapter
Cursor c = ((SimpleCursorAdapter)getListAdapter()).getCursor();
// Go to required position
c.moveToPosition(position);
// Read database fields values associated with our long-pressed item
Log.d(TAG, "Long-pressed-item with position: " + c.getPosition());
Log.d(TAG, "Long-pressed-item _id: " + c.getString(0));
Log.d(TAG, "Long-pressed-item Name: " + c.getString(1));
Log.d(TAG, "Long-pressed-item Date: " + c.getString(2));
Log.d(TAG, "Long-pressed-item Path: " + c.getString(3));
// Do whatever you need here with received values
}