我在应用程序中遇到的问题是在 API级别9 下运行 API级别11 (对于更高级别,它可以)。 我有一个继承 ListActivity 的活动,当用户长按一下时,对于此列表中的每个项目,都会显示一个上下文菜单。 问题是当运行API级别9/11时,上下文菜单会出现两次。 仍然无法弄清楚原因。 这是场景(代码):
的活动:
public class ActivityBoxList extends ToyshopActivity {
public static final String SELECTED_BOX_ID = "selected_box_id";
public static final String SELECTED_DATE_PERIOD = "selected_date_period";
public static final int FILE_SELECT_CODE = 0;
private BoxService boxService;
private LinearLayout layoutBoxSubHeader;
private LinearLayout layoutBoxLabelsSubHeader;
private EntryService entryService;
private ImageButton btnMainMenu, btnAddMonthIncome;
private TextView txtSelectedDatePeriodMonth, txtSelectedDatePeriodYear, txtMonthIncomeSum, txtMonthOutgoSum, txtMonthBalance;
private static BoxRepository boxRepository;
private int selectedBoxIndex;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.box_list_view);
context = this;
boxService = BoxService.getInstance();
entryService = EntryService.getInstance();
initLayout();
receiveSelectedDatePeriodBroadcast();
registerForContextMenu(getListView());
final BoxAdapter adapter = new BoxAdapter(this, getData());
setListAdapter(adapter);
registerForContextMenu(this.btnMainMenu);
increaseAccessCounter();
}
protected void onRestoreInstanceState(android.os.Bundle state) {
selectedDatePeriod = (DatePeriod)state.get(ActivityBoxList.SELECTED_DATE_PERIOD);
}
@Override
protected void onNewIntent(android.content.Intent intent) {
selectedDatePeriod = (DatePeriod)intent.getSerializableExtra(ActivityBoxList.SELECTED_DATE_PERIOD);
refreshListData(null);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public void refreshListData(Long domainId) {
Collection<Box> boxes = getData();
setLayoutVisibility();
BoxAdapter adapter = new BoxAdapter(context, boxes);
setListAdapter(adapter);
adapter.notifyDataSetChanged();
}
this.btnMainMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openContextMenu(view);
}
});
this.btnAddMonthIncome.setOnClickListener(new View.OnClickListener() {
Dialog dialogAddIncome = new DialogAddMonthIncome(context);
@Override
public void onClick(View view) {
if (DatePeriod.isSelectedPeriodActual(selectedDatePeriod)) {
dialogAddIncome.show();
}
else {
ToastOnMiddle.makeText(context, context.getString(R.string.txt_operation_not_permitted_not_actual_period), Integer.parseInt(context.getString(R.string.app_toast_time_long))).show();
}
}
});
}
@Override
protected void onRestart() {
super.onRestart();
context = this;
}
private View.OnClickListener openIncomeListOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
openIncomeListActivity();
}
};
@Override
public void onCreateContextMenu(android.view.ContextMenu menu, android.view.View v, android.view.ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
if(v.getId() == getListView().getId()) {
inflater.inflate(R.menu.context_menu_box, menu);
} else if (v.getId() == R.id.btn_main_menu) {
inflater.inflate(R.menu.main_menu, menu);
}
}
@Override
public boolean onContextItemSelected(android.view.MenuItem item) {
Box box = ((Box)getListView().getItemAtPosition(selectedBoxIndex));
if(!isFinishing()) {
if (item.getItemId() == R.id.box_edit) {
Dialog dialogEditBox = new DialogEditBox(context, box);
dialogEditBox.show();
} else if (item.getItemId() == R.id.box_delete) {
new AlertDialogDelete(context, context.getString(R.string.txt_delete_box_confirm), new OnClickListenerDeleteBoxConfirm(context, box), null).show();
} else if (item.getItemId() == R.id.main_menu_add_box) {
Dialog dialogAddBox = new DialogAddBox(context);
dialogAddBox.show();
} else if (item.getItemId() == R.id.main_menu_delete_month_income) {
openIncomeListActivity();
} else if (item.getItemId() == R.id.main_menu_select_period) {
Dialog dialogSelectPeriod = new DialogSelectPeriod(context, getSelectedDatePeriod());
dialogSelectPeriod.show();
} else if (item.getItemId() == R.id.main_menu_backup_data) {
Dialog dialogDataBackup = new DialogDataBackup(context);
dialogDataBackup.show();
} else if (item.getItemId() == R.id.main_menu_help) {
openHelpActivity();
}
}
return true;
}
}
适配器:
public class BoxAdapter extends BaseAdapter {
Collection<Box> boxes = new ArrayList<Box>(0);
LayoutInflater inflater;
Context context;
public BoxAdapter(Context context, Collection<Box> boxes){
this.boxes = boxes;
this.context = context;
this.inflater = LayoutInflater.from(this.context);
}
@Override
public int getCount() {
return boxes.size();
}
@Override
public Object getItem(int i) {
return ((ArrayList<Box>) boxes).get(i);
}
@Override
public long getItemId(int i) {
return i > 0 ? ((ArrayList<Box>) boxes).get(i).getId() : 0;
}
@Override
public View getView(final int i, View view, ViewGroup viewGroup) {
View v = view;
final ViewHolderBoxItem viewHolder;
if (view == null) {
final LayoutInflater li = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = li.inflate(R.layout.box_list_view_item, null);
viewHolder = new ViewHolderBoxItem(v);
v.setTag(viewHolder);
} else {
viewHolder = (ViewHolderBoxItem) v.getTag();
}
final Box box = ((ArrayList<Box>) boxes).get(i);
viewHolder.boxItemDescription.setText(box.getDescription());
viewHolder.boxItemValue.setText(box.getFormattedOutgoSum(this.context));
viewHolder.boxImage.setImageResource(resolveImageFor(box));
viewHolder.boxOutgoesBar.setBarSize(box.getBarSize());
viewHolder.boxOutgoesBar.setDomain(box);
viewHolder.layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivityEntryList(box, ((ActivityBoxList)context).getSelectedDatePeriod());
}
});
viewHolder.layout.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
((ActivityBoxList)context).setSelectedBoxIndex(i+1);
((ActivityBoxList)context).openContextMenu(((ActivityBoxList)context).getListView());
return false;
}
});
return v;
}
}
如您所见,长按侦听器附加在适配器中(仅一次):
viewHolder.layout.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
((ActivityBoxList)context).setSelectedBoxIndex(i+1);
((ActivityBoxList)context).openContextMenu(((ActivityBoxList)context).getListView());
return false;
}
});
我也只注册一次上下文菜单(onCreate):
registerForContextMenu(getListView());
我无法弄清楚为什么当我长按一下时,上下文菜单会出现两次。 欢迎任何帮助!
答案 0 :(得分:1)
我对解决方案不满意但...... 要修复它,我必须在膨胀之前关闭菜单(menu.close()):
@Override
public void onCreateContextMenu(android.view.ContextMenu menu, android.view.View v, android.view.ContextMenu.ContextMenuInfo menuInfo) {
menu.close(); //This fixes issue (duplicated menu) in Android APIs under version 15.
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
if(v.getId() == getListView().getId()) {
inflater.inflate(R.menu.context_menu_box, menu);
} else if (v.getId() == R.id.btn_main_menu) {
inflater.inflate(R.menu.main_menu, menu);
}
}
如果有人弄清楚这是什么原因并发布更好的答案,我会很高兴的!