Thursday, June 19, 2014

Navigation Drawer Icon in Action Bar without Using Drawer Layout

This post help us to get navigation drawer icon without android drawer layout in the Action Bar.

Enable action bar icon to support navigation drawer toggle.
// Set whether home should be displayed as an "up" affordance.
// Set this to true if selecting "home" returns up by a single level in your UI rather than back to the top level or front page.
getActionBar().setDisplayHomeAsUpEnabled(true);
//Enable or disable the "home" button in the corner of the action bar.
getActionBar().setHomeButtonEnabled(true);

We should be aware of navigation drawer before starting, navigation drawer helps user to bring the navigation drawer onto the screen by swiping from the left edge of the screen or by touching the application icon on the action bar.

On Tap of application icon, Navigation drawer opens by using DrawerLayout listeners, where ActionBarDrawerToggle supports us from toggling the drawer.

This class provides a handy way to tie together the functionality of DrawerLayout and the framework ActionBar to implement the recommended design for navigation drawers.

ActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, int drawerImageRes, int openDrawerContentDescRes, int closeDrawerContentDescRes)

Construct a new ActionBarDrawerToggle.
The given Activity will be linked to the specified DrawerLayout. The provided drawer indicator drawable will animate slightly off-screen as the drawer is opened, indicating that in the open state the drawer will move off-screen when pressed and in the closed state the drawer will move on-screen when pressed.
String resources must be provided to describe the open/close drawer actions for accessibility services.
Parameters

activity The Activity hosting the drawer
drawerLayout The DrawerLayout to link to the given Activity's ActionBar
drawerImageRes A Drawable resource to use as the drawer indicator
openDrawerContentDescRes A String resource to describe the "open drawer" action for accessibility
closeDrawerContentDescRes A String resource to describe the "close drawer" action for accessibility

The third parameter is the drawable which we are seeing beside the action bar icon.

Now the question, How can we update the navigation drawer icon without DrawerLayout?

Just call updateNavigationDrawerIcon method after enabling the action bar methods.

public void updateNavigationDrawerIcon(Drawable drawable) {
Method setHomeAsUpIndicator;
           try {
           setHomeAsUpIndicator = ActionBar.class.getDeclaredMethod("setHomeAsUpIndicator",            Drawable.class);
           setHomeAsUpIndicator.invoke(getActionBar(), drawable);
           } catch (NoSuchMethodException e) {
                      Log.e("CHECK", "No Such Method");
                      View home = findViewById(android.R.id.home);
                      ViewGroup parent = (ViewGroup) home.getParent();
                      int childCount = parent.getChildCount();
                      if (childCount == 2) {
                                final View first = parent.getChildAt(0);
                                final View second = parent.getChildAt(1);
                               final View up = first.getId() == android.R.id.home ? second : first;
                                 ((ImageView) up).setImageDrawable(drawable);
                      }
           } catch (Exception e) {
           e.printStackTrace();
           }
}

On click of app icon, we will be invoking onOptionsItemSelected method.

@Override
public boolean onOptionsItemSelected(MenuItem item) {

           switch (item.getItemId()) {
           case android.R.id.home:
                      Log.d("CHECK", "Navigation Icon is selected");
                      // Use for slide from left to right
                      slide_me.toggleLeftDrawer();
                      break;
           }
           return super.onOptionsItemSelected(item);
}

Output:




Source Code
You can download the source code by Source Code Click Here.  This project is built using eclipse IDE. Unzip and import the project into Eclipse, it’s a good idea to use the Project by clean and rebuild from the project menu. It works in all API levels above 14.

Thanks for reading :) 
Whether this post is helpful?

Have something to add to this post? If you have any other quick thoughts/hints that you think people will find useful? Share it in the comments.

Thursday, June 5, 2014

Android Immersive Mode for Dialog

This post is going to be discussed about the problem of Immersive Mode for Dialog.

Before going to the details we need to know about Immersive Mode and the usage?

Everyone knows andorid came up with KitKat 4.4 version and it bought new features and improvements.

Such in case, Immersive mode is one among them, which allows developers to take advantage of full screen from edge to edge on phones and tablets, hiding all system UI such as the status bar and navigation bar.

To make sure that users always have easy, consistent access to system UI from full-screen immersive mode, Android 4.4 supports a new gesture — in immersive mode, an edge swipe from the top or bottom of the screen now reveals the system UI.

To return to immersive mode, users can touch the screen outside of the bar bounds or wait for a short period for the bars to auto-hide. For a consistent user experience, the new gesture also works with previous methods of hiding the status bar.

How to Use the Immersive Mode?

// This snippet hides the system bars.
private void hideSystemUI() {
    // Set the IMMERSIVE flag.
    // Set the content to appear under the system bars so that the content
    // doesn't resize when the system bars hide and show.
    mDecorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
            | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
            | View.SYSTEM_UI_FLAG_IMMERSIVE);
}
Origin Code Snippet: Immersive Training Material

Before setting the View Flags, know about them.

Flag
Impact
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
Action bar is hidden
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
Hides Navigation Bar
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN   
Hides Status Bar


Coming to the Problem:

When we use Spinner, Alert Dialog, and Dialog and … Immersive mode is not working.
For more Information visit the link Android Issue regrading Immersive Mode

Why this Problem is Occurring for Dialog and so on...?

Each Dialog, Alert Dialog, Spinners are having their own window and it is not accessing application window.

So the flags which we are used for application window is not impacting the Dialog, Alert Dialog window.

How to Solve this Issue for Dialog Box?

Here we should know about the FLAG_NOT_FOCUSABLE flag, which helps us in solving the issue and then just add the same Immersive Flags to the Dialog, it works as we expect.

Setting this flag implies that the window will not need to interact with a soft input methodSo, Once the dialog is created and shown then clear the flag, otherwise we can’t get access to the Navigation Bar UI keys like back, home and etc..

Look at the snippet:

final Dialog dialog = new Dialog(v.getContext());
dialog.setCanceledOnTouchOutside(false);

dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);

dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

dialog.getWindow().getDecorView().setSystemUiVisibility(
          View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
          | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
      | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
      | View.SYSTEM_UI_FLAG_FULLSCREEN
      | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
      | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);

dialog.setContentView(R.layout.dialog_custom);
dialog.setTitle("Immersive Mode Dialog");

dialog.findViewById(R.id.dialogBtnYes).setOnClickListener(new OnClickListener() {
          @Override
      public void onClick(View v) {
          dialog.dismiss();
           }
          });

dialog.findViewById(R.id.dialogBtnNo).setOnClickListener(new OnClickListener() {
          @Override
      public void onClick(View v) {
          dialog.dismiss();
            }
          });

dialog.show();

dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);


Now check the dialog box, how it appears...


Happy Coding.. :) 

Screen shot:





Source Code
You can download the source code by clicking here: Source.  This project is built using eclipse IDE. Unzip and import the project into Eclipse, it’s a good idea to use the Project by clean and rebuild from the project menu. It works from API level 19.

Thanks for reading :) 
Whether this post is helpful?

Have something to add to this post? If you have any other quick thoughts/hints that you think people will find useful? feedback's are welcome...