Android sidebar like facebook or firefox [duplicate]
Asked Answered
E

4

17

With the new facebook app it comes with an hidden sidebar that I would love to use something like that in my applications. It looks kinda like the sidebars that firefox mobile have...

Do you have any idea how to implement it besides re-implementing the ViewPager? I've tried with an HorizontalScrollView but that would also lead to re-implementation of it...

I'm not seeing any other way besides these two... any suggestions?

Thanks in advance

Estremadura answered 10/12, 2011 at 0:17 Comment(2)
Expanded facebook the grey layout expands from the left from this: Main view on facebook On firefox we have this: firefox - left side is the "sidebar"Estremadura
@alextsc nice! My 2 day search I didn't come up with that result! thanks =)Estremadura
E
23

I came up with a solution... I don't know if it is perfect but it is working well.

So what I did was a single FrameLayout with both of the Layouts stacked together and then I just animate the top layout to slide to the right of the screen (just need to call the slideTo or scrollBy. And basically it's that! Quite simple and effective! (the code though is not very pretty :P)

EDIT:

Some code samples.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#FFF" >

        <include
        android:id="@+id/menu_layout"
            layout="@layout/menu_list"
            android:visibility="invisible"/>

        <include
            android:id="@+id/news_list_parent"
            layout="@layout/main_news_list" 
            />

</FrameLayout>

This is the layout xml, quite simpe. The included .xml are simple LinearLayouts with a heading and a listview.

The "magic" happens in the animation:

protected void applyTransformation(float interpolatedTime, Transformation t) {
    int newOffset;
    if(expanded) {
        newOffset = 0;
        newOffset = (int)(endOffset*(1-interpolatedTime));
    } else {
        newOffset = (int)(endOffset*(interpolatedTime));
    }
    view.scrollTo(-newOffset, 0);
}

The endOffset is the target movement. I set it before I start the animation, and the View I want to animate (in this case is the view with the id=news_list_parent) it is set on the constructor.

But just to understand how that works make a button and its listener would do something like this:

if(viewBeneath.getVisibility() == View.INVISIBLE) {
    viewBeneath.setVisibility(View.Visible);
    viewToSlide.slideTo(-(width-50), 0);
}

And finally override the back button to do the opposite of the button

if(viewBeneath.getVisibility() == View.VISIBLE) {
    viewToSlide.slideTo(0, 0);
    viewBeneath.setVisibility(View.Visible);
}

Read this as pseudo-code =) This is what I did in the beginning, that code is lost :P

Estremadura answered 11/12, 2011 at 1:55 Comment(12)
Baen, could you please share your code with us? I'm trying to do that myself and so far without any success...Thanks!Emelyemelyne
I edited it to include. Anything just ask!Estremadura
@Estremadura I see what you are doing. Why don't you wrap this into a library and share it on Github?Unwrap
@AmokraneChentir I have plans to do that but right now I want to end this project as fast as I can, then I want to make a custom viewgroup that implements this... Right now the best I could do was this, giving you an example. I hope you understand ;)Estremadura
Sure, it's explicit enough ;)Unwrap
@baen, I managed to get it working, except for the opposite action(when the back button is pressed).It does return to the initial state(x=0), but without the animation. I've used your code. Any idea what may cause it?Emelyemelyne
Is there a way to add animation in the scrollBy action? I got it working, but I would like to have the scroll action to run smoothly instead of a quick scroll. ThanksPeterus
@tofira do you reset the animation everytime you do anything with it? It's only my guessEstremadura
@HarshaMV unfortunately no... i'm sorry.Estremadura
@Peterus how so? I didn't quite get your question... Can you repeat it in another terms?Estremadura
@bean: The only downside to this sort of implementation is that I have to have the FrameLayout part and the menu layout part in every layout file. Am I right or am I missing something?Bauer
@AnandS yes... it is a big downside, I still haven't had time to implement this in a single view (which is possible)... If someone develops such view please share :DEstremadura
S
6

You can try out this. Good Example. Check for slider class..

https://github.com/gitgrimbo/android-sliding-menu-demo

Scram answered 4/10, 2012 at 22:19 Comment(0)
S
4

I did something like below: enter image description here

enter image description here

Below is my code for something like facebook side menu bar

  1. I put 2 views overlap in a frame layout. The bottom view is the menu, the top view is the content body.
  2. And I put the content body into a horizantal scroll view. I also put a view to the left of the content body in the horizantal scroll view. And set the view's background as transparent.
  3. Then scroll to content body at begining. So the side menu bar is blocked by the content body.
  4. When click a button to show the menu, I scroll the horizantal scroll view to show the transparent placeholder. Then the menu will show up since it is under the transparent placeholder now.

I did not use XML for the interface. I create everything in the below code. I think it should be easy to read and put into your eclipse.

package com.chaoshen.androidstudy.facebooklikesidemenubar;


import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends Activity{

    private boolean Menu_Displayed=false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Display display = getWindowManager().getDefaultDisplay();
        final int width = display.getWidth();

        // menu:
        LinearLayout li_menu = new LinearLayout(this);
        li_menu.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));  
        li_menu.setOrientation(1);//1 is vertical
        li_menu.setBackgroundColor(Color.GREEN);

        Button btn1 = new Button(this);
        btn1.setText("button 1");
        btn1.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));  

        li_menu.addView(btn1);

        //body:
        final HorizontalScrollView hsv = new HorizontalScrollView(this){
            @Override
            // do not let hsv consume the click itself. Then the view under the hsv will also consume the click
            //so that the menu will be clicked
            //when menu is not showed up, let hsv be the only view to consume the click.
            //so that the menu will not be clicked
            public boolean onTouchEvent(MotionEvent ev) {
                if(Menu_Displayed){
                    return false;
                }
                else{
                    return true;
                }
            }
        };
        hsv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));  
        hsv.setBackgroundColor(Color.TRANSPARENT);
        hsv.setHorizontalFadingEdgeEnabled(false);
        hsv.setVerticalFadingEdgeEnabled(false);

        final LinearLayout li_body = new LinearLayout(this);
        li_body.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT));  
        li_body.setOrientation(0);//0 is horizantal
        li_body.setBackgroundColor(Color.TRANSPARENT);

        hsv.addView(li_body);

        //body: place holder transparent
        TextView placeholder = new TextView(this);
        placeholder.setTextColor(Color.TRANSPARENT); 
        placeholder.setLayoutParams(new LayoutParams(width-100, LayoutParams.FILL_PARENT));  
        placeholder.setVisibility(View.INVISIBLE);
        li_body.addView(placeholder);

        //body: real content
        LinearLayout li_content = new LinearLayout(this);
        li_content.setLayoutParams(new LayoutParams(width, LayoutParams.FILL_PARENT));  
        li_content.setOrientation(1);//1 is vertical
        li_content.setBackgroundColor(Color.CYAN);

        TextView tv1 = new TextView(this);  
        tv1.setText("txt 1");  
        tv1.setTextSize(40);  
        tv1.setTextColor(Color.BLACK);  

        TextView tv2 = new TextView(this);  
        tv2.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));  
        tv2.setTextSize(50);  
        tv2.setText("txt 2");  
        tv2.setTextColor(Color.WHITE);  

        //use this button to scroll
        Button btn_showMenu = new Button(this);
        btn_showMenu.setText("Menu");
        btn_showMenu.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
        btn_showMenu.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                hsv.post(new Runnable() {

                    @Override
                    public void run() {
                        if(Menu_Displayed){
                            hsv.smoothScrollTo(width-100, 0);
                        }
                        else{
                            hsv.smoothScrollTo(0, 0);
                        }
                        Menu_Displayed = !Menu_Displayed;
                    }
                });
            }
        });

        li_content.addView(tv1);
        li_content.addView(tv2);
        li_content.addView(btn_showMenu);

        li_body.addView(li_content);

        //add menu and body in to frame
        FrameLayout mainFrame = new FrameLayout(this);  
        mainFrame.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));  
        mainFrame.addView(li_menu);  
        mainFrame.addView(hsv);  

        //scroll to the body real content to block the menu
        hsv.post(new Runnable() {

            @Override
            public void run() {
                hsv.scrollBy(width-100, 0);             
            }
        });

        setContentView(mainFrame);         
    }
}
Stunner answered 24/8, 2012 at 4:15 Comment(0)
B
3

I've created my own solution for this as well, as many stock solutions appeared to not work on older Android version or lacked proper instructions on how to get it to work.

My solution has the following features:

  • Provides support for sliding away a view to reveal a menu that lies underneath it
  • The menu can be any custom View
  • The view above can be any custom View as well
  • Supported on old Android versions (tested to work at least on Android 2.2)

The solution uses a custom layout, called SlidingMenuLayout, that you are expected to add 2 views to. The first view you add is the menu, the second is the main view.

The simplest way to add the layout to your existing project is to override your Activity's setContentView() method:

@Override
public void setContentView(View view) {

    SlidingMenuLayout layout = new SlidingMenuLayout(this);
    layout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT, 0.0F));

    layout.addView(new MenuView(this));

    layout.addView(view);

    super.setContentView(layout);
}

In this example, MenuView is the view that will actually show the menu. It is up to you to implement this view.

Finally, you can add a button (typically in the top left corner of your main view), that calls openMenu() or closeMenu() on the layout as appropriate.

The code for SlidingMenuLayout is found on the GitHub project page:

Brennen answered 27/9, 2012 at 9:1 Comment(2)
i tried several fly in navigations. but your navi seems the best one so far - and its really easy to implement into existing projects. I appreciate that!Epitomize
Thanks for the implementation, but could you as well post an example on how you implemented te MenuView class? Thanks in advance.Tapping

© 2022 - 2024 — McMap. All rights reserved.