web-dev-qa-db-ja.com

Googleはどのようにしてこれを実現しましたか? AndroidアプリケーションでのActionBarのスライド

私は本当に自分のアプリにこれ(サイドナビゲーション)を実装したいのですが、Googleがこれをどうやってやったのか誰もが知っていますか?

彼らは、現在のウィンドウを脇に引っ張り、独自のフライインナビゲーションを行ったようです。

119
hwrdprkns

実際、これを行う方法があります。独自のActionBarを実装しなくても。

hierachyviewerをご覧ください。 (toolsディレクトリにあります)

DecorViewと、子としてLinearLayoutがあります。このLinearLayoutには、ActionBarとその他のコンテンツの両方が含まれています。したがって、このLinearLayoutにいくつかのFrameLayout.LayoutParamsを適用するだけで、この方法で左側にスペースを確保できます。次に、このスペースをmenu-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>

リストアイテムのレイアウト(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

私の知る限り、それは機能しています。問題が発生した場合や説明が明確でない場合は、ご連絡ください!

編集:ExtendedViewPagerExtendedPagerStrip

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

このSlideMenuViewPagerのアクティビティに使用し、PagerTabStripをTalk、Marketなどのタブに使用します。これらのビューを簡単な方法で無効にすることはできません。無効になったらonTouchイベントを停止するように拡張します。

150
Scirocco

これを行うにはいくつかの試みがありますが、すべてのAPIレベルでactionbarを使用してそれを正常に実装する方法についてのlibまたはソースコードをまだ見つけていません。 1つの有望なライブラリはこちら

https://github.com/jfeinstein10/SlidingMen

アプリの例 のビデオです。

Google Play アプリリンクです。

これはActionbarSherlockで機能します。それを機能させるには、ABSでSlidingMenuライブラリを構築する必要があります。動作し、見栄えがいい!

21
Patrick

元の実装 のまとめを行い、XML解析と、存在する可能性のあるautodetectionactionbarを追加したため、ネイティブおよびサポートアクションバーなどで機能します。 ActionBarSherlockとして。

全体がライブラリプロジェクトであり、サンプルアプリと一緒に Androidのスライドメニュー に感謝します scirocco 最初のアイデアとコードについて!

LibSlideMenu Screenshot

8
bk138

11を超えるAPIレベルを使用している場合、 @ Sciroccoによる回答 に触発されたより単純なアプローチを使用できます

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

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

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

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

ここでの考え方は、メインのレイアウトをアクションバーでアニメーション化するだけでなく、変換するValueAnimatorを使用することです。これにより、スライドパネルとして使用する拡大表示を操作できます。ハードコードされた値は、アプリで使用できるものに置き換える必要があります。

これが役立つことを願っています:)

7
Medo

現在、プロジェクトに取り組んでいて、スライディングメニューに出会いましたが、グーグルで検索しましたが、スライディングメニューの作成を開始するためのコードやヒントを誰も与えていないことに非常に失望しましたが、使用するgithubのプロジェクト/ライブラリ、私は自分でそれをすることにし、最終的に私は自分のスライドメニューの準備ができて...

私は2日間過ごしました

1。スライドのアニメーション作成時

2。すべての画面解像度で動作させる場合

アニメーションについてのアイデアが得られたら、本当に簡単で簡単です。Wheel(githubソースを参照している人々を再発明することは賢明ではありません。スライドメニューのコード)、しかし、私はあなたがそれを実際にどのように機能させ、どのように機能するかのアイデアを得るために少なくとも一度あなた自身を作ろうとするべきであると信じています:P

これは、スライドメニューがどのように機能するかを示す写真です

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

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


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

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

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

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

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

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

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

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

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

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

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


        </RelativeLayout>

    </RelativeLayout>

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

    </GridView>

    </RelativeLayout>

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

enter image description here

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

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

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

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

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

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

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

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

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

        </RelativeLayout>


    </RelativeLayout>

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

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

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

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

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

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


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

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

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


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

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

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


    </RelativeLayout>



    </RelativeLayout>

    </ScrollView>



</RelativeLayout>

enter image description here

find.xmlに含まれているfilter.xml最初は見えない

FilterAnimation.Java

package matchat.helpers;

import com.s3.matchat.R;

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

public class FilterAnimation implements AnimationListener 
{
    Context context;

    RelativeLayout filterLayout, otherLayout;

    private Animation filterSlideIn, filterSlideOut, otherSlideIn, otherSlideOut;

    private static int otherLayoutWidth, otherLayoutHeight;

    private boolean isOtherSlideOut = false;

    private int deviceWidth;

    private int margin;

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

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

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

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

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

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

    }

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

        otherLayoutWidth = otherLayout.getWidth();

        otherLayoutHeight = otherLayout.getHeight();


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

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

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

            filterLayout.setVisibility(View.INVISIBLE);

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

            filterLayout.setVisibility(View.VISIBLE);

            filterLayout.startAnimation(filterSlideIn);
        }
    }

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

            otherLayout.setLayoutParams(params);

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



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

            params.leftMargin = margin;

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

            otherLayout.setLayoutParams(params);

            isOtherSlideOut = true;

            dimOtherLayout();
        }
    }

    @Override
    public void onAnimationRepeat(Animation animation) 
    {

    }

    @Override
    public void onAnimationStart(Animation animation) 
    {

    }

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

        alphaAnimation.setFillAfter(true);

        otherLayout.startAnimation(alphaAnimation);
    }

}

現在の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;
        }
    } 

}

こちらがアニメーションres/animです

1.filter_slide_in.xml

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

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

</set>

2.filter_slide_out.xml

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

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

</set>

.other_slide_in.xml

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

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

</set>

4.other_slide_out.xml

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

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

</set>

そこには完全に機能する機能的なスライドメニューがあり、要件に合わせてカスタマイズできます。セットアップにまだ問題がある場合は、お気軽にお問い合わせください。喜んでお手伝いいたします:)

6
Muhammad Babar

他の多くのソリューションが古いAndroidバージョンで動作しないように見えるか、動作させる方法に関する適切な指示がなかったため、ビューをスライドさせて下にメニューを表示する独自のソリューションを作成しました。

私のソリューションには次の機能があります。

  • ビューをスライドさせて、その下にあるメニューを表示するサポートを提供します
  • 上記のメニューとビューは、任意のカスタムビューにすることができます
  • 古いAndroidバージョンでサポート(少なくともAndroid 2.2で動作することがテスト済み)
  • PhoneGap/Cordovaプロジェクトで動作します

ソリューションでは、SlidingMenuLayoutというカスタムレイアウトを使用します。このレイアウトには、2つのビューを追加することが期待されています。追加する最初のビューはメニューで、2番目はメインビューです。

既存のプロジェクトにレイアウトを追加する最も簡単な方法は、アクティビティのsetContentView()メソッドをオーバーライドすることです:

@Override
public void setContentView(View view) {
    SlidingMenuLayout layout = new SlidingMenuLayout(this);
    layout.setLayoutParams(new LinearLayout.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT, 
        0.0F));
    layout.addView(new MenuView(this));
    layout.addView(view);
    super.setContentView(layout);
}

この例では、MenuViewは実際にメニューを表示するビューです。このビューを実装するのはあなた次第です。
最後に、必要に応じてレイアウト上のopenMenu()またはcloseMenu()を呼び出すボタン(通常はメインビューの左上隅)を追加できます。
SlidingMenuLayoutのコードは、GitHub プロジェクトページ にあります。

5
arendjr

SlidingMenuライブラリ(- https://github.com/jfeinstein10/SlidingMen )を使用している人にはそれをジャックする方法とそれはうまくいくようです! @Sciroccoの助けを借りて、これをアクティビティのonCreateに追加します。

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

基本的に、装飾ビューのlinearlayoutを代わりにslidingmenuに置き換えます。

注意:私はそれを軽くテストしただけですが、うまくいくようです。

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

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

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

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

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

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

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

}

これは私のクラスがSlidingPaneLayoutを拡張したものです。アクションでスライドできます

0
user2212515