Closing an Android Popup Menu - java

I am attempting to use a popup menu that uses the view of a dynamically added EditText box.
When I do not create the new popup menu inside the onTouch method, the popup closes as expected but, I could not figure out a way to use the view of the touched EditText this way. Instead the popup would show up in the view of the last added EditText.
View.OnTouchListener subjectListener(final EditText editText) {
return new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
popupMenu = new PopupMenu(MainActivity.this, editText);
popupMenu.getMenu().add("works");
popupMenu.show();
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
popupMenu.getMenu().close();
list.get((Integer) editText.getTag()).setText(item.getTitle());
return true;
}
});
return false;
}
};
}
With this code the popup menu shows up exactly where I want it too except it does not close unless I touch another EditText a few times. Which makes me think I am creating multiple popup menu's behind each other or something.
Any ideas?

popupmenu.dismiss();
You can use this to close popup

Related

How to trigger an event when user clicks away from EditText?

I am building an app, and I want the app to trigger an event when the user has entered text into the editText and clicks away from it or closes the keyboard? How can I do this?
I am not very skilled in Java, so I would be grateful if you provided some description or code.
You can use onFocusChange listener on your edit text to overcome this problem
yourEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
if(b==true){
//entered in the edit text
}
else {
//left edit text
}
}
});
Simply set an onFocusChangedListener on your EditText and configure what happens when the EditText loses focus. Here's an illustration:
mEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean bool) {
if(bool){
// here, the EditText is in focus
}
else {
//here, the EditText is no longer in focus.
// do what you want to do
}
}
});
I hope this helps.

How to create navigation view open on condition?

First of all, I have two navigation view for both sides in android as shown in this Image. Left side for user who signup as parents meanwhile the right side for the user who signup as a tuition provider. For example, if User A signs up as a parent, so he/she can only open the left side navigation ONLY. I have made some studies, mostly using radio button/radio group. Unfortunately, I have to use the spinner, what coding should I write to ensure the navigation view can be opened for certain users. For your information, I have 3 activity.
1) User.Java wherein coding, I have coding initialize, constructor and getter.
2) RegistrationActivity.Java where I put all the spinner coding.
//USER TYPE SPINNER
List<String> categories = new ArrayList<>();
categories.add(0, "Choose Category");
categories.add("Parents");
categories.add("Tuition Provider");
ArrayAdapter<String> dataAdapter;
dataAdapter = new ArrayAdapter(this,android.R.layout.simple_spinner_item, categories);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
RegisterUserType.setAdapter(dataAdapter);
RegisterUserType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
if(position==0)
{
//Toast.makeText(getApplicationContext(),"No Item Selected",Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(),parent.getItemAtPosition(position) +" Selected",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
3) Home.Java where I put all my navigation view coding.
menuLeft = (ImageButton) findViewById(R.id.menu_left);
menuRight = (ImageButton) findViewById(R.id.menu_right);
parentsNavigation = findViewById(R.id.nav_view);
tuitionProviderNavigation = findViewById(R.id.nav_view2);
menuLeft.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if (drawerLayout.isDrawerOpen(GravityCompat.START))
{
drawerLayout.closeDrawer(GravityCompat.START);
}
else
{
drawerLayout.openDrawer(GravityCompat.START);
}
}
});
menuRight.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if (drawerLayout.isDrawerOpen(GravityCompat.END))
{
drawerLayout.closeDrawer(GravityCompat.END);
}
else
{
drawerLayout.openDrawer(GravityCompat.END);
}
}
});
parentsNavigation.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener()
{
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item)
{
UserMenuSelector(item);
return false;
}
});
tuitionProviderNavigation.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener()
{
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item)
{
UserMenuSelector(item);
return false;
}
});
I can not paste all my coding here because it is too long but I can email you to better understand my XML layout.
All you have to do is lock the drawer that you want to Disable and unlock again if you want to Enable it
use drawerLayout.setDrawerLockMode();
in your case below code will close your one drawer that have gravity start
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, GravityCompat.START);
and when you want to unlock again then simply
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, GravityCompat.START);
Remember one more thing
drawerLayout.setDrawerLockMode() allows the application to restrict the user's ability to open or close the given drawer (cannot open via sliding) but DrawerLayout will still respond to calls to openDrawer(), closeDrawer()
so in your case you also consider disabling the ImageView click because they have these methods
In Your Case
when user will click on a spinner item you check if(position==1)
if this condition true you know it's a parent
so do this in your Home.Java
do this
if(parent==true){
//this will disable right drawer
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, GravityCompat.END);
//and this will enable left drawer
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, GravityCompat.START);
//and also do to disable right ImageView
menuRight.setEnabled(false);
//and also do to enable left ImageView
menuLeft.setEnabled(true);}
now for tuition provider do same but this time enable right and disable left,
also same for menu button.

Make EditText pass focus back to parent layout when finished editing.

I have a linear layout in a fragment with a bunch of checkboxes and various edittext widgets inside it. Basically like a quiz. A bunch of multiple choice(checkboxes) and a dozen short answer(edittexts) questions.
What I would like is for users to be able to click an edittext, type in an answer, then press DONE or click anywhere else on the layout and have the widget lose focus and the keyboard hide. Currently I am overriding the setOnEditorActionListener and setOnFocusChangeListener methods of each edittext to give focus back to a main layout, and hide the keyboard respectively. Here is the code for an edittext instance called "input_7d":
final EditText input_7d = (EditText) thisview.findViewById(R.id.txtinput_7d);
final LinearLayout parentLayout = (LinearLayout) thisview.findViewById(R.id.main_layout);
input_7d.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_ACTION_DONE) {
parentLayout.requestFocus();
}
return false;
}
});
input_7d.setOnFocusChangeListener(new TextView.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus){
InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(parentLayout.getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
}
}
});
This is annoying to do for every edittext I add, and it means editing lots of code if I remove them or add more in the future. What I would like to do is have a custom edittext class that can return focus to it's parent view/layout and hide the keyboard, then use that instead of the built in edittext. I'm very new to this and I haven't been able to find a way for a custom edittext to pass focus back to it's parent layout. Is there a better way to get a bunch of edittexts to all have this behavior and not have it all "hardcoded" into my fragment class?
So I could not find a way to have a edittext pass focus back to it's parent layout from inside the view itself. So instead I have opted to just disable focusable property of it when it
1) It loses focus (user clicked outside the view on something focusable, ie. The parent layout)
2) Finishes it's edit(user presses Done action on soft keyboard)
Surprisingly neither of these actions by default remove focus and the cursor from a default editText. At least not inside my scroll views.
So I added these lines to a custom view(myEditText) that extends the editText view:
this.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_ACTION_DONE) {
myEditText.setFocusable(false);
myEditText.setFocusableInTouchMode(false);
}
return false;
}
});
this.setOnFocusChangeListener(new TextView.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus){
myEditText.setFocusable(false);
myEditText.setFocusableInTouchMode(false);
hideKeyboardFrom(context, v);
}
}
});
this.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
myEditText.setFocusableInTouchMode(true);
myEditText.setFocusable(true);
return false;
}
});
I find it really annoying that to get simple functionality like not having the cursor blinking at me always or having the view not take focus when changing fragments and such you have to do such a weird workaround. Making a view unfocusable unless it's focused in which case it is focusable but only until it isn't focused again just seems dumb. Still wondering if there is a better way to do this for a large number of edits in one layout.
you can set a touch listener for the root layout and then remove the focus whenever not needed for the view
findViewById(R.id.rootView).setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
v.requestFocusFromTouch() //check for y
return false;
}
});

Not propagating clicks

When I click an Android button the Android's Software Keys are shown (hidden before) instead of firing the onClick() method for the actual button that I click.
I have two methods for showing or hiding the system UI:
1.
// Set up the user interaction to manually show or hide the system UI.
contentView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (TOGGLE_ON_CLICK) {
mSystemUiHider.toggle();
} else {
mSystemUiHider.show();
}
}
});
and 2:
/**
* Touch listener to use for in-layout UI controls to delay hiding the
* system UI. This is to prevent the jarring behavior of controls going away
* while interacting with activity UI.
*/
View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (AUTO_HIDE) {
delayedHide(AUTO_HIDE_DELAY_MILLIS);
}
return false;
}
};
And I also have another method which a switch to get the onClick() event on buttons
public void onClick(View v) { switch() { } }
Is it possible to fix this behaviour and when I click the actual button will be fired and the System UI will be shown?
There is no workaround to overcome this behaviour until you have both touch listener and also a click listener inside the same view. Try using
View.SYSTEM_UI_FLAG_LOW_PROFILE|View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
instead. Add the below code before setcontentview() method.
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFILE|View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);

Is there a way to use setOnClickListener with an Android Spinner?

The java.lang.RuntimeException is "Don't call setOnClickListener for an AdapterView. You probably want setOnItemClickListener instead," but that is not correct. I am using setOnItemClickListener to do some stuff based on the new selection, but I also need to do some stuff before the user changes the selection. Specifically, I am collecting data for each selection that needs to be saved to a file before moving to another selection, since the other selection is associated with different set of data. Is there a way to use setOnClickListener with an Android Spinner?
spinner.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Do some stuff before the user changes the selection
...
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
// Do some stuff based onItemSelected
...
You can replicate the an onclick event using ontouch events
this.spinner=(Spinner)findViewById(R.id.spinner);
this.spinner.setClickable(false);
this.spinner.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.v(TAG, "spinner touch");
//replicating a click
if(event.getAction() == MotionEvent.ACTION_UP){
v.playSoundEffect(android.view.SoundEffectConstants.CLICK);
}
return true;
}
});
You will have to set the Click listener on the underlying view (normally a TextView with id: android.R.id.text1) of the spinner. To do so:
Create a custom Spinner
In the constructor (with attributes) create the spinner by supplying the layout android.R.layout.simple_spinner_item
Do a findViewById(android.R.id.text1) to get the TextView
Now set the onClickListener to the TextView

Categories

Resources