1

I want to set status bar color in my custom DrawerLayout like default navigation drawee. It work perfectly but DraweeLayout should be behind status bar and status bar color should be custom. Below is my v21\style.

<resources>
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="android:statusBarColor">@color/orange</item>
</style>

Here is activity_main.xml

    <android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="false">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="vertical"
        >
        <android.support.v7.widget.Toolbar
            android:id="@+id/my_awesome_toolbar"
            android:layout_height="80dp"
            android:layout_width="match_parent"
            android:minHeight="?attr/actionBarSize"
            android:background="@color/orange"
            android:fitsSystemWindows="true"
            />
    </LinearLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="50dp">

        <LinearLayout
            android:id="@+id/llFirst"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="@color/orange"
            android:layout_marginTop="25dp"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/imgMenu"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_gravity="center"
                android:src="@drawable/menu" />
        </LinearLayout>
    </FrameLayout>

    <ExpandableListView
        android:id="@+id/lvLeft"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="@color/white"
        android:choiceMode="singleChoice"
        android:dividerHeight="0dp"
        />    
</android.support.v4.widget.DrawerLayout>

Here is my MainActivity.

    public class MainActivity extends Activity implements View.OnClickListener, ExpandableListView.OnChildClickListener {

    private MyAdapter drawerLayoutAdapter;
    private DrawerLayout drawer_layout;
    private ImageView imgMenu;
    private ArrayList<String> alTemp;
    private ArrayList<MyModel> arrayList;
    private ExpandableListView expandbleLis;

    private Activity activity;

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setId();
        setListner();
        setSliderColor();
        slideMenu();
        loadArraylist();
        drawerLayoutAdapter = new MyAdapter(MainActivity.this, arrayList);
        expandbleLis.setAdapter(drawerLayoutAdapter);
        expandbleLis.setOnChildClickListener(this);
    }

    private void setListner()
    {
        imgMenu.setOnClickListener(this);

        // it is used to close all child view on expandable listview and show only one childview at a time.
        expandbleLis.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
            int previousGroup = -1;

            @Override
            public void onGroupExpand(int groupPosition) {
                if(groupPosition != previousGroup)
                    expandbleLis.collapseGroup(previousGroup);
                previousGroup = groupPosition;
            }
        });
    }
    private void loadArraylist()
    {

        arrayList = new ArrayList<MyModel>();
        alTemp = new ArrayList<>();

        //here we have pur zero position blank because on zero position we will be put profile picture layout.
        arrayList.add(new MyModel("", 0, alTemp));

        alTemp = new ArrayList<>();
        alTemp.add("My Profile");
        arrayList.add(new MyModel("Profile", R.drawable.profile, alTemp));

        alTemp = new ArrayList<>();
        alTemp.add("My Transaction");

        arrayList.add(new MyModel("Transaction History", R.drawable.transaction, alTemp));

        alTemp = new ArrayList<>();
        alTemp.add("My Setting");
        arrayList.add(new MyModel("Setting", R.drawable.setting, alTemp));

        alTemp = new ArrayList<>();
        alTemp.add("Logout");
        arrayList.add(new MyModel("Log out", R.drawable.logout, alTemp));
    }


    private void slideMenu()
    {
        try
        {
            DrawerLayout.LayoutParams layoutParams = (DrawerLayout.LayoutParams) expandbleLis.getLayoutParams();
            expandbleLis.setLayoutParams(layoutParams);
            expandbleLis.setAdapter(drawerLayoutAdapter);

            if (drawer_layout.isDrawerOpen(expandbleLis))
            {
                drawer_layout.closeDrawer(expandbleLis);
            }

            expandbleLis.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, final int pos, long id)
                {
                    drawer_layout.setDrawerListener(new DrawerLayout.SimpleDrawerListener() {
                        @Override
                        public void onDrawerClosed(View drawerView)
                        {
                            super.onDrawerClosed(drawerView);

                        }
                    });
                    drawer_layout.closeDrawer(expandbleLis);
                    displayView(pos);
                }
            });
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    private void displayView(final int positionTitle)
    {
        try
        {
            closeDrawer();
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run()
                {
                    switch (positionTitle)
                    {
                        case 0:
                            break;

                        case 1:
                            break;

                        case 2:
                            break;
                    }
                }
            }, 200);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    private void setId()
    {
        try
        {
            drawer_layout = (DrawerLayout) findViewById(R.id.drawer_layout);
            imgMenu = (ImageView) findViewById(R.id.imgMenu);

            // below is for expandable listview.
            expandbleLis = (ExpandableListView) findViewById(R.id.lvLeft);
            expandbleLis.setDividerHeight(1);
            expandbleLis.setGroupIndicator(null);   // it is used to hide expandable list symbol.
            expandbleLis.setClickable(true);

        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }


    public void openDrawer()
    {
        try
        {
            expandbleLis.invalidateViews();
            drawer_layout.openDrawer(expandbleLis);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    private void closeDrawer()
    {
        try
        {
            if (drawer_layout.isDrawerOpen(expandbleLis))
            {
                drawer_layout.closeDrawer(expandbleLis);
            }
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }


    @Override
    public void onClick(View v)
    {
        switch (v.getId())
        {
            case R.id.imgMenu:

                openDrawer();

                break;
        }
    }

    @Override
    public boolean onChildClick(ExpandableListView parent, View v,
                                int groupPosition, int childPosition, long id)
    {
        Toast.makeText(MainActivity.this, "Clicked On Child",
                Toast.LENGTH_SHORT).show();
        return true;
    }
}

Actually I want to implement custom Drawer layout in which status bar color should be custom as well as Drawer layout should be behind of status bar which will semi transparent. Here I have attach picture and I want to implement as same. I have try almost every solution but not get any proper result so please help me to solve such issue. Thanks in advance. enter image description here

Mohd Sakib Syed
  • 1,679
  • 1
  • 25
  • 42

2 Answers2

2

I think you are looking for ScrimInsetsFrameLayout.

Here is Custom ScrimInsetsFrameLayout class with which you can implement this kind of behaviour

ScrimInsetsFrameLayout.java

public class ScrimInsetsFrameLayout extends FrameLayout {
    private Drawable mInsetForeground;

    private Rect mInsets;
    private Rect mTempRect = new Rect();
    private OnInsetsCallback mOnInsetsCallback;

    public ScrimInsetsFrameLayout(Context context) {
        super(context);
        init(context, null, 0);
    }

    public ScrimInsetsFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public ScrimInsetsFrameLayout(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        final TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.ScrimInsetsView, defStyle, 0);
        if (a == null) {
            return;
        }
        mInsetForeground = a
                .getDrawable(R.styleable.ScrimInsetsView_insetForeground1);
        a.recycle();

        setWillNotDraw(true);
    }

    @Override
    protected boolean fitSystemWindows(Rect insets) {
        mInsets = new Rect(insets);
        setWillNotDraw(mInsetForeground == null);
        ViewCompat.postInvalidateOnAnimation(this);
        if (mOnInsetsCallback != null) {
            mOnInsetsCallback.onInsetsChanged(insets);
        }
        return true; // consume insets
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);

        int width = getWidth();
        int height = getHeight();
        if (mInsets != null && mInsetForeground != null) {
            int sc = canvas.save();
            canvas.translate(getScrollX(), getScrollY());

            // Top
            mTempRect.set(0, 0, width, mInsets.top);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Bottom
            mTempRect.set(0, height - mInsets.bottom, width, height);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Left
            mTempRect
                    .set(0, mInsets.top, mInsets.left, height - mInsets.bottom);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Right
            mTempRect.set(width - mInsets.right, mInsets.top, width, height
                    - mInsets.bottom);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            canvas.restoreToCount(sc);
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (mInsetForeground != null) {
            mInsetForeground.setCallback(this);
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mInsetForeground != null) {
            mInsetForeground.setCallback(null);
        }
    }

    public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
        mOnInsetsCallback = onInsetsCallback;
    }

    public static interface OnInsetsCallback {
        public void onInsetsChanged(Rect insets);
    }
}

Now Regarding Use of this class.

-> activity_main.xml

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true" >

    <RelativeLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true" >

        <include
            android:id="@+id/toolbar_headers"
            layout="@layout/toolbar_header"
            android:visibility="invisible" />
    </RelativeLayout>

    <yourpackagename.ScrimInsetsFrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:layout_marginRight="-8dp"
        android:elevation="8dp"
        android:fitsSystemWindows="true"
        app:insetForeground1="#4000" >

        <!-- this would be your custom drawer layout -->
        <include
            android:id="@+id/drawar_layout"
            layout="@layout/drawar_layout" />
    </bhagyagold.com.extraclasses.ScrimInsetsFrameLayout>

</android.support.v4.widget.DrawerLayout>

here impotent tag is android:fitsSystemWindows check this in all views carefully.

-> java part

finally open or close your drawer with this layout.

for e.g

mLayout = (ScrimInsetsFrameLayout) findViewById(R.id.container);
mDrawerLayout.closeDrawer(mLayout);

-> styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light">
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">colorPrimaryDark</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
        <item name="android:windowContentTransitions">true</item>
        <item name="android:windowAllowEnterTransitionOverlap">true</item>
        <item name="android:windowAllowReturnTransitionOverlap">true</item>
        <item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
        <item name="android:windowSharedElementExitTransition">@android:transition/move</item>
        <item name="windowNoTitle">true</item>
    </style>

EDIT :

-> attrs.xml

<resources>

    <declare-styleable name="ScrimInsetsView">
        <attr name="insetForeground1" format="reference|color" />
    </declare-styleable>

</resources>

Happy coding..

V-rund Puro-hit
  • 5,518
  • 9
  • 31
  • 50
  • Hello Mr Purohit, Thanks for help me but In `ScrimInsetsFrameLayout` class is not working properly show error in 40th line [like](https://drive.google.com/a/ifuturz.com/file/d/0B0OXBbfffzFRSE54RUJFY0t3Tmc/view?usp=sharing). Please let me know how to fix such issue. – Mohd Sakib Syed May 25 '16 at 06:39
  • 1
    Thanks Mr. Purohit, It is working fine. You save my time and solve my problem..Thanks you so much my brother.. – Mohd Sakib Syed May 25 '16 at 07:02
0
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/statusbar_color</item>
    <item name="colorPrimaryDark">@color/statusbar_color</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

Add that code in your style.XML and then apply in your manifiest in application tag set that theam like . ..

 android:theme="@style/AppTheme"
Akshay More
  • 359
  • 2
  • 13
  • @Akshay....Thanks for help me, I have tried your solution but `DrawerLayout` display below `status bar`. I want to show `status bar` semi transparent like attached image and `DrawerLayout` should be show behind `status bar`. – Mohd Sakib Syed May 25 '16 at 05:49
  • 1
    @Sakib. . Please check this link http://stackoverflow.com/questions/26913770/make-navigation-drawer-draw-behind-status-bar – Akshay More May 25 '16 at 05:57