OnCheckedChangeListener not invoked immediately - android

I have a switch within a menu that is show as an action on the action bar. The onCheckedChangeListener is not being invoked immediately after when I set the checked property to true. The switch does show up in the action bar, and every time it is pressed it the checkedchangelistener is invoked. However, it is not invoked in the beginning when it should be. How is this possible? Why is it not invoked? How do I fix this?
Here is the onCreateMenuOptionsMenu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.i(TAG, "onCreateOptionsMenu()");
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mainmenu, menu);
serviceSwitch = (Switch) menu.findItem(R.id.Switch).getActionView().findViewById(R.id.switchid);
serviceSwitch.setOnCheckedChangeListener(mCheckedChangeListener);
serviceSwitch.setChecked(false);
//OnCheckedChange is not being called here. I have set a breakpoint at the method.
//I have also looked at the log - nothing.
//It is being called when I click the switch however.
return true;
}
private OnCheckedChangeListener mCheckedChangeListener = new OnCheckedChangeListener(){
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.i(TAG, isChecked ? "true" : "false";
}
}
Here is the xml:
R.menu.mainmenu
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:title=""
android:id="#+id/Switch"
android:actionLayout="#layout/switch_layout"
android:showAsAction="always"></item>
</menu>
R.layout.switch_layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Switch
android:id="#+id/switchid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:paddingRight="20dp"
android:paddingLeft="20dp"
android:textOff="Off"
android:textOn="On"
android:checked="true"/>
</RelativeLayout>

R.layout.switch_layout
Switch checked value is already true in your layout file.
android:checked="true"
so when set its value to true its checked change listener is not called.
Hope you get my point.

Related

TextView in menu is always null after orientation change

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().

Add/remove item menu menuItem dynamically

I have a problem, I want to add item in a toolbar (material design) programatically .
This is a my menu :
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
<item android:id="#+id/action_settings" android:title="#string/action_settings"
android:orderInCategory="100" android:showAsAction="never" />
</menu>
I know change text , color , background, and #override listener
toolbar.setBackgroundColor
toolbar.setTextColor
toolbar.setNavigationIcon
toolbar.setText
I don't know how I can add a menu ítem with a category " android:orderInCategory="300"
Thanks.
Note : I have all fragment, without 1 Activity
Tree - > Activity - > Fragment1(here add menu item) - > Fragment2(add/remove menu item) - > Fragmentx ..
Try this Toolbar has option getMenu() which return menu
private static final String placeholder1="Something";
private static final int FIRST_ID=Menu.FIRST;
private static final int SECOND_ID=Menu.FIRST+1;
//To add an item
toolbar.getMenu().add(Menu.NONE,FIRST_ID,Menu.NONE,R.string.placeholder1);
toolbar.getMenu().add(Menu.NONE,SECOND_ID,Menu.NONE,R.string.placeholder2);
//and to remove a element just remove it with id
toolbar.getMenu().removeItem(FIRST_ID);
First of all put the item you want to display/hide in your xml file.
Let's say it's "action_settings" as mentioned in your code, override the "onCreateOptionsMenu"
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.your_menu, menu);
MenuItem item = menu.findItem(R.id.action_settings);
if (yourConditionToShow) {
item.setVisible(true);
} else {
item.setVisible(false);
}
return true;
}
If you do not have access to the toolbar, you can do the following:
1 - Add the item to the menu through onCreateOptionsMenu():
public boolean onCreateOptionsMenu(Menu menu){
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.my_item_id, menu);
return true;
}
2 - Create a boolean equal to true if the item must be visible
3 - Hide or show the item according to the value of your boolean in onPrepareOptionsMenu()
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem mi = menu.findItem(R.id.my_item_id);
if(displayItem)
mi.setVisible(true);
else
mi.setVisible(false);
return super.onPrepareOptionsMenu(menu);
}
In your onCreateOptionmenu, try this code
//menu.add("groupId", "ItemId", "OrderID", "title")
MenuItem item = menu.add(1, 100, 300, "Settings");
item.setIcon(R.drawable.ic_launcher);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
you can also add setting like xml. You can check by itemid("100") in onOptionsItemSelected.
If you don't want to use 100 as ItemId, you can create ids resource file. And can use like this,
//R.id.action_settings is from ids resource file
MenuItem item = menu.add(1, R.id.action_settings, 300, "Settings");
1 Solution :
#Chitrang Thanks to idea, I solved with this line :
toolbar.inflateMenu(R.menu.menu_activity1);
toolbar.inflateMenu(R.menu.menu_activity2);
toolbar.inflateMenu(R.menu.menu_activityx);
Options select R.menu.item1,2,x
2 Solution :
Create custom toolbar : into "android.support.v7.widget.Toolbar" and can you managment all icons.
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"></LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Toolbar Title"
android:layout_gravity="center"
android:id="#+id/toolbar_title" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="right"
android:layout_marginRight="15dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="24dp"
android:id="#+id/imageView10"
android:src="#drawable/sun"
android:adjustViewBounds="true" />
</LinearLayout>
</LinearLayout>
In your menu XML file, you can add a menu item not visible (android:visible=false) and render visible when you want.

OnOptionsItemSelected not being called for Action Bar Menu Item with custom actionLayout

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.

Show copy/paste context menu on text using code android

I have an EditText and its text gets selected from through code. But I want to allow users to cut/copy the selected text. However, the cut/copy context menu doesn't appear until user long presses on text. But then it loses the actual selection. So, I'm thinking to show the context menu as the text get selected by the code.
I tried this inside onFocusChanged, but nothing appeared.
openContextMenu(EditText);
IF I follow you usecase correctly, you can open context menu from the onFocusChangeListener registered on the testedEditText.
I prepared some small test for that which seems to be correctly supporting your usecase.
You need to openMenu on the hooks which are selecting the content in the EditText.
public class Main extends Activity {
private EditText testedEditText;
private Button selectingButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
selectingButton = (Button) findViewById(R.id.button);
testedEditText = (EditText) findViewById(R.id.textView);
registerForContextMenu(testedEditText);
selectingButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
testedEditText.setSelection(6, 11);
openContextMenu(testedEditText);
}
});
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.cmenu, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.select_all:
return true;
case R.id.copy:
//do something
return true;
case R.id.cut:
//do something
return true;
case R.id.paste:
//do something
return true;
default:
return super.onContextItemSelected(item);
}
}
}
Weirdly enough registering testedEditText.requestFocus(), and setting onFocusChangedListener for EditText was not enough.
Additional xml files for reference:
cmenu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/select_all"
android:title="select all"
/>
<item android:id="#+id/copy"
android:title="copy"
/>
<item android:id="#+id/cut"
android:title="cut"
/>
<item android:id="#+id/paste"
android:title="paste"
/>
</menu>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World, Initial Text..."
android:layout_centerInParent="true"
/>
<Button android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="button"
/>
</RelativeLayout>

onOptionsItemSelected() not called when clicking on menu item which has an actionLayout set on it

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);
}

Categories

Resources