最近在做通过程序内定义菜单编写安卓的上下文菜单程序时,出现了模拟器上程序长按菜单只能出来一次的情况,再次长按无法再出现菜单。
MainActivity的 代码为:
package com.example.my17jk_09_e1;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.registerForContextMenu(findViewById(R.id.textOne));
this.registerForContextMenu(findViewById(R.id.textTwo));
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
menu.setHeaderIcon(R.drawable.ic_launcher);
if(view == findViewById(R.id.textOne)) {
menu.add(0, 1, 0, "二号大小");
menu.add(0, 2, 0, "三号大小");
menu.add(0, 3, 0, "四号大小");
menu.add(0, 4, 0, "五号大小");
}
if(view == findViewById(R.id.textTwo)) {
menu.add(0, 5, 0, "红色");
menu.add(0, 6, 0, "蓝色");
menu.add(0, 7, 0, "绿色");
menu.add(0, 8, 0, "黑色");
}
}
/**
* 必须注释掉setContentView这句话,否则将导致多选框只能被调用第一次。——2019.10.28
* @param size
*/
void setFontSize(int size) {
//setContentView(R.layout.activity_main);
TextView textOne = (TextView)findViewById(R.id.textOne);
TextView textTwo = (TextView)findViewById(R.id.textTwo);
textOne.setTextSize(size);
textTwo.setTextSize(size);
}
void setFontColor(int c) {
//setContentView(R.layout.activity_main);
TextView textOne = (TextView)findViewById(R.id.textOne);
TextView textTwo = (TextView)findViewById(R.id.textTwo);
textOne.setTextColor(c);
textTwo.setTextColor(c);
}
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {
case 1:
setFontSize(16); break;
case 2:
setFontSize(25);break;
case 3:
setFontSize(30);break;
case 4:
setFontSize(35);break;
case 5:
setFontColor(Color.RED);break;
case 6:
setFontColor(Color.BLUE);break;
case 7:
setFontColor(Color.GREEN);break;
case 8:
setFontColor(Color.BLACK);break;
default:
return super.onContextItemSelected(item);
}
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
xml布局代码略。
程序的模拟器效果图如下,长按语句会弹出菜单框:
当时的问题在,在第一次长按调出菜单框后,第二次及之后长按不会出任何东西。
后来,发现在调用设置字体和颜色的函数里,
void setFontSize(int size) {
//setContentView(R.layout.activity_main);
TextView textOne = (TextView)findViewById(R.id.textOne);
TextView textTwo = (TextView)findViewById(R.id.textTwo);
textOne.setTextSize(size);
textTwo.setTextSize(size);
}
void setFontColor(int c) {
//setContentView(R.layout.activity_main);
TextView textOne = (TextView)findViewById(R.id.textOne);
TextView textTwo = (TextView)findViewById(R.id.textTwo);
textOne.setTextColor(c);
textTwo.setTextColor(c);
}
注释掉setContentView(R.layout.activity_main)
后,菜单框才能被重复按出,即onCreateContextMenu函数才能正常运行。
经测试,在调用setContentView函数后,必须调用registerForContextMenu函数注册上下文菜单控件,否则,新建立的View不仅会覆盖原来的视图效果,还会因为没有给控件注册上下文菜单导致上下文菜单不能再调用出,即本次上下文菜单只能调用一次的原因所在。
事实上,通过TextView textOne = (TextView)findViewById(R.id.textOne); TextView textTwo = (TextView)findViewById(R.id.textTwo); 调用控件并不需要再新建视图,即没必要再调用setContentView。
总结:
在程序中创建上下文菜单的步骤:
- 第一步,重写Activity的onCreateContextMenu()方法,调用Menu的add()方法添加菜单项MenuItem。
- 第二步,重写Activity的onContextItemSelected()方法,响应菜单单击事件。
- 第三步,调用registerForContextMenu()方法,为视图View对象注册上下文菜单。