DrawerLayout on top of Actionbar - java

When using the drawer layout is there a way to overlay the drawer view over the action bar? I do not want to hide the action bar when the drawer is shown. I want the action bar to simply stay put, but be sent to the background. An example of this is the iOS Play Music app...
My current implementation hides and shows the action bar when the drawer state changes, but I do not like this user experience.
public void onDrawerClosed(View view) {
getActionBar().show();
invalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView) {
getActionBar().hide();
invalidateOptionsMenu();
}

I searched the web in order to find any good solution for this problem and haven't found. So I did a trick that did this.
First of all we need to request action bar overlay feature. So in onCreate() of your activity, before setContntView() call: requestWindowFeature(com.actionbarsherlock.view.Window.FEATURE_ACTION_BAR_OVERLAY);
It will make everything including navigation drawer draw behind action bar. We don't need this, so we need to set the top margin of our FrameLayout which hosts our fragments in the activity with the exact height of the action bar. In the layout file of the activity we need to do the following:
<!-- Framelayout to display Fragments -->
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize" />
It will make only navigation drawer appear behind the action bar.
Now we will hide the action bar when the navigation drawer is opened on half, and will show it when the drawer is nearly closed. To do this we need to make the following in the activity:
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
if(slideOffset > 0.5){
actionBar.setBackgroundDrawable(null);
actionBar.hide();
} else {
actionBar.show();
if(slideOffset < 0.1){
actionBar.setBackgroundDrawable(layerDrawable);
}
}
}
As you can see I also change the background drawable of the action bar to make it transparent when before I begin to hide it, and change it back with my custom background when I show it back.
My custom background is a layerListDrawable which is all transparent but have a divider in bottom with some shadow.
And to achieve this I have defined the following layer-list in XML:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="0dp" android:left="0dp" android:bottom="0dp" android:right="0dp">
<shape android:shape="rectangle">
<solid android:color="#android:color/transparent"/>
</shape>
</item>
<item android:top="0dp" android:left="0dp" android:bottom="0dp" android:right="0dp">
<shape android:shape="rectangle">
<solid android:color="#afafaf"/>
</shape>
</item>
<item android:top="0dp" android:left="0dp" android:bottom="0dp" android:right="0dp">
<shape android:shape="rectangle">
<gradient
android:angle="270"
android:startColor="#88afafaf"
android:endColor="#33afafaf"
/>
</shape>
</item>
</layer-list>
And to get the background I need from this XML I do the following in the activity:
final ActionBar actionBar = getSupportActionBar();
final LayerDrawable layerDrawable = (LayerDrawable) getResources()
.getDrawable(R.drawable.shadow_divider);
final TypedArray styledAttributes = getTheme().obtainStyledAttributes(
new int[] { R.attr.actionBarSize });
int topOffset = (int) (styledAttributes.getDimension(0, 0));
styledAttributes.recycle();
layerDrawable.setLayerInset(1, 0, topOffset - 3, 0, 2);
layerDrawable.setLayerInset(2, 0, topOffset - 2, 0, 0);
actionBar.setBackgroundDrawable(layerDrawable);
where R.drawable.shadow_divider is the XML layer-list I have defined earlier.
It looks really great! Hope it can help someone.
EDIT
I had a small bug here which can be a reason of a crush sometimes. Here is the fixed code:
`
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
**android:paddingTop="?attr/actionBarSize"** />`
It should be paddingTop not layout_marginTop!

That's the proper effect in Android defaults. If you want to emulate the iOS effect, you'll probably have to do it yourself, because AFAIK the drawer component of the support library doesn't allow such type of configurations.
Anyway, every time a programmer codes a lot just to emulate some fancy (and much probably not worthy) iOS effect in Android, a little cat dies...

I don't think you'll be able to do this with Android's provided Navigation Drawer (without doing something really hacky), since doing this really goes against Android design patterns. If you want a library that does what you're looking for, I've used this library before Android came out with it's own widget, and it does what you're looking for.

I found the answer in my question, also added an example project for reference. You can take a look to see if it works for you.
Android Navigation Drawer on top ActionBar

You can achieve this with ActionBarSherlock.
http://actionbarsherlock.com/

You will be able to do it but the drawer will look so awkward that you will not like it. I had the same requirement and I ended up using Radio Buttons customized to appear as tabs. You can also try hiding the tabs when the drawer opens and vice versa, but that certainly is not what you want here.
You can try to use ViewPager, tabbed indicator such PagerTabStrip and/or TabPageIndicator.
Source.

Related

Android toolbar replace colorPrimary with a full width background image in Task View or Recent Apps Screen

Hi I have a problem with my toolbar. I'm testing on a lollipop 5.1.1. I have tried:
How to add image in toolbar
This Setting header color of app in overview (recent apps) screen
takes the full width background image and squashes it into the icon.
The toolbar displays the correct background image when i am in the app (on Create or on Resume)
but if I am in on Pause, the default colorPrimary and mipmap icon show as below
I have tried all suggestions on Stackoverflow. I am beginning to think that truly one cannot customise the toolbar in taskView or the recent apps screen.
Does anyone know any unconventional way of having my background image in Task View (recent apps screen) and not the default colorPrimary with the default mipmap icon?
in onCreate, I tried doing the following as well:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
ActivityManager.TaskDescription td = new ActivityManager.TaskDescription("",bm,R.drawable.header);
setTaskDescription(td);
whereby header is a drawable xml file that has myImage in it:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/myImage" />
<item>
<shape android:shape="rectangle" android:padding="10dp">
<corners
android:bottomRightRadius="5dp"
android:bottomLeftRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp"/>
</shape>
</item>
</layer-list>
but get a crash with the warning that the primaryColor must be opaque.

How to change the selected item's background color in android navigation drawer?

I am using Navigation Drawer (using Navigation Drawer Activity) in android studio and its working fine.
But I want to change the Background Color of selected item in Drawer's item List. I want to change default Color to my custom Color.
Any idea ???
Create another xml layout under res ⇒ drawable named list_item_bg_pressed.xml with following content.
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"><gradient
android:startColor="#color/list_background_pressed"
android:endColor="#color/list_background_pressed"
android:angle="90" />
Create Selector
<item android:drawable="#drawable/list_item_bg_normal" android:state_activated="false"/>
<item android:drawable="#drawable/list_item_bg_pressed" android:state_pressed="true"/>
<item android:drawable="#drawable/list_item_bg_pressed" android:state_activated="true"/>
For more info see this link Sliding drawer

ImageButton background color change onClick

First-time Android dev, though have used C# and Java in the past.
Trying to make a simple, Windows 8-like GUI. At the moment I have one tile (ImageButton) with a background color set in activity_main.xml.
<ImageButton
android:id="#+id/btn1"
android:layout_width="120dp"
android:layout_height="120dp"
android:background="#FF0000"
android:onClick="changeColor"/>
And I have a function to change the color in MainActivity.java.
public void changeColor(){
ImageButton btn1 = (ImageButton) findViewById(R.id.btn1);
btn1.setBackgroundColor(Color.GREEN);
}
Compiles fine, but every time I click the red square, the app crashes.
I'm assuming there's something fundemental about how Android is developed that I'm missing which is leading to a very obvious mistake. Is there a better way to be doing this rather than ImageButtons?
Thanks!
Compiles fine, but every time I click the red square, the app crashes.
Because when adding android:onClick in xml then method must be public and accept a View as its only parameter which we want to call on View click:
public void changeColor(View view){
ImageButton btn1 = (ImageButton) findViewById(R.id.btn1);
btn1.setBackgroundColor(Color.GREEN);
}
It's better to create a selector and set it as backgraund to the button.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#color/button_pressed" />
<item android:color="#color/button_normal" />
</selector>
Hope it'll help you.
P.S. useful link
Is there a better way to be doing this rather than ImageButtons?
Yes, ImageButtons are mainly for creating a 'clickable' image. If you simply want a colored button, a regular Button will do fine.
You can do this by setting your Buttons background right from XML using a selector with a Drawable state list.
A good example can be found here: https://stackoverflow.com/a/3882151/1683141 (a color will also qualify as a Drawable)
Why isn't my current code working?
You should add the view as parameter to your method like this:
public void changeColor(View view){
view.setBackgroundColor(Color.GREEN);
}

android generate resource on the fly

I would like to generate a pressend button design and load it on the fly.
The static version it is an xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- selected state -->
<item android:drawable="#drawable/bt_back_pressed" android:state_pressed="true" android:state_selected="false"/>
<item android:drawable="#drawable/bt_back_pressed" android:state_pressed="false" android:state_selected="true"/>
<item android:drawable="#drawable/bt_back_pressed" android:state_pressed="true" android:state_selected="true"/>
<!-- unselected state (default) -->
<item android:drawable="#drawable/bt_back_normal"/>
</selector>
which is located in the /res/drawable folder. When I want to use it just a line of the code:
android:background="#drawable/bt_back"
Now, the current project loads the design for the button from the server side, let it be the bt_back_normal.png loaded from www.somehost.com/some/resource/bt_back_normal.png.
It would be nice if I could get an API to generate the "pressed" version ( some darker) and link it at events chain to show, when needed.
Right now there is no visual effect, when the user press the button.
How can I generate that xml equivalent on the fly? -generate a pressed version and set to show when needed.
Thanks.
I think you're looking for the StateListDrawable class. You can create these in code, add states to it (e.g. your downloaded pressed png file) and then set it to your button with button.setBackgroundDrawable(stateList).
No, you can't do this on the fly. If you wanna use dynamically generated pressed drawables you should implement OnTouchListener and set needed background inside of it.
This is kind of a workaround for that, but you could just override the OnClickListener for the button, and change the background of the button inside there. ie.
final Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
button.setBackgroundDrawable(R.drawable.button_pressed);
}
});
EDIT:
I didn't realize you wanted to change the states; thought you just wanted to show it was pressed. In that case, use StateListDrawable: http://developer.android.com/reference/android/graphics/drawable/StateListDrawable.html

How can i draw a circle that compatible with all android device with fixed radius?

I need to create a program, that have 5 radius buttons. When i'm click on these each button i want to adjust my circle radius.(Circle should have same size in all android phones).
pls help me to find this...
Deducting the screen size before you create a circle and act based on that is a elegant way ,
There are difference sizes of screens in android devices,
so find out the screen size place your co-ordinate values according to the found screen size,
If drawing is only one option for you then the following
thread will be helpful for you to achieve this,
Compatible Canvas draw tip
If not, then button backgounds should be 9 patch image is always better.
Hope , you will find it useful.
You could create a circle-shape in xml and set this as background resource to a button or an imageButton, or you could do your own button-class and override onDraw method. A tutorial with shape is here:
http://dandar3.blogspot.de/2012/10/android-custom-round-buttons.html
or here:
http://yekmer.posterous.com/how-to-make-rounded-buttons-on-android
Instead of using "rectangle" at the shape, You could use "oval".
I don´t know if I understand You right, but making a button that had the same size on every phone is not a good way. Views had to be independent, a view should be created in a way, that it is adjusted to the individual screen size. To do so, use "dp" units in your xml layouts.
Now here is my example:
1.) first create a shape-drawable in the drawable folder:
round_button_oval_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#00ced1" />
</shape>
2.) create a second shape in drawable folder:
rounded_button_oval_shape_pressed.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#008b8b" />
</shape>
3.) create a selector in the drawable folder:
rounded_button_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/rounded_button_oval_shape_pressed"
android:state_pressed="true"></item>
<item android:drawable="#drawable/round_button_oval_shape"
android:state_pressed="false"></item>
<item android:drawable="#drawable/round_button_oval_shape"></item>
</selector>
4.)create your main-layout
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world"
android:textColor="#ff0000" />
<Button
android:id="#+id/rounded_button"
android:layout_width="250dp"
android:layout_height="250dp"
android:background="#drawable/rounded_button_selector" />
</LinearLayout>
If you have done this parts, you could anything do with that button in your activity.
RoundedButtonDemo.java
public class RoundedButtonDemo extends Activity {
private Button mRoundedButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mRoundedButton = (Button) findViewById(R.id.rounded_button); //initialize your button
mRoundedButton.setOnClickListener(new OnClickListener() { // set Button on click listener
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Toast.makeText(RoundedButtonDemo.this, //show a toast when pressing button
R.string.rounded_button_message, Toast.LENGTH_LONG)
.show();
}
});
}
}
The shapes and the selector are needed for showing a pressed behavior of the button. The first shape is a normal button, which is not pressed. the second one is a shape that is pressed. The selector is using the two shapes for showing the pressed state to the user. To get this, set the selector as background to your button in your main.xml .

Categories