Google如何设法做到这一点? 在Android应用程序中滑动ActionBar
我真的想在我自己的应用中实现这个(侧面导航),有谁知道谷歌如何做到这一点?
他们似乎把当前的窗户拉到一边,并进入自己的飞行导航。
事实上,有一种方法可以做到这一点。 即使没有实现你自己的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; } }
一些帮助方法(对于我来说,在静态的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>
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 homebutton的处理程序中:
slidemenu.show();
而已!
而现在,它的一个小截图在行动:
据我所知,这是工作。 如果您遇到任何问题或我的解释不清楚,请与我联系!
编辑: 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
事件。
有几次这样做的尝试 ,但是我还没有find一个lib或源代码如何成功地实现与所有api级别的操作栏。 一个有希望的lib在这里
https://github.com/jfeinstein10/SlidingMenu
这里是一个示例应用程序的video。
这里是Google Play应用程序链接。
这与ActionbarSherlock一起工作。 你将不得不build立与ABS的SlidingMenu库来得到它的工作。 作品,看起来不错!
对原始实现进行了总结,并添加了XMLparsing以及可能存在的操作栏的autodetection
,因此它可以与本地以及支持操作栏(如ActionBarSherlock
。
整个事情现在是一个图书馆项目连同一个示例应用程序,并在Android的滑动菜单上描述感谢scirocco最初的想法和代码!
如果您使用的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
进行转换,而不只是使用动作栏来animation主布局,所以您可以与想要用作滑动面板的充气视图进行交互。 您应该将硬编码值replace为适用于您的应用的某些内容。
我希望这有帮助 :)
以及目前我正在一个项目工作,遇到滑动菜单,我google了,但非常失望,看到没有人给了一些代码或一些提示如何开始做一个滑动菜单,但每一个已经给一些链接github的项目/图书馆使用,我决定自己做,最后我有我自己的滑动菜单准备…
我花了两天的时间
1.制作滑动animation
2.使其适用于所有屏幕分辨率
它真的很容易和简单,一旦你对animation有一些想法,我已经阅读了一些地方,它不是重新发明轮子 (指的是滑动菜单的github源代码的人),但我beleif,你应该至less一次试着让你自己,让你知道它是如何工作和function: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>
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>
在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); } }
现在Find.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; } } }
这里是animationres / 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>
3.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>
在这里你可以find一个完整的工作和function滑动菜单,你可以定制它来满足你的要求,如果任何人仍然有一些设置问题,随时问,我很乐意帮助你🙂
我已经创build了我自己的解决scheme,用于滑开视图并显示下面的菜单,因为许多其他解决scheme似乎在旧版本的Android上无法正常工作,或者缺less有关如何使其工作的正确说明。
我的解决scheme具有以下function:
- 提供滑动视图以显示位于其下的菜单的支持
- 菜单和上面的视图都可以是任何自定义视图
- 支持旧的Android版本(至less在Android 2.2上testing过)
- 适用于PhoneGap / Cordova项目
该解决scheme使用名为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
是实际显示菜单的视图。 这是由你来实现这个观点。
最后,您可以添加一个button(通常位于主视图的左上angular),根据需要在布局上调用openMenu()
或closeMenu()
。
SlidingMenuLayout
的代码可以在GitHub 项目页面find 。
对于那些使用SlidingMenu库( 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);
基本上它是用linearlayout
代替装饰视图中的linearlayout
。
注意:我只testing过它,但它似乎工作。
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
。 可以用活动滑动