谷歌是如何做到这一点的? 在 Android 应用程序中滑动动作栏

我真的很想在我自己的应用程序中实现这个(侧面导航) ,有人知道谷歌是如何做到这一点的吗?

They seem to have pulled the current window aside and put in a fly-in navigation of their own.

62376 次浏览

事实上,有一种方法可以做到这一点,即使不实现您自己的 ActionBar

只需看一下 hierachyviewer! (位于 tools 目录中)

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

Then, the layouts:

菜单的布局(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>

Layout of the listitems (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();

就是这样!

And now, a little screenshot of it in action:

SlideMenu

据我所知,这是有效的。如果您遇到任何问题或我的解释不清楚,请与我联系!

编辑: ExtendedViewPager & ExtendedPagerStrip:

扩展浏览页面:

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的活动与 ViewPagerPagerTabStrip的标签,如谈话,市场等。您不能以简单的方式禁用这些视图,因此上面的两个类只是扩展它们以在禁用时停止 onTouch事件。

有几个 企图在这样做,但我还没有找到一个库或源代码,如何成功地实现它与操作栏跨所有 api 级别。一个有前途的解放者来了

Https://github.com/jfeinstein10/slidingmenu

这是 示例应用程序的视频。

here is the Google Play app link.

这个确实适用于 ActionbarSherlock。你将不得不建立滑动菜单库与 ABS 得到它的工作。效果很好,看起来很棒!

Did a roundup of the 原来的实施方案 and added XML parsing as well as autodetection of a possibly present actionbar, so it works with the native as well as a support action bar such as ActionBarSherlock.

整个事情现在是一个图书馆项目连同一个示例应用程序,是在 机器人的滑动菜单上描述了感谢 < strong > scirocco 的最初的想法和代码!

LibSlideMenu Screenshot

如果您使用的 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转换,而不仅仅是动画与动作栏的主要布局,所以您可以交互与膨胀的视图,您想要使用作为一个滑动面板。 您应该使用对应用程序有用的内容来替换硬编码值。

我希望这有所帮助:)

我已经创建了自己的解决方案,可以滑动视图并显示下面的菜单,因为许多其他解决方案似乎不能在旧的 Android 版本上工作,或者缺乏如何让它工作的正确说明。

我的解决方案有以下特点:

  • 提供对滑动视图以显示位于视图下方的菜单的支持
  • 上面的菜单和视图都可以是任何自定义视图
  • Supported on old Android versions (tested to work at least on Android 2.2)
  • 与 PhoneGap/Cordova 项目合作

该解决方案使用名为 SlidingMenuLayout 的自定义布局,您需要向其添加2个视图。您添加的第一个视图是菜单,第二个是主视图。

将布局添加到现有项目的最简单方法是重写 Activity 的 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 project page上找到。

对于那些使用 滑动菜单库(https://github.com/jfeinstein10/SlidingMenu)的人来说,有一种方法可以插入它,而且似乎是有效的!在@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);

基本上它所做的就是用 slidingmenu代替装饰视图中的 linearlayout

注意: 我只是轻轻地测试了一下,但是它似乎起作用了。

现在我正在做一个项目,遇到了一个滑动菜单,我谷歌了一下,但是很失望的发现没有人给出一些代码或者关于如何开始制作一个滑动菜单的提示,但是每个人都给出了链接到一些 github 的项目/库来使用,我决定自己来做,最后我有了自己的滑动菜单。

我花了两天时间

制作滑动动画

2. 关于如何使其适用于所有屏幕分辨率

一旦你对 动画片有了一些了解,它真的很简单,我在哪里读到过,重新发明 Wheel(参考滑动菜单的 github 源代码的人)是不明智的,但我相信你至少应该尝试自己做一次,这样你就会知道它实际上是如何工作和功能的:

这是我的滑动菜单如何工作的图片

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

Xml中,我最初包含了不可见的 Xml

Now 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;
}
}


}

这是动画

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>

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>

在那里你去一个完整的工作和功能的滑动菜单,你可以定制它来满足你的要求,如果任何人仍然有一些问题设置,随时询问,我很高兴能帮助你出 :)

    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。可以与动作幻灯片