I have a TextView functioning as a notification badge on a menu item. The problem is that the findViewById method always returns null after an orientation change, so when I try to modify its visibility with setVisibility it throws a NullPointerException. I've tried calling the onCreateOptionsMenu again by calling invalidateOptionsMenu in onRestart but it doesn't appear to help.
From what I can tell every other view is found and it's just this TextView that is being a nuisance.
The part where it crashes (this is called in onCreate) :
public void updateUnreadNotificationCount(final int unreadNotificationsCount) {
unreadNotificationCount = unreadNotificationsCount;
if (unreadNotificationCount == 0) {
notificationCounter.setVisibility(View.INVISIBLE);
}else {
notificationCounter.setVisibility(View.VISIBLE);
notificationCounter.setText(String.valueOf(unreadNotificationCount));
}
}
How the Textview gets created:
#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);
View count = menu.findItem(R.id.action_notifications).getActionView();
notificationCounter = (TextView) count.findViewById(R.id.textview_notification_count);
count.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mCtx, NotificationListActivity.class);
startActivity(i);
}
});
notificationCounter.setText(String.valueOf(unreadNotificationCount));
return super.onCreateOptionsMenu(menu);
}
The XML for the menu item:
<item
android:id="#+id/action_notifications"
android:title="#string/action_notifications"
android:icon="#drawable/ic_mail_white_48dp"
android:actionLayout="#layout/actionbar_notification_icon"
android:showAsAction="always"
app:showAsAction="always"
android:orderInCategory="60"/>
The action layout for the TextView:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
style="#android:style/Widget.ActionButton">
<ImageView
android:id="#+id/imageview_notification"
android:src="#drawable/ic_mail_white_48dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_margin="0dp"/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textview_notification_count"
android:layout_width="wrap_content"
android:minWidth="17sp"
android:textSize="12sp"
android:textColor="#ffffffff"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#null"
android:layout_alignTop="#id/imageview_notification"
android:layout_alignRight="#id/imageview_notification"
android:layout_marginRight="0dp"
android:layout_marginTop="3dp"
android:paddingBottom="1dp"
android:paddingRight="4dp"
android:paddingLeft="4dp"
android:background="#drawable/rounded_square"/>
</RelativeLayout>
Managed to fix the issue by moving the initialization of the TextView into onPrepareOptionsMenu and calling invalidateOptionsMenu() during onResume().
Related
I've been trying to load an image into a menu item which has been created through a custom layout and have been checking on the official documentation and on posts such as these Custom view for Menu Item but..
That's my onCreateOptionsMenu ond OnPrepareOptionsMenu
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
final MenuItem alertMenuItem = menu.findItem(R.id.action_my_personal);
FrameLayout rootView = (FrameLayout) alertMenuItem.getActionView();
redCircle = (FrameLayout) rootView.findViewById(R.id.view_alert_red_circle);
countTextView = (TextView) rootView.findViewById(R.id.view_alert_count_textview);
ImageView hc_image_menu_inflated = (ImageView) rootView.findViewById(R.id.hc_image_menu);
rootView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onOptionsItemSelected(alertMenuItem);
}
});
if (menu.findItem(R.id.hc_image_menu) != null) {
loadMenuIcon(menu.findItem(R.id.hc_image_menu), my_image_url);
}
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.toolbar_menu_main, menu);
return true;
}
As you can see I have added these lines to avoid the app crashing, as menu.finditem(R.id.hc_image_menu) is returning as null and that's where the problem is, as I want to populate the ImageView that has the id hc_image_menu but am not being successful despite so many attempts
if (menu.findItem(R.id.hc_image_menu) != null) {
loadMenuIcon(menu.findItem(R.id.hc_image_menu), my_image_url);
}
My code for my toolbar_main_menu layout is this:
<item
android:id="#+id/action_my_personal"
app:actionLayout="#layout/toolbar_menu_hc"
android:orderInCategory="100"
android:title="My Personal Trainer"
app:showAsAction="always" />
And for my custom layout (toolbar_hc_menu) is this one:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="48dp"
android:layout_height="32dp"
android:layout_gravity="center">
<ImageView
android:id="#+id/hc_image_menu"
android:layout_marginRight="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="#drawable/gavin"/>
<FrameLayout
android:id="#+id/view_alert_red_circle"
android:layout_width="14dp"
android:layout_height="14dp"
android:layout_gravity="top|end"
android:background="#drawable/date_circle"
android:visibility="gone"
tools:visibility="visible">
<TextView
android:id="#+id/view_alert_count_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#color/white"
android:textSize="10sp"
tools:text="3"/>
</FrameLayout>
Thanks very much for any help on that. Really much appreciated!! :)
Issue fixed. :)
At the end I just had to load the image into the ImageView after having got the alertMenuItem.
if (my_image_url!= null) {
Picasso.with(getApplicationContext()).load(my_image_url).into(hc_image_menu_inflated);
}
I am using the new Android BottomNavigationView but the bottom navigation MenuItem action view is not showing.
After debugging I found that the menu item is not null and the visibility is visible.
After checking height and width of the root view it's coming 0 even after hardcoding the values in layout layout_width=50dp and layout_height=50dp of the root element.
Here is my bottom navigation menu:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/nearby_fragment"
android:enabled="true"
android:icon="#drawable/homenearbyfragment"
android:title="#string/bottom_nearby"
app:showAsAction="always"/>
<item
android:id="#+id/route_fragment"
android:title="#string/bottom_homescreen"
android:enabled="true"
app:showAsAction="always"
android:icon="#drawable/home_mycommute" />
<item
android:id="#+id/newsfeed_activity"
android:title="#string/bottom_news"
android:enabled="true"
app:showAsAction="always"
android:icon="#drawable/newsfeed"
app:actionLayout="#layout/bagde_layout"/>
</menu>
My action layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="?android:attr/actionButtonStyle"
android:layout_width="50dp"
android:layout_height="50dp"
android:clickable="true"
android:focusable="true"
android:gravity="center">
<ImageView
android:id="#+id/menu_badge_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/newsfeed" />
<TextView
android:id="#+id/menu_badge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|end"
android:layout_marginTop="4dp"
android:background="#drawable/circle_bg"
android:gravity="center"
android:textColor="#android:color/white"
android:textSize="8sp"
/>
In my Activity I am trying to set:
private void setCountOnNews(Menu menu) {
mReportMenu = menu.findItem(R.id.newsfeed_activity);
FrameLayout count = (FrameLayout) mReportMenu.getActionView();
count.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, NewsFeedActivity.class);
startActivity(intent);
MainApplication.getInstance().trackScreenView(getString(R.string.tracknewsfeedmenu));
}
});
TextView notifCount = (TextView) count.findViewById(R.id.menu_badge);
//if (Utils.getNewsfeedCountPreference(MainActivity.this) > 0)
notifCount.setText(String.valueOf(Utils.getNewsfeedCountPreference(MainActivity.this)));
notifCount.setText("asd;jfnapsdifnaspdifnasdpifnaspdfnapsdifnaspidfnapsidfnaspdiufif");
Log.d(TAG, "setCountOnNews:" + notifCount.getText().toString());
//else
// notifCount.setVisibility(View.GONE);
}
Did you forget to add that in your MainActivity?
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
if you are using fragment than you need to set has option menu true.
setHasOptionsMenu(true);
I'm trying to implement a notification icon in my actionbar to show the count of notifications. Something like
I've added a custom layout file for it NotificationIcon.xml:
<!-- Menu Item Image -->
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp"
android:clickable="true"
android:src="#drawable/notification" />
<!-- Badge Count -->
<TextView
android:id="#+id/actionbar_notifcation_textview"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:minWidth="20dp"
android:layout_alignParentRight="true"
android:gravity="center_horizontal"
android:background="#drawable/circle_green"
android:fontFamily="sans-serif-black"
android:textStyle="bold"
android:text="0"
android:textColor="#FFFFFF" />
</RelativeLayout>
And used it in my menu as main_activity_actions.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/action_add"
android:title="#string/AddTag"
android:icon="#+drawable/ic_action_new"
android:showAsAction="always" />
<item
android:id="#+id/notification_icon"
android:title="#string/PendingJobs"
android:actionLayout="#layout/notificationIcon"
android:icon="#+drawable/notification"
android:showAsAction="always" />
<item
android:id="#+id/gps_status_icon"
android:title="#string/GPS"
android:icon="#+drawable/gps_grey"
android:showAsAction="always" />
</menu>
The UI looks fine but the OnOptionsItemSelected is not being called for the notification icon. It works fine for the other two.
I did google this and ound this link: onOptionsItemSelected not getting called when using custom action view
I tried to implement it in my main activity:
public override bool OnCreateOptionsMenu(IMenu menu)
{
actionBarMenu = menu;
MenuInflater.Inflate(Resource.Menu.main_activity_actions, menu);
var notificationMenuItem = menu.FindItem(Resource.Id.notification_icon);
notificationMenuItem.ActionView.Click += (sender, args) => {
this.OnOptionsItemSelected(notificationMenuItem);
};
return base.OnCreateOptionsMenu(menu);
}
but it does not works for me. It never fires the click event.
Please help.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
final View notification_icon= menu.findItem(R.id.notification_icon).getActionView();
notification_icon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// write ur code here
}
});
return super.onCreateOptionsMenu(menu);
}
use this code......hope it helps :)
i struggle with the same Problem and found following Solution:
First of all: i really don't know why but if you delete the
android:clickable="true"
then ... and ONLY then you get the click event!!!
Second: you have to set the Listener...
...
item.getActionView().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do Your Stuff.....
}
});
May someone can Explain why this is with the "android:clickable" Thing... i tough the standard value IS true??
You had made ImageButton clickable, and then written the clickListener for the Layout of menuItem. You can observe that if you click outside the ImageButton but inside the MenuItem layout, your listener will work. The reason is simple clickListener for ImageButton has nothing to do, on setting Clickable = true defines whether this button reacts to click events. Just simply set Clickable = false, your button will not react to its click event, eventually your whole layout will react to your defined clickListener and then your problem will be solved.
In my action bar, I have defined a menu item that can show text "DONE" by the code below:
Menu.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/action_register_text"
android:actionLayout="#layout/action_done_text"
android:title="#string/action_done"
android:showAsAction="always"/>
</menu>
action_done_text.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/expand_activities_button"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:clickable="true"
android:focusable="true"
android:addStatesFromChildren="true">
<TextView
android:id="#+id/register_action_bar_done"
android:layout_width="53dp"
android:layout_height="35dp"
android:layout_gravity="center"
android:layout_marginRight="10dip"
android:gravity="center"
android:text="DONE" />
</FrameLayout>
I have onCreateOptionsMenu implement properly in the code, and the view can show the text correctly, but just when I tap on the DONE text, onOptionsItemSelected is not called. To me, it seems like the click event is not recognized.
I was wondering if the above way is not a good way to add a text menu item?
Use this as shown in onOptionsItemSelected not called when using actionLayout (SherlockActionBar)
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.map_menu, menu);
for (int i = 0; i < menu.size(); i++) {
MenuItem item = menu.getItem(i);
if (item.getItemId() == R.id.menu_more) {
itemChooser = item.getActionView();
if (itemChooser != null) {
itemChooser.setOnClickListener(this);
}
}
}
return super.onCreateOptionsMenu(menu);
}
My android application has an action bar item to add employees.
So here what I did is call custom layout named add_employee when this action bar item clicked.
<item android:id="#+id/action_add"
android:icon="#drawable/ic_action_add_person"
android:title="#string/action_add"
android:showAsAction="ifRoom|collapseActionView"
android:actionLayout="#layout/add_employee"/>
Following image shows that custom layout:
This is a loyout xml file named add_employee. Add and cross marks are image views.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/imageView1"
android:layout_marginRight="12dp"
android:src="#drawable/ic_action_cancel" />
<EditText
android:id="#+id/editText1"
android:layout_width="228dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginRight="40dp"
android:layout_toLeftOf="#+id/imageView1"
android:ems="10"
android:inputType="numberSigned" />
<ImageView
android:id="#+id/addemp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/editText1"
android:layout_marginRight="26dp"
android:layout_toLeftOf="#+id/imageView2"
android:src="#drawable/ic_action_add_person" />
</RelativeLayout>
Now I want to get the entered value to this edit text field when add image view clicked. This operation should be handled in the same java class where I set the option menu also.
public class MainPortal extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_portal);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.main_portal, menu);
return super.onCreateOptionsMenu(menu);
}
}
I have used setOnItemClickListener for imge view but it ends with a forced closed error. How can I do this task?
Please help me...
Thanks in advanced.
Did you create the actions in onOptionsItemSelected? Where is the code showing the implementation of the Action bar tabs?
this is how to implement an option on actionbar
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_search:
openSearch();
return true;
case R.id.action_compose:
composeMessage();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
there you can implement whatever and however...
plus showing more code and LogCat would help understanding your exact issue