How to create navigation view open on condition? - java

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.

Related

Android Studio local variable says Unreachable statement Error

So i have a problem with my local variable it says Unreachable statement.
This is the line of code i get the error (" View textViewOptions; ") i cant even run the app
private View findViewById(int position) {
View view = findViewById(R.id.textViewOptions);
return view;
View textViewOptions;
textViewOptions.setOnClickListener(new View.OnClickListener() {
ViewHolder holder;
public void onClick(View view) {
//creating a popup menu
PopupMenu popup = new PopupMenu(context, holder.textViewOptions);
//inflating menu from xml resource
popup.inflate(R.menu.chatmenu);
//adding click listener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.BlockUser:
//handle menu1 click
return true;
case R.id.MuteNotificationsCH:
//handle menu2 click
return true;
default:
return false;
}
}
});
popup.show();
}
});
}
As mentioned in commnets, return keyword is used to exit the method. From there onwards execution will stop. So the code below return statement will not be executed and hence will become unreachable.
So put return view; as the last statement of the method

How to maintain backstack of fragment in Navigation Drawer?

I have taken one activity and with activity I have attached navigation drawer and the home fragment. In that navigation drawer there is a option of "Contact Us". When user click on that option a fragment gets open. But I am not able to maintain the stack of that. means when I am on contact us fragment then using navigation drawer again click on contact us it overlaps previous one. I have to press back button 2 times to go on home fragment. Please Help me how to maintain back stack for this. Here is my code..
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.rate:
Uri uri = Uri.parse("market://details?id=" + getPackageName());
Intent myAppLinkToMarket = new Intent(Intent.ACTION_VIEW, uri);
try {
startActivity(myAppLinkToMarket);
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), "Unable to find source market app!", Toast.LENGTH_SHORT).show();
}
break;
case R.id.contact_us:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.fragment_container_dashboard, ContactUsFragment.newInstance());
transaction.addToBackStack(null);
transaction.commit();
mDrawerLayout.closeDrawer(GravityCompat.START);
break;
}
return false;
}
});
After this code I use this to maintain back stack:
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() != 0) {
getFragmentManager().popBackStack();
}
else new AlertDialog.Builder(this)
.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Dashboard.super.onBackPressed();
}
})
.setNegativeButton("No", null)
.show();
}
But the issue is It's show exit dialogue on contact us fragment when ever I press back button. But I want firstly I reach to home fragment and after that If I press back button then it show exit dialogue.
I solved this by adding this in the onCreate method.
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if(getSupportFragmentManager().getBackStackEntryCount() == 0){
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
menuToggle.setDrawerIndicatorEnabled(true);
// your dialog
}else{
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
menuToggle.setDrawerIndicatorEnabled(false);
// remove to your previous fragment
}
}
});

Android when fragment is removed

I have a FrameLayout and put there some fragments by click on button, next click should remove fragment from FrameLayout, I do this by removeAllViews() (FrameLayout is in another Fragment so translaction method is in Activity).
I need to do some action when removeAllViews() starts and have to do it in Fragment class but something goes wrong.
I tried:
OnDestroy()
OnDestroyView()
OnPause()
in Fragment class
but it works like:
put Fragment in FrameLayout (from Activity)
use removeAllViews() (from Activity)
there is no Fragment in FrameLayout (is clear) but nothing else happens and methods are not working
put new Fragment in FrameLayout (from Activity) - now all methods (OnDestroy() from Fragment class) works (probably it's real time to destroy old fragment)
How is it possible to 'get moment' when Fragment is not exists for user? I want to send some information to server if user hides Fragment.
#Edit3
code from method from Activity where I want to make translaction
public void showProductsList(String productType,int containerID){
List<String> prodNames = new ArrayList<String>();
List<Long> prodIds = new ArrayList<Long>();
DatabaseDAOProdProtein dao = new DatabaseDAOProdProtein(getApplicationContext());
dao.open();
List<DatabaseProduct> productList = dao.getAllProducts();
for(int i=0;i<productList.size();i++){
prodNames.add(productList.get(i).getName());
prodIds.add(productList.get(i).getId());
}
dao.close();
ProductsList productsList = new ProductsList(productType,prodNames,prodIds);
productsList.setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int visibility) {
// Note that system bars will only be "visible" if none of the
// LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set.
Toast.makeText(getApplicationContext(),"action1 " ,Toast.LENGTH_LONG).show();
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
// TODO: The system bars are visible. Make any desired
// adjustments to your UI, such as showing the action bar or
// other navigational controls.
Toast.makeText(getApplicationContext(),"action2 " ,Toast.LENGTH_LONG).show();
} else {
// TODO: The system bars are NOT visible. Make any desired
// adjustments to your UI, such as hiding the action bar or
// other navigational controls.
Toast.makeText(getApplicationContext(),"action3 " ,Toast.LENGTH_LONG).show();
}
}
});
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(containerID, productsList).commit();
}
I used this method in another Fragment by:
((MainActivity) getContext()).showProductsList("carb", carbContainer.getId());
there is an error:
Error:(560, 21) error: cannot find symbol method setOnSystemUiVisibilityChangeListener(<anonymous OnSystemUiVisibilityChangeListener>)
You say:
"How is it possible to 'get moment' when Fragment is not exists for
user? I want to send some information to server if user hides
Fragment."
I now know you did not mean "hide", so just use the OnDestroy() method.
Try this to trigger the "hide"
View topLevelLayout = findViewById(R.id.top_layout);
topLevelLayout.setVisibility(View.INVISIBLE);
You cannot go into stopped state while Fragment (Activity) is visible. Android destroying activities, killing processes
The best way to make sure something runs via a view is to run it via a post:
topLevelLayout.post(new Runnable()
{
#Override
public void run()
{
topLevelLayout.removeAllViews();
}
}
To get notified of system UI visibility changes, register an View.OnSystemUiVisibilityChangeListener to your view (fragment).
https://developer.android.com/training/system-ui/visibility.html
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toast.makeText(getContext(),"action0 " ,Toast.LENGTH_LONG).show();
Fragment your_frag = new ProductsList(productType,prodNames,prodIds);
getSupportFragmentManager().beginTransaction().replace(containerID,your_frag).commit();
getSupportFragmentManager().executePendingTransactions();//make sure onCreateView has executed
your_frag.getRootView().setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int visibility) {
// Note that system bars will only be "visible" if none of the
// LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set.
Toast.makeText(getContext(),"action1 " ,Toast.LENGTH_LONG).show();
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
// TODO: The system bars are visible. Make any desired
// adjustments to your UI, such as showing the action bar or
// other navigational controls.
Toast.makeText(getContext(),"action2 " ,Toast.LENGTH_LONG).show();
} else {
// TODO: The system bars are NOT visible. Make any desired
// adjustments to your UI, such as hiding the action bar or
// other navigational controls.
Toast.makeText(getContext(),"action3 " ,Toast.LENGTH_LONG).show();
}
}
});
}
A typical fragment looks like this:
public class HomeFragment extends Fragment {
View mRootView = null;
public HomeFragment(){}//null constructor
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.fragment_home, container, false);
return mRootView ;
}
public View getRootView ()
{
return mRootView;
}
}

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

Add up button to PreferenceScreen

I can't figure out how I would go about implementing an up button in a PreferenceScreen. An up button displays a caret in your action bar next to your app icon that allows you to navigate the app's hierarchy, more info here.
I have a Preference Fragment that displays when my main activity is opened and I can get the up button to display by adding this line " getActionBar().setDisplayHomeAsUpEnabled(true);":
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setDisplayHomeAsUpEnabled(true);
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
This causes the up button to display in the Preference Fragment, but I only want to show the up button when one of my PreferenceScreens is opened, allowing navigation to the main PreferenceFragment.
My app is analogous to the main settings app. Only the child screens, like Location Access, that opens from the main Settings app has the up arrow.
From this question, I simply added these two code blocks to my Preference Fragment:
#Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
super.onPreferenceTreeClick(preferenceScreen, preference);
// If the user has clicked on a preference screen, set up the action bar
if (preference instanceof PreferenceScreen) {
initializeActionBar((PreferenceScreen) preference);
}
return false;
}
And this one:
/** Sets up the action bar for an {#link PreferenceScreen} */
public static void initializeActionBar(PreferenceScreen preferenceScreen) {
final Dialog dialog = preferenceScreen.getDialog();
if (dialog != null) {
// Inialize the action bar
dialog.getActionBar().setDisplayHomeAsUpEnabled(true);
// Apply custom home button area click listener to close the PreferenceScreen because PreferenceScreens are dialogs which swallow
// events instead of passing to the activity
// Related Issue: https://code.google.com/p/android/issues/detail?id=4611
View homeBtn = dialog.findViewById(android.R.id.home);
if (homeBtn != null) {
OnClickListener dismissDialogClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
};
// Prepare yourselves for some hacky programming
ViewParent homeBtnContainer = homeBtn.getParent();
// The home button is an ImageView inside a FrameLayout
if (homeBtnContainer instanceof FrameLayout) {
ViewGroup containerParent = (ViewGroup) homeBtnContainer.getParent();
if (containerParent instanceof LinearLayout) {
// This view also contains the title text, set the whole view as clickable
((LinearLayout) containerParent).setOnClickListener(dismissDialogClickListener);
} else {
// Just set it on the home button
((FrameLayout) homeBtnContainer).setOnClickListener(dismissDialogClickListener);
}
} else {
// The 'If all else fails' default case
homeBtn.setOnClickListener(dismissDialogClickListener);
}
}
}
}
If your complete application is a preferences screen, then you can make your main activity a PreferenceActivity and the sub-levels can be fragments. This way the 'up' functionality is going to be by default what you are looking for.
Have a look at this.
For the XML:
<Preference android:title="Acts like a button"
android:key="button"
android:summary="This will act like a button"/>
Then for the Java in your onCreate()
Preference button = (Preference)findPreference("button");
button.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference arg0) {
//code for what you want it to do
return true;
}
});

Categories

Resources