I customized the option menu, removed default background and customized the item it self by referring to a style, but I stack in removal the line between the items as shown in pic.
Any advice will be appreciated.
My code :
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:width="1dp" android:height="1dp" android:color="#B22222" />
<solid android:color="#FCE6C9" />
<padding android:left="2dp" android:top="2dp" android:right="2dp"
android:bottom="2dp" />
<corners android:bottomRightRadius="30dp" android:bottomLeftRadius="30dp"
android:topLeftRadius="30dp" android:topRightRadius="30dp" />
</shape>
Option menu code :
public class OptionMenu extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);}
public boolean onCreateOptionsMenu(android.view.Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.cool_menu, menu);
getLayoutInflater().setFactory(new Factory() {
public View onCreateView(String name, Context context,
AttributeSet attrs) {
if (name .equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView")) {
try {
LayoutInflater li = LayoutInflater.from(context);
final View view = li.createView(name, null, attrs);
new Handler().post(new Runnable() {
public void run() {
// set the background drawable
view .setBackgroundResource(R.drawable.border);
((TextView) view).setTextSize(20);
// set the text color
((TextView) view).setTextColor(Color.RED);}
});
return view;}
catch (InflateException e) { }
catch (ClassNotFoundException e) { }
}
return null; }
});
return super.onCreateOptionsMenu(menu);}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.AboutUs:
Intent i = new Intent("com.test.demo.ABOUT");
startActivity(i);
break;
case R.id.preferences:
Intent p = new Intent("com.test.demo.PREFS");
startActivity(p);
break;
case R.id.exit:
finish();
break;}
return false;} }
cool_menu.xml :
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="about" android:id="@+id/AboutUs" />
<item android:title="Prefs" android:id="@+id/preferences" />
<item android:title="Exit" android:id="@+id/exit" />
</menu>
menu_style.xml :
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme_menu">
<item name="android:panelFullBackground">@drawable/border</item>
</style>
</resources>
referal of style in manifest to option menu :
<activity
android:name=".OptionMenu"
android:label="@string/app_name" android:theme="@style/Theme_menu">
As you mentioned you want to find a solution for removing line. I have no idea to do that but I also prefer to write my own menu system that is dynamic and customizable ( specially in animation and graphic ). You can pick the source code that written for my own projects.
And design your layout as you wish.
Sample Result:
UPDATE: COMPLETE ANSWER
NEXT
public class MenuActivity extends EnhancedActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
NEXT
public class EnhancedActivity extends Activity {
private static Activity _this;
public static Activity getCurrent() {
return _this;
}
public static void setCurrent(Activity activity) {
_this = activity;
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
_this = this;
G.gWidgetMenu.retarget();
}
@Override
protected void onResume() {
super.onResume();
if (_this == this) {
return;
}
_this = this;
G.gWidgetMenu.retarget();
}
@Override
protected void onPause() {
G.gWidgetMenu.forceClose();
super.onPause();
}
@Override
public boolean onKeyDown(int keycode, KeyEvent e) {
if (G.gWidgetMenu.processKey(keycode, e)) {
return true;
}
return super.onKeyDown(keycode, e);
}
}
NEXT
public class G extends Application {
public static Context gContext;
public static LayoutInflater gInflator;
public static WidgetMenu gWidgetMenu;
@Override
public void onCreate() {
gContext = getApplicationContext();
gInflator = (LayoutInflater) gContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
gWidgetMenu = new WidgetMenu();
}
}
NEXT
public class WidgetMenu extends FrameLayout implements AnimationListener {
private static final int _RES_LAYOUT = R.layout.widget_menu;
private static final int _RES_ANIMATION_OPEN = R.anim.anim_menu_open;
private static final int _RES_ANIMATION_CLOSE = R.anim.anim_menu_close;
private static final Animation _ANIM_OPEN = AnimationUtils.loadAnimation(G.gContext, _RES_ANIMATION_OPEN);
private static final Animation _ANIM_CLOSE = AnimationUtils.loadAnimation(G.gContext, _RES_ANIMATION_CLOSE);
private static boolean _canReceiveKey = true;
private Ui _ui;
public WidgetMenu() {
super(G.gContext);
_ANIM_CLOSE.setAnimationListener(this);
_ANIM_OPEN.setAnimationListener(this);
View view = G.gInflator.inflate(_RES_LAYOUT, this);
_ui = new Ui(view);
}
/**
* open/close menu if menu key pressed, and close menu when back key
* pressed. if this method act, it will return true other wise return false
* as meaning no action occured.
*/
public boolean processKey(int keycode, KeyEvent e) {
if ( !_canReceiveKey) {
return false;
}
switch (keycode) {
case KeyEvent.KEYCODE_MENU:
if (getVisibility() == View.VISIBLE) {
close();
} else {
open();
}
return true;
case KeyEvent.KEYCODE_BACK:
if (getVisibility() == View.VISIBLE) {
close();
return true;
}
return false;
}
return false;
}
public void retarget() {
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, Gravity.LEFT | Gravity.BOTTOM);
if (EnhancedActivity.getCurrent() != null) {
ViewGroup parent = (ViewGroup) getParent();
if (parent != null) {
parent.removeView(this);
}
setVisibility(View.GONE);
_ui.format();
EnhancedActivity.getCurrent().addContentView(this, layoutParams);
_canReceiveKey = true;
}
}
public void forceClose() {
onAnimationEnd(_ANIM_CLOSE);
}
/** play close animation and when close listener act, remove it from view */
private void close() {
_canReceiveKey = false;
startAnimation(_ANIM_CLOSE);
}
/** add control to view an show open animation */
private void open() {
_canReceiveKey = false;
setVisibility(View.VISIBLE);
startAnimation(_ANIM_OPEN);
}
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
if (animation == _ANIM_CLOSE) {
setVisibility(View.GONE);
}
_canReceiveKey = true;
}
private class Ui {
public ViewGroup panel_about;
public ViewGroup panel_setting;
public Ui(View view) {
panel_about = (ViewGroup) findViewById(R.id.panel_about);
panel_setting = (ViewGroup) findViewById(R.id.panel_setting);
format();
}
public void format() {
panel_about.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Log.i("LOG", "About Menu Pressed");
}
});
panel_setting.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Log.i("LOG", "Setting Menu Pressed");
}
});
}
}
}
NEXT widget_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" android:background="#000000">
<ImageView
android:id="@+id/imageView2"
android:layout_width="fill_parent"
android:layout_height="2dip"
android:background="#c84300"/>
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_marginTop="4dip">
<LinearLayout
android:id="@+id/panel_feedback"
android:layout_width="1dip"
android:layout_height="wrap_content"
android:layout_marginLeft="4dip"
android:layout_weight="0.33"
android:background="#330000"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingBottom="4dip"
android:paddingTop="4dip" android:layout_marginRight="2dip">
<ImageView
android:id="@+id/ImageView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dip"
android:singleLine="true"
android:text="Feedback"
android:textColor="#ffffff"
android:textSize="17dip"/>
</LinearLayout>
<LinearLayout
android:id="@+id/panel_about"
android:layout_width="1dip"
android:layout_height="wrap_content"
android:layout_weight="0.33"
android:background="#330000"
android:gravity="center_horizontal"
android:orientation="vertical"
android:layout_marginLeft="2dip" android:layout_marginRight="2dip" android:paddingTop="4dip" android:paddingBottom="4dip">
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/txt_menu1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dip"
android:singleLine="true"
android:text="About"
android:textColor="#ffffff"
android:textSize="17dip"/>
</LinearLayout>
<LinearLayout
android:id="@+id/panel_setting"
android:layout_width="1dip"
android:layout_height="wrap_content"
android:layout_weight="0.33"
android:background="#330000"
android:gravity="center_horizontal"
android:orientation="vertical"
android:layout_marginRight="4dip" android:paddingTop="4dip" android:paddingBottom="4dip" android:layout_marginLeft="2dip">
<ImageView
android:id="@+id/ImageView05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/txt_menu2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dip"
android:singleLine="true"
android:text="Settings"
android:textColor="#ffffff"
android:textSize="17dip"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
NEXT anim_menu_close.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="200"
android:fillAfter="true"
android:fillBefore="true"
android:fromXDelta="0%"
android:fromYDelta="0%"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:repeatCount="0"
android:toXDelta="0%"
android:toYDelta="100%" />
</set>
NEXT anim_menu_open.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="200"
android:fillAfter="true"
android:fillBefore="true"
android:fromXDelta="0%"
android:fromYDelta="100%"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:repeatCount="0"
android:toXDelta="0%"
android:toYDelta="0%" />
</set>
NEXT manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.uncocoder.menu"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="7" />
<application
android:name="com.uncocoder.menu.G"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name="com.uncocoder.menu.MenuActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Those dividers look similar to those inserted by default between entries in a ListView. Depending on how similar Menu is to ListView (which is probably not very) the following code modification might work:
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
android:divider="@android:color/transparent">
<item android:title="about" android:id="@+id/AboutUs" />
<item android:title="Prefs" android:id="@+id/preferences" />
<item android:title="Exit" android:id="@+id/exit" />
</menu>
If that doesn't work it might be useful to read up on the Menu object. I found the following quote from the Menu.addIntentOptions()
function documentation.
Normally this function will automatically remove any existing items in the menu in the same group and place a divider above and below the added items; this behavior can be modified with the flags parameter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With