it-swarm.com.ru

Как Google удалось это сделать? Слайд ActionBar в приложении Android

Я действительно хочу реализовать это (боковую навигацию) в своем приложении, кто-нибудь знает, как Google удалось это сделать?

Они, кажется, отодвинули текущее окно в сторону и включили собственную навигацию.

119
hwrdprkns

На самом деле, есть способ сделать это. Даже без реализации вашего собственного ActionBar.

Просто взгляните на hierachyviewer! (Находится в каталоге инструментов)

Есть DecorView и LinearLayout как ребенок. Это LinearLayout содержит и ActionBar, и другое содержимое. Таким образом, вы можете просто применить некоторый FrameLayout.LayoutParams к этому LinearLayout и таким образом получить место слева. Затем вы можете заполнить это пространство с помощью вашего меню-ListView и наложить другой контент с помощью FrameLayout, который при щелчке сворачивает меню. Итак, вот некоторый код:

Во-первых, класс для свертывания/расширения (SlideMenu.Java):

package your.cool.app;

import Android.app.Activity;
import Android.content.Context;
import Android.content.Intent;
import Android.graphics.Rect;
import Android.util.Log;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.View.OnClickListener;
import Android.view.ViewGroup;
import Android.view.Window;
import Android.view.animation.TranslateAnimation;
import Android.widget.AdapterView;
import Android.widget.AdapterView.OnItemClickListener;
import Android.widget.ArrayAdapter;
import Android.widget.FrameLayout;
import Android.widget.ImageView;
import Android.widget.LinearLayout;
import Android.widget.ListView;
import Android.widget.TextView;

public class SlideMenu {
//just a simple adapter
public static class SlideMenuAdapter extends ArrayAdapter<SlideMenu.SlideMenuAdapter.MenuDesc> {
    Activity act;
    SlideMenu.SlideMenuAdapter.MenuDesc[] items;
    class MenuItem {
        public TextView label;
        public ImageView icon;
    }
    static class MenuDesc {
        public int icon;
        public String label;
    }
    public SlideMenuAdapter(Activity act, SlideMenu.SlideMenuAdapter.MenuDesc[] items) {
        super(act, R.id.menu_label, items);
        this.act = act;
        this.items = items;
        }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View rowView = convertView;
        if (rowView == null) {
            LayoutInflater inflater = act.getLayoutInflater();
            rowView = inflater.inflate(R.layout.menu_listitem, null);
            MenuItem viewHolder = new MenuItem();
            viewHolder.label = (TextView) rowView.findViewById(R.id.menu_label);
            viewHolder.icon = (ImageView) rowView.findViewById(R.id.menu_icon);
            rowView.setTag(viewHolder);
        }

        MenuItem holder = (MenuItem) rowView.getTag();
        String s = items[position].label;
        holder.label.setText(s);
        holder.icon.setImageResource(items[position].icon);

        return rowView;
    }
}

private static boolean menuShown = false;
private static View menu;
private static LinearLayout content;
private static FrameLayout parent;
private static int menuSize;
private static int statusHeight = 0;
private Activity act;
SlideMenu(Activity act) {
    this.act = act;
}
//call this in your onCreate() for screen rotation
public void checkEnabled() {
    if(menuShown)
        this.show(false);
}
public void show() {
//get the height of the status bar
    if(statusHeight == 0) {
        Rect rectgle = new Rect();
        Window window = act.getWindow();
        window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
        statusHeight = rectgle.top;
        }
    this.show(true);
}
public void show(boolean animate) {
    menuSize = Functions.dpToPx(250, act);
    content = ((LinearLayout) act.findViewById(Android.R.id.content).getParent());
    FrameLayout.LayoutParams parm = (FrameLayout.LayoutParams) content.getLayoutParams();
    parm.setMargins(menuSize, 0, -menuSize, 0);
    content.setLayoutParams(parm);
//animation for smooth slide-out
    TranslateAnimation ta = new TranslateAnimation(-menuSize, 0, 0, 0);
    ta.setDuration(500);
    if(animate)
        content.startAnimation(ta);
    parent = (FrameLayout) content.getParent();
    LayoutInflater inflater = (LayoutInflater) act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    menu = inflater.inflate(R.layout.menu, null);
    FrameLayout.LayoutParams lays = new FrameLayout.LayoutParams(-1, -1, 3);
    lays.setMargins(0,statusHeight, 0, 0);
    menu.setLayoutParams(lays);
    parent.addView(menu);
    ListView list = (ListView) act.findViewById(R.id.menu_listview);
    list.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            //handle your menu-click
        }
    });
    if(animate)
        menu.startAnimation(ta);
    menu.findViewById(R.id.overlay).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            SlideMenu.this.hide();
        }
    });
    Functions.enableDisableViewGroup((LinearLayout) parent.findViewById(Android.R.id.content).getParent(), false);
    ((ExtendedViewPager) act.findViewById(R.id.viewpager)).setPagingEnabled(false);
    ((ExtendedPagerTabStrip) act.findViewById(R.id.viewpager_tabs)).setNavEnabled(false);
    menuShown = true;
    this.fill();
}
public void fill() {
    ListView list = (ListView) act.findViewById(R.id.menu_listview);
    SlideMenuAdapter.MenuDesc[] items = new SlideMenuAdapter.MenuDesc[5];
    //fill the menu-items here
    SlideMenuAdapter adap = new SlideMenuAdapter(act, items);
    list.setAdapter(adap);
}
public void hide() {
    TranslateAnimation ta = new TranslateAnimation(0, -menuSize, 0, 0);
    ta.setDuration(500);
    menu.startAnimation(ta);
    parent.removeView(menu);

    TranslateAnimation tra = new TranslateAnimation(menuSize, 0, 0, 0);
    tra.setDuration(500);
    content.startAnimation(tra);
    FrameLayout.LayoutParams parm = (FrameLayout.LayoutParams) content.getLayoutParams();
    parm.setMargins(0, 0, 0, 0);
    content.setLayoutParams(parm);
    Functions.enableDisableViewGroup((LinearLayout) parent.findViewById(Android.R.id.content).getParent(), true);
    ((ExtendedViewPager) act.findViewById(R.id.viewpager)).setPagingEnabled(true);
    ((ExtendedPagerTabStrip) act.findViewById(R.id.viewpager_tabs)).setNavEnabled(true);
    menuShown = false;
}
}

Некоторые вспомогательные методы (для меня в static Functions.Java):

    public static int dpToPx(int dp, Context ctx) {
    Resources r = ctx.getResources();
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());
}
//originally: http://stackoverflow.com/questions/5418510/disable-the-touch-events-for-all-the-views
//modified for the needs here
public static void enableDisableViewGroup(ViewGroup viewGroup, boolean enabled) {
    int childCount = viewGroup.getChildCount();
    for (int i = 0; i < childCount; i++) {
        View view = viewGroup.getChildAt(i);
        if(view.isFocusable())
            view.setEnabled(enabled);
        if (view instanceof ViewGroup) {
            enableDisableViewGroup((ViewGroup) view, enabled);
            } else if (view instanceof ListView) {
                if(view.isFocusable())
                    view.setEnabled(enabled);
                ListView listView = (ListView) view;
                int listChildCount = listView.getChildCount();
                for (int j = 0; j < listChildCount; j++) {
                    if(view.isFocusable())
                        listView.getChildAt(j).setEnabled(false);
                    }
                }
        }
    }

Затем макеты:

Расположение меню (res/layout/menu.xml)

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
              Android:layout_width="fill_parent"
              Android:layout_height="fill_parent" >
    <LinearLayout
        Android:orientation="vertical"
        Android:layout_height="fill_parent"
        Android:layout_width="250dip"
        Android:background="@color/darkblack">
        <ListView
            Android:id="@+id/menu_listview"
            Android:layout_width="fill_parent"
            Android:layout_height="wrap_content"
            Android:divider="@color/dividerblack"
            Android:dividerHeight="2dip"  />
    </LinearLayout>
    <FrameLayout
        Android:id="@+id/overlay"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" >
    </FrameLayout>
</LinearLayout>

Расположение элементов списка (res/layout/menu_listitem.xml):

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_height="wrap_content"
Android:layout_width="fill_parent" >
    <ImageView
        Android:id="@+id/menu_icon"
        Android:layout_width="30dp"
        Android:layout_height="30dp"
        Android:layout_marginRight="5dip"
        Android:layout_marginLeft="10dip"
        Android:layout_marginTop="10dip"
        Android:layout_marginBottom="10dip" />

    <TextView
        Android:id="@+id/menu_label"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:textColor="@color/white"
        Android:textSize="24dp"
        Android:layout_marginTop="10dip"
        Android:layout_marginBottom="10dip" />
</LinearLayout>

Как это использовать:

В вашей onCreate():

private SlideMenu slidemenu;
@Override
public void onCreate(Bundle savedInstanceState) {
    //your onCreate code
    slidemenu = new SlideMenu(this);
    slidemenu.checkEnabled();
}

В обработчике домашней кнопки ActionBar:

slidemenu.show();

Это оно!

А теперь маленький скриншот этого в действии:

SlideMenu

Насколько я знаю, это работает. Если у вас возникли проблемы или мои объяснения неясны, пожалуйста, свяжитесь со мной!

Правка: ExtendedViewPager & ExtendedPagerStrip:

ExtendedViewPager:

package your.cool.app;

//source: http://blog.svpino.com/2011/08/disabling-pagingswiping-on-Android.html

import Android.content.Context;
import Android.support.v4.view.ViewPager;
import Android.util.AttributeSet;
import Android.view.MotionEvent;

public class ExtendedViewPager extends ViewPager {

private boolean enabled;

public ExtendedViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.enabled = true;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (this.enabled) {
        return super.onTouchEvent(event);
    }

    return false;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    if (this.enabled) {
        return super.onInterceptTouchEvent(event);
    }

    return false;
}

public void setPagingEnabled(boolean enabled) {
    this.enabled = enabled;
}
}

ExtendedPagerTabStrip:

package your.cool.app;

//source: http://blog.svpino.com/2011/08/disabling-pagingswiping-on-Android.html

import Android.content.Context;
import Android.support.v4.view.PagerTabStrip;
import Android.util.AttributeSet;
import Android.view.MotionEvent;

public class ExtendedPagerTabStrip extends PagerTabStrip {

private boolean enabled;

public ExtendedPagerTabStrip(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.enabled = true;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (this.enabled) {
        return super.onTouchEvent(event);
    }

    return false;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    if (this.enabled) {
        return super.onInterceptTouchEvent(event);
    }

    return false;
}

public void setNavEnabled(boolean enabled) {
    this.enabled = enabled;
}
}

Я использую это SlideMenu для действия с ViewPager с PagerTabStrip для вкладок, таких как Talk, Market и т.д. Вы не можете отключить эти представления простым способом, поэтому два вышеупомянутых класса просто расширяют их, чтобы остановить событие onTouch, когда оно отключено.

150
Scirocco

Есть несколько попыток сделать это, однако мне еще предстоит найти lib или исходный код, как успешно реализовать его с помощью actionbar на всех уровнях API. Одна многообещающая библиотека здесь

https://github.com/jfeinstein10/SlidingMen

вот видео о пример приложения .

вот ссылка на приложение Google Play .

Это работает с ActionbarSherlock. Вам нужно будет собрать библиотеку SlidingMenu с ABS, чтобы она заработала. Работает и выглядит отлично!

21
Patrick

Сделал округление оригинальная реализация и добавил синтаксический анализ XML, а также autodetection из возможного присутствующего actionbar, чтобы он работал как с родной, так и с панелью действий поддержки, такой как ActionBarSherlock.

Все это теперь библиотечный проект вместе с примером приложения и описан в Sliding Menu for Android Благодаря scirocco за первоначальную идею и код!

LibSlideMenu Screenshot

8
bk138

Если вы используете уровень API выше 11, вы можете использовать гораздо более простой подход, основанный на ответ дан @Scirocco

// get content parent that is basically the whole 
// app screen (viewed from hierarchy viewer)
final LinearLayout content = 
     (LinearLayout) findViewById(Android.R.id.content).getParent();

// make new value animator with range from 0 to 1
final ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
// set custom duration
animator.setDuration(500);
// on update is called for every value in the 
    // given range in time frame defined by the duration
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

    public void onAnimationUpdate(ValueAnimator animation) {
        // get the current value
        float value = ((Float) (animation.getAnimatedValue())).floatValue();
        // translate by that value, minus means translate left
        content.setTranslationX(-250 * value);
    }
});
// start the animator
animator.start();

// make or inflate custom view for test purposes 
Button textView = new Button(this);
textView.setText("TestButton");
// add it to the frame layout that is the parent of the content on position 0
FrameLayout parent = (FrameLayout) content.getParent();
parent.addView(textView, 0);

Идея здесь состоит в том, чтобы использовать ValueAnimator, который преобразует, а не просто анимирует основной макет с помощью панели действий, чтобы вы могли взаимодействовать с раздутым видом, который вы хотите использовать в качестве скользящей панели. Вы должны заменить жестко закодированные значения чем-то полезным для вашего приложения.

Надеюсь, это поможет :)

7
Medo

Ну, в настоящее время я работаю над проектом и наткнулся на скользящее меню, я погуглил, но очень разочарован тем, что никто не дал какой-то кусок кода или подсказку о том, как начать создавать скользящее меню, но каждый дал ссылку на некоторые Проекты/библиотеки github для использования, я решил сделать это сам и, наконец, у меня есть готовое скользящее меню ...

Я потратил два дня на это

1. При создании анимации скольжения

2. При работе со всеми разрешениями экрана

Это действительно легко и просто, как только вы получите представление о анимации, я читал кое-где, не имеет смысла изобретать Wheel (людей, которые ссылаются на источник github код скользящего меню), но я полагаю, что вы должны хотя бы один раз попытаться сделать свой собственный, чтобы вы поняли, как это на самом деле работает и функционирует: P

так что это картина того, как мое скользящее меню будет работать

1.Find.xml//later in the code it will be refer as findLayout

<?xml version="1.0" encoding="utf-8"?>


<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent" >

    <RelativeLayout
        Android:id="@+id/find_layout"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent">

    <RelativeLayout
        Android:id="@+id/header" 
        Android:layout_width="match_parent"
        Android:layout_height="60dp"
        Android:padding="2dp"
        Android:background="@drawable/main_header">

        <Button 
            Android:id="@+id/filter"
            Android:layout_width="40dp"
            Android:layout_height="30dp"
            Android:layout_alignParentLeft="true"
            Android:layout_centerVertical="true"
            Android:background="@drawable/filter_button" />

        <TextView 
            Android:id="@+id/city"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_toRightOf="@+id/filter"
            Android:layout_marginLeft="20dp"
            Android:layout_marginTop="3dp"
            Android:text="Islamabad"
            Android:textSize="22sp"
            Android:textStyle="bold"
            Android:textColor="@Android:color/primary_text_dark"/>

        <RelativeLayout 
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_below="@+id/city"
            Android:layout_alignLeft="@+id/city">

            <TextView 
                Android:id="@+id/interested_in"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:layout_centerVertical="true"
                Android:text="Men and Women"
                Android:textSize="12sp"
                Android:textColor="@Android:color/primary_text_dark"/>

            <ImageView 
                Android:id="@+id/separator"
                Android:layout_width="2dp"
                Android:layout_height="18dp"
                Android:layout_toRightOf="@+id/interested_in"
                Android:layout_marginLeft="4dp"
                Android:src="@drawable/separator_1"
                Android:layout_centerVertical="true" />

            <TextView 
                Android:id="@+id/age"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:layout_marginLeft="4dp"
                Android:layout_toRightOf="@+id/separator"
                Android:layout_centerVertical="true"
                Android:text="18-24 years"
                Android:textSize="12sp"
                Android:textColor="@Android:color/primary_text_dark"/>

            <ImageView
                Android:id="@+id/separator_1" 
                Android:layout_width="2dp"
                Android:layout_height="18dp"
                Android:layout_toRightOf="@+id/age"
                Android:layout_marginLeft="4dp"
                Android:src="@drawable/separator_1"
                Android:layout_centerVertical="true" />

            <TextView 
                Android:id="@+id/distance"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:layout_marginLeft="4dp"
                Android:layout_toRightOf="@+id/separator_1"
                Android:layout_centerVertical="true"
                Android:text=">30km"
                Android:textSize="12sp"
                Android:textColor="@Android:color/primary_text_dark" />


        </RelativeLayout>

    </RelativeLayout>

    <GridView 
        Android:id="@+id/users_grid"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:layout_below="@+id/header"
        Android:numColumns="4">

    </GridView>

    </RelativeLayout>

    <include 
        layout="@layout/filter"/> //here i included the filter.xml, which is on top of find.xml layout and is initially invisible    
</RelativeLayout>

enter image description here

2.Filter.xml//later in code refer as FilterLayout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/filter_layout"
    Android:visibility="invisible"
    Android:layout_width="260dp"
    Android:layout_height="match_parent"
    Android:background="@drawable/grey_bg" >

    <ImageView 
        Android:id="@+id/profile_pic"
        Android:layout_width="match_parent"
        Android:layout_height="220dp"
        Android:src="@drawable/pic"/>

    <RelativeLayout
        Android:id="@+id/header" 
        Android:layout_width="match_parent"
        Android:layout_height="55dp"
        Android:paddingLeft="10dp"
        Android:paddingTop="5dp"
        Android:layout_below="@+id/profile_pic"
        Android:background="@drawable/light_blue_header">

        <TextView
            Android:id="@+id/name" 
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_marginTop="3dp"
            Android:text="Raja Babar"
            Android:textSize="18sp"
            Android:textStyle="bold"
            Android:textColor="@Android:color/primary_text_dark"/>

        <RelativeLayout
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_below="@+id/name"
            Android:layout_alignLeft="@+id/name">

            <TextView
                Android:id="@+id/gender"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:layout_centerVertical="true"
                Android:text="Male"
                Android:textSize="12sp"
                Android:textColor="@Android:color/primary_text_dark" />

            <ImageView 
                Android:id="@+id/seperator"
                Android:layout_width="2dp"
                Android:layout_height="20dp"
                Android:layout_toRightOf="@+id/gender"
                Android:layout_marginLeft="5dp"
                Android:src="@drawable/separator_1"
                Android:layout_centerVertical="true" />

            <TextView
                Android:id="@+id/age"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:layout_toRightOf="@+id/seperator"
                Android:layout_marginLeft="5dp"
                Android:layout_centerVertical="true"
                Android:text="22 years"
                Android:textSize="12sp"
                Android:textColor="@Android:color/primary_text_dark" />

        </RelativeLayout>


    </RelativeLayout>

    <ScrollView 
        Android:layout_width="250dp"
        Android:layout_height="wrap_content"
        Android:layout_below="@+id/header"
        Android:layout_marginTop="15dp"
        Android:layout_centerHorizontal="true">

    <RelativeLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">

    <TextView
            Android:id="@+id/filter_options" 
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="@string/filter_options"
            Android:textSize="18sp"
            Android:textStyle="bold"
            Android:textColor="@Android:color/primary_text_light"/>

    <RelativeLayout
        Android:id="@+id/interested_in_layout" 
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:paddingLeft="15dp"
        Android:paddingRight="40dp"
        Android:layout_below="@+id/filter_options"
        Android:background="@drawable/interested_in_field">

        <TextView 
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_alignParentLeft="true"
            Android:layout_centerVertical="true"
            Android:text="@string/gender"
            Android:textSize="18sp"
            Android:textStyle="bold"
            Android:textColor="@Android:color/primary_text_light"/>

        <TextView 
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_alignParentRight="true"
            Android:layout_centerVertical="true"
            Android:text="@string/women_men"
            Android:textSize="18sp"
            Android:textColor="#33b9cd" />


    </RelativeLayout>
    <RelativeLayout
        Android:id="@+id/age_layout" 
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:paddingLeft="15dp"
        Android:paddingRight="40dp"
        Android:layout_below="@+id/interested_in_layout"
        Android:background="@drawable/age_field_1">

        <TextView 
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_alignParentLeft="true"
            Android:layout_centerVertical="true"
            Android:text="@string/age"
            Android:textSize="18sp"
            Android:textStyle="bold"
            Android:textColor="@Android:color/primary_text_light"/>

        <TextView 
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_alignParentRight="true"
            Android:layout_centerVertical="true"
            Android:text="18-24 years"
            Android:textSize="18sp"
            Android:textColor="#33b9cd"/>


    </RelativeLayout>
    <RelativeLayout 
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:paddingLeft="15dp"
        Android:paddingRight="40dp"
        Android:layout_below="@+id/age_layout"
        Android:background="@drawable/distance_field">

        <TextView 
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_alignParentLeft="true"
            Android:layout_centerVertical="true"
            Android:text="@string/distance"
            Android:textSize="18sp"
            Android:textStyle="bold"
            Android:textColor="@Android:color/primary_text_light"/>

        <TextView 
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_alignParentRight="true"
            Android:layout_centerVertical="true"
            Android:text=">30km"
            Android:textSize="18sp"
            Android:textColor="#33b9cd"/>


    </RelativeLayout>



    </RelativeLayout>

    </ScrollView>



</RelativeLayout>

enter image description here

В find.xml я включил filter.xml изначально, который невидим

Сейчас FilterAnimation.Java

package matchat.helpers;

import com.s3.matchat.R;

import Android.content.Context;
import Android.util.DisplayMetrics;
import Android.view.View;
import Android.view.animation.AlphaAnimation;
import Android.view.animation.Animation;
import Android.view.animation.Animation.AnimationListener;
import Android.view.animation.AnimationUtils;
import Android.widget.RelativeLayout;

public class FilterAnimation implements AnimationListener 
{
    Context context;

    RelativeLayout filterLayout, otherLayout;

    private Animation filterSlideIn, filterSlideOut, otherSlideIn, otherSlideOut;

    private static int otherLayoutWidth, otherLayoutHeight;

    private boolean isOtherSlideOut = false;

    private int deviceWidth;

    private int margin;

    public FilterAnimation(Context context) 
    {
        this.context = context;

        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();

        deviceWidth = displayMetrics.widthPixels; // as my animation is x-axis related so i gets the device width and will use that width,so that this sliding menu will work fine in all screen resolutions
    }

    public void initializeFilterAnimations(RelativeLayout filterLayout)
    {
        this.filterLayout = filterLayout;

        filterSlideIn = AnimationUtils.loadAnimation(context, R.anim.filter_slide_in);

        filterSlideOut = AnimationUtils.loadAnimation(context, R.anim.filter_slide_out);    

    }

    public void initializeOtherAnimations(RelativeLayout otherLayout)
    {       
        this.otherLayout = otherLayout;

        otherLayoutWidth = otherLayout.getWidth();

        otherLayoutHeight = otherLayout.getHeight();


        otherSlideIn = AnimationUtils.loadAnimation(context, R.anim.other_slide_in);
        otherSlideIn.setAnimationListener(this);

        otherSlideOut = AnimationUtils.loadAnimation(context, R.anim.other_slide_out);
        otherSlideOut.setAnimationListener(this);
    }

    public void toggleSliding()
    {
        if(isOtherSlideOut) //check if findLayout is already slided out so get so animate it back to initial position
        {       
            filterLayout.startAnimation(filterSlideOut);

            filterLayout.setVisibility(View.INVISIBLE);

            otherLayout.startAnimation(otherSlideIn);
        }
        else //slide findLayout Out and filterLayout In
        {
            otherLayout.startAnimation(otherSlideOut);

            filterLayout.setVisibility(View.VISIBLE);

            filterLayout.startAnimation(filterSlideIn);
        }
    }

    @Override
    public void onAnimationEnd(Animation animation) 
    {
        if(isOtherSlideOut) //Now here we will actually move our view to the new position,because animations just move the pixels not the view
        {
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(otherLayoutWidth, otherLayoutHeight);

            otherLayout.setLayoutParams(params);

            isOtherSlideOut = false;
        }
        else
        {   
            margin = (deviceWidth * 80) / 100; //here im coverting device percentage width into pixels, in my other_slide_in.xml or other_slide_out.xml you can see that i have set the Android:toXDelta="80%",so it means the layout will move to 80% of the device screen,to work across all screens i have converted percentage width into pixels and then used it



            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(otherLayoutWidth, otherLayoutHeight);

            params.leftMargin = margin;

            params.rightMargin = -margin; //same margin from right side (negavite) so that our layout won't get shrink

            otherLayout.setLayoutParams(params);

            isOtherSlideOut = true;

            dimOtherLayout();
        }
    }

    @Override
    public void onAnimationRepeat(Animation animation) 
    {

    }

    @Override
    public void onAnimationStart(Animation animation) 
    {

    }

    private void dimOtherLayout()
    {
        AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.5f);

        alphaAnimation.setFillAfter(true);

        otherLayout.startAnimation(alphaAnimation);
    }

}

сейчас найди. Java

package main.matchat.activities;

import matchat.helpers.FilterAnimation;
import com.s3.matchat.R;
import Android.app.Activity;
import Android.os.Bundle;
import Android.util.DisplayMetrics;
import Android.view.View;
import Android.view.ViewTreeObserver;
import Android.view.View.OnClickListener;
import Android.view.ViewTreeObserver.OnGlobalLayoutListener;
import Android.widget.Button;
import Android.widget.RelativeLayout;

public class Find extends Activity implements OnClickListener
{
    RelativeLayout filterLayout, findLayout;

    Button btFilter;

    FilterAnimation filterAnimation;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {       
        super.onCreate(savedInstanceState);
        setContentView(R.layout.find);

        filterLayout = (RelativeLayout)findViewById(R.id.filter_layout);

        findLayout = (RelativeLayout)findViewById(R.id.find_layout);

        btFilter = (Button)findViewById(R.id.filter);
        btFilter.setOnClickListener(this);

        filterAnimation = new FilterAnimation(this);

        initializeAnimations(); 
    }

    private void initializeAnimations()
    {   //Setting GlobolLayoutListener,when layout is completely set this function will get called and we can have our layout onbject with correct width & height,else if you simply try to get width/height of your layout in onCreate it will return 0

        final ViewTreeObserver filterObserver = filterLayout.getViewTreeObserver();

        filterObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() 
        {

            @Override
            public void onGlobalLayout() 
            {
                filterLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);

                DisplayMetrics displayMetrics = getResources().getDisplayMetrics();

                int deviceWidth = displayMetrics.widthPixels;

                int filterLayoutWidth = (deviceWidth * 80) / 100; //here im coverting device percentage width into pixels, in my other_slide_in.xml or other_slide_out.xml you can see that i have set the Android:toXDelta="80%",so it means the layout will move to 80% of the device screen,to work across all screens i have converted percentage width into pixels and then used it

                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(filterLayoutWidth, RelativeLayout.LayoutParams.MATCH_PARENT);

                filterLayout.setLayoutParams(params);//here im setting the layout params for my filter.xml because its has width 260 dp,so work it across all screen i first make layout adjustments so that it work across all screens resolution 

                filterAnimation.initializeFilterAnimations(filterLayout);

            }
        });

        final ViewTreeObserver findObserver = findLayout.getViewTreeObserver();

        findObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() 
        {

            @Override
            public void onGlobalLayout() 
            {
                findLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);

                filterAnimation.initializeOtherAnimations(findLayout);
            }
        });

    }

    @Override
    public void onClick(View v) 
    {
        int id = v.getId();

        switch(id)
        {

        case R.id.filter:

            filterAnimation.toggleSliding();

            break;
        }
    } 

}

Вот анимация res/anim

1.filter_slide_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.Android.com/apk/res/Android"
     Android:interpolator="@Android:anim/decelerate_interpolator">

    <translate 
        Android:fromXDelta="-100%"
        Android:toXDelta="0%"
        Android:duration="1000"
        Android:fillEnabled="true" />

</set>

2.filter_slide_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.Android.com/apk/res/Android"
     Android:interpolator="@Android:anim/decelerate_interpolator">

    <translate 
        Android:fromXDelta="0%"
        Android:toXDelta="-100%"
        Android:duration="1000"/>

</set>

.other_slide_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.Android.com/apk/res/Android"
     Android:interpolator="@Android:anim/decelerate_interpolator" >

    <translate 
        Android:fromXDelta="0%"
        Android:toXDelta="-80%"
        Android:duration="1000"
        Android:fillEnabled="true"/>

</set>

4.other_slide_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.Android.com/apk/res/Android"
     Android:interpolator="@Android:anim/decelerate_interpolator">

    <translate 
        Android:fromXDelta="0%"
        Android:toXDelta="80%"
        Android:duration="1000"
        Android:fillEnabled="true"/>

</set>

Там вы получаете полное рабочее и функциональное скользящее меню, и вы можете настроить его в соответствии с вашими требованиями, если у кого-то все еще есть проблемы с настройкой, не стесняйтесь спрашивать, я рад помочь вам :)

6
Muhammad Babar

Я создал свое собственное решение для смещения представления и отображения меню под ним, поскольку многие другие решения, по-видимому, не работали на более старых Android версиях или не имели надлежащих инструкций о том, как заставить его работать.

Мое решение имеет следующие особенности:

  • Обеспечивает поддержку скольжения вида для отображения меню, которое находится под ним.
  • И меню, и вид выше могут быть любым пользовательским видом.
  • Поддерживается в старых версиях Android (проверено на работу как минимум в Android 2.2)
  • Работает с проектами PhoneGap/Cordova

В решении используется пользовательский макет с именем SlidingMenuLayout, к которому предполагается добавить 2 представления. Первый вид, который вы добавляете - это меню, второй - основной вид.

Самый простой способ добавить макет в существующий проект - переопределить метод setContentView() вашей деятельности:

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

В этом примере MenuView - это представление, которое фактически отображает меню. Это зависит от вас, чтобы реализовать эту точку зрения.
Наконец, вы можете добавить кнопку (обычно в верхнем левом углу вашего основного вида), которая вызывает openMenu() или closeMenu() в зависимости от ситуации.
Код для SlidingMenuLayout находится на GitHub страница проекта .

5
arendjr

Для тех из вас, кто использует библиотеку SlidingMenu ( https://github.com/jfeinstein10/SlidingMen ), есть способ поднять его, и это, кажется, работает! С помощью @Scirocco поместите это в свое onCreate для действия:

ViewGroup decorView = (ViewGroup) getWindow().getDecorView();
mSlidingMenu = new SlidingMenu(this);
ViewGroup mainContent = (ViewGroup) decorView.getChildAt(0);
decorView.removeView(mainContent);
mSlidingMenu.setContent(mainContent);
decorView.addView(mSlidingMenu);
mMenu = (LinearLayout) View.inflate(this, R.layout.menuview, null);
mSlidingMenu.setMenu(mMenu);
mSlidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);
mSlidingMenu.setBehindOffsetRes(R.dimen.slidingmenu_offset);

в основном он заменяет linearlayout в виде декора на slidingmenu.

Обратите внимание: я только протестировал это слегка, но, похоже, работает.

3
Hirschen
    public class ImprovedSlidingPaneLayout extends SlidingPaneLayout {
    Context context;
    FrameLayout left;
    FrameLayout right;
    Boolean canOpen = true;
    public ImprovedSlidingPaneLayout(Context context) {
        super(context);
        this.context = context;
        this.left = new FrameLayout(context);
        this.right = new FrameLayout(context);
        this.addView(left);
        this.addView(right);
    }
    public ImprovedSlidingPaneLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (canOpen)
            return super.onInterceptTouchEvent(ev);
        else
            return false;
    }

    public ImprovedSlidingPaneLayout canOpen(Boolean canOpen) {
        this.canOpen = canOpen;
        return this;
    }

    public ImprovedSlidingPaneLayout makeActionBarSlide(Window window){
        ViewGroup decorView = (ViewGroup) window.getDecorView();
        ViewGroup mainContent = (ViewGroup) decorView.getChildAt(0);
        decorView.removeView(mainContent);
        setContentView(mainContent);
        decorView.addView(this);
        return this;
    }

    public ImprovedSlidingPaneLayout setMenuView(View view){
        if((left.getChildCount()== 1)){
            left.removeView(left.getChildAt(0));
        }
        left.addView(view);
        return this;
    }

    public ImprovedSlidingPaneLayout setContentView(View view){
        if((right.getChildCount()== 1)){
            right.removeView(right.getChildAt(0));
        }
        right.addView(view);
        return this;
    }

    public ImprovedSlidingPaneLayout setMenuWidth(int width){
        left.setLayoutParams(new SlidingPaneLayout.LayoutParams(width, ViewGroup.LayoutParams.MATCH_PARENT));
        return this;
    }

}

это мой класс расширяет SlidingPaneLayout. Может скользить с actio

0
user2212515