Je souhaite vraiment implémenter cette fonctionnalité (la navigation latérale) dans une application personnelle. Quelqu'un sait-il comment Google a réussi à le faire?
Ils semblent avoir écarté la fenêtre actuelle et mis en place leur propre système de navigation.
En fait, il existe un moyen de le faire. Même sans implémenter votre propre ActionBar
.
Il suffit de regarder le hierachyviewer
! (Situé dans le répertoire des outils)
Il y a le DecorView
et un LinearLayout
en tant qu'enfant. Ce LinearLayout
contient à la fois le ActionBar
et l'autre contenu. Donc, vous pouvez simplement appliquer un peu de FrameLayout.LayoutParams
À ce LinearLayout
et obtenir de l’espace sur le côté gauche de cette façon. Ensuite, vous pouvez remplir cet espace avec votre menu-ListView et superposer l'autre contenu avec un FrameLayout, qui, lorsqu'il est cliqué, réduit le menu. Alors, voici un code:
Tout d’abord, la classe pour réduire/développer (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;
}
}
Quelques méthodes d'aide (pour moi, dans Functions.Java statique):
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);
}
}
}
}
Ensuite, les mises en page:
Mise en page du 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>
Mise en page des éléments de liste (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>
Comment l'utiliser:
Dans votre onCreate()
:
private SlideMenu slidemenu;
@Override
public void onCreate(Bundle savedInstanceState) {
//your onCreate code
slidemenu = new SlideMenu(this);
slidemenu.checkEnabled();
}
Dans le gestionnaire de votre homebutton ActionBar:
slidemenu.show();
C'est ça!
Et maintenant, une petite capture d'écran en action:
Pour autant que je sache, cela fonctionne. Si vous rencontrez des problèmes ou si mes explications ne sont pas claires, contactez-moi!
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;
}
}
J'utilise ce SlideMenu
pour une activité avec un ViewPager
avec PagerTabStrip
pour des onglets tels que Talk, Market, etc. Vous ne pouvez pas désactiver ces affichages de manière simple. Les classes ci-dessus les étendent simplement pour arrêter l'événement onTouch
lorsqu'il est désactivé.
Il y a plusieurs tentatives , mais je n'ai pas encore trouvé de code source ni de code source sur la façon de le mettre en œuvre avec succès avec actionbar à travers tous les niveaux de l'API. Une lib prometteuse est ici
https://github.com/jfeinstein10/SlidingMen
voici une vidéo de la exemple d'application .
voici le lien Google Play app.
Cela fonctionne avec ActionbarSherlock. Vous devrez construire la bibliothèque SlidingMenu avec ABS pour le faire fonctionner. Fonctionne et est superbe!
A fait un résumé de implémentation d'origine et ajouté l'analyse XML ainsi que autodetection
d'un éventuellement présent actionbar
, de sorte qu'il fonctionne à la fois en natif et avec une action de support bar tel que ActionBarSherlock
.
Le tout est maintenant un projet de bibliothèque associé à un exemple d'application. Il est décrit ci-après à l'adresse menu coulissant pour Android Merci à scirocco pour l'idée initiale et le code!
Si vous utilisez un niveau d'API supérieur à 11, vous pouvez utiliser une approche beaucoup plus simple inspirée par le réponse donnée par @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);
L'idée ici est d'utiliser ValueAnimator
qui transforme et non seulement animer la mise en page principale avec la barre d'actions, afin que vous puissiez interagir avec la vue gonflée que vous souhaitez utiliser en tant que panneau coulissant. Vous devez remplacer les valeurs codées en dur par quelque chose d’utile pour votre application.
J'espère que ça aide :)
Actuellement, je travaille sur un projet et je suis tombé sur le menu coulissant. J’ai cherché sur Google, mais j’ai été très déçu de constater que personne n’a donné de code ou quelque indice sur la façon de commencer à créer un menu coulissant, mais chacun a donné un lien vers certains. Les projets/bibliothèques de github à utiliser, j'ai décidé de le faire moi-même et j'ai enfin mon propre menu coulissant prêt ...
J'ai passé deux jours dessus
1. Faire des animations de glisse
2. sur le faire fonctionner avec toutes les résolutions d'écran
C'est vraiment facile et simple une fois que vous avez une idée de Animations, j'en ai lu où, il n'est pas judicieux de réinventer le Wheel (les gens qui font référence à la source github code du menu glissant), mais je crois que vous devriez au moins essayer de faire le vôtre afin d’avoir une idée de son fonctionnement et de ses fonctions: P
c'est donc une image de la façon dont mon menu coulissant va fonctionner
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>
Dans find.xml j'ai inclus filter.xml ce qui est initialement invisible
Maintenant 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);
}
}
maintenant 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;
}
}
}
Voici les animations 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>
Vous y trouverez un menu coulissant complet, fonctionnel et fonctionnel, que vous pourrez personnaliser en fonction de vos besoins. Si vous rencontrez encore des problèmes d’installation, n'hésitez pas à demander, je me ferai un plaisir de vous aider :)
J'ai créé ma propre solution pour dissimuler la vue et afficher un menu sous-jacent, de nombreuses autres solutions semblant ne pas fonctionner avec les versions antérieures Android ou manquant d'instructions sur la façon de la faire fonctionner .
Ma solution présente les caractéristiques suivantes:
La solution utilise une présentation personnalisée, appelée SlidingMenuLayout, à laquelle vous devez ajouter 2 vues. La première vue que vous ajoutez est le menu, la seconde est la vue principale.
Le moyen le plus simple d’ajouter la mise en page à votre projet existant consiste à remplacer la méthode setContentView()
de votre activité:
@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);
}
Dans cet exemple, MenuView
est la vue qui affichera le menu. C'est à vous de mettre en œuvre cette vue.
Enfin, vous pouvez ajouter un bouton (généralement situé dans le coin supérieur gauche de votre vue principale), appelant openMenu()
ou closeMenu()
de la présentation, selon le cas.
Le code pour SlidingMenuLayout
se trouve sur le GitHub page du projet .
Pour ceux d’entre vous qui utilisent la bibliothèque SlidingMenu ( https://github.com/jfeinstein10/SlidingMen ), il existe un façon de le brancher et il semble fonctionner! Avec l'aide de @Scirocco, mettez ceci dans votre onCreate
pour l'activité:
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);
en gros, elle remplace le linearlayout
dans la vue décor par le slidingmenu
à la place.
Remarque: je l’ai seulement testé légèrement mais cela semble fonctionner.
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;
}
}
c'est ma classe s'étend SlidingPaneLayout
. Peut glisser avec l'action