Google如何管理?(How did Google manage to do this? Slide ActionBar in Android application)

编程入门 行业动态 更新时间:2024-10-23 18:24:11
Google如何管理?(How did Google manage to do this? Slide ActionBar in Android application)

我真的想在我自己的应用程序中实现这个(侧面导航),有谁知道Google是如何设法实现的?

他们似乎把目前的窗户拉到一边,放进了自己的飞行导航。

I really want to implement this (the side navigation) in an app of my own, does anyone know how Google managed to do this?

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

最满意答案

其实有一个办法可以做到这一点。 即使没有实现自己的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>

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

而已!

而现在,它有一个截图:

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事件。

In fact, there's a way to do this. Even without implementing your own ActionBar.

Just have a look at the hierachyviewer! (Located in the tools directory)

There's the DecorView, and a LinearLayout as a child. This LinearLayout contains both the ActionBar and the other content. So, you can simply apply some FrameLayout.LayoutParams to this LinearLayout and get some space on the left side this way. Then, you can fill this space with your menu-ListView and overlay the other content with a FrameLayout, that, when it's clicked, collapses the menu. So, here's some code:

First, the class for collapsing / expanding (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; } }

Some helping methods (for me, in 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:

Layout of the menu (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>

How to use it:

In your onCreate():

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

In the handler for your ActionBar homebutton:

slidemenu.show();

That's it!

And now, a little screenshot of it in action:

SlideMenu

As far as I know, it is working. If you experience any problems or my explanations are not clear, please contact me!

EDIT: 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; } }

I use this SlideMenu for an Activity with a ViewPager with PagerTabStrip for tabs like Talk, Market etc. You can't disable these Views in an easy way, so the two classes above just extend them to stop the onTouch event when disabled.

更多推荐

本文发布于:2023-08-07 18:02:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1465103.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Slide   manage   Google   application   Android

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!