Bagaimana Google bisa melakukan ini? Geser ActionBar di aplikasi Android

118

Saya benar-benar ingin menerapkan ini (navigasi samping) di aplikasi saya sendiri, apakah ada yang tahu bagaimana Google berhasil melakukan ini?

Mereka tampaknya telah menarik jendela saat ini ke samping dan membuat navigasi terbang mereka sendiri.

hwrdprkns
sumber
Saya kira mereka hanya memiliki tata letak yang berisi 2 tata letak: 1 adalah aplikasi utama, dan yang lainnya adalah bilah sisi. Saat bilah sisi diaktifkan, itu mendorong tata letak aplikasi utama ke samping. Ini hanya tebakan, jadi saya tidak mengatakannya sebagai jawaban.
Eric
1
Saya yakin seseorang menanyakan hal ini pada sesi Tanya Jawab setelah pembicaraan "Apa yang baru di Android" di IO. Versi rekaman belum tersedia, dan sayangnya saya tidak ingat apa jawabannya.
Bryan Herbst
3
@ Tanis.7x Jawabannya cukup banyak karena mereka belum merencanakan komponen kerangka untuk menu ini, tetapi Anda dapat menemukan serangkaian posting blog yang bagus di sini (sejauh yang saya ingat) .
1
Saya membaca posting blog itu. Mereka mengatakan bahwa mereka menerapkan bilah tindakan khusus. Sekarang ini terdengar masuk akal oleh pengembang tetapi bukan oleh Google yang meretas apinya sendiri!
Matroska
2
Jawaban atas pertanyaan ini sekarang "quazi" sudah ketinggalan zaman. Google sekarang telah memperkenalkan Panel Samping Navigasi, dan pendekatannya akan berbeda dari yang saat ini terdaftar.
Mengejar Florell

Jawaban:

150

Sebenarnya, ada cara untuk melakukan ini. Bahkan tanpa menerapkan Anda sendiri ActionBar.

Lihat saja hierachyviewer! (Terletak di direktori alat)

Ada DecorView, dan LinearLayoutsebagai seorang anak. Ini LinearLayoutberisi ActionBarkonten dan konten lainnya. Jadi, Anda cukup menerapkan beberapa FrameLayout.LayoutParamsuntuk ini LinearLayoutdan mendapatkan ruang di sisi kiri dengan cara ini. Kemudian, Anda dapat mengisi ruang ini dengan menu-ListView Anda dan menghamparkan konten lainnya dengan FrameLayout, yang, saat diklik, menciutkan menu. Jadi, inilah beberapa kodenya:

Pertama, kelas untuk menciutkan / meluaskan (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;
}
}

Beberapa metode bantuan (bagi saya, di Functions.java statis):

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

Kemudian, tata letak:

Tata letak 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>

Tata letak 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>

Bagaimana cara menggunakannya:

Di Anda onCreate():

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

Di handler untuk tombol beranda ActionBar Anda:

slidemenu.show();

Itu dia!

Dan sekarang, tangkapan layar kecil itu beraksi:

SlideMenu

Sejauh yang saya tahu, ini berhasil. Jika Anda mengalami masalah atau penjelasan saya tidak jelas, silakan hubungi saya!

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

Saya menggunakan ini SlideMenuuntuk Aktivitas dengan ViewPagerdengan PagerTabStripuntuk tab seperti Talk, Market, dll. Anda tidak dapat menonaktifkan Tampilan ini dengan cara yang mudah, jadi dua kelas di atas hanya memperluasnya untuk menghentikan onTouchacara saat dinonaktifkan.

Scirocco
sumber
1
Terlihat bagus, tapi dari mana ExtendedViewPager dan ExtendedPagerTabStrip berasal?
bk138
1
Keren, terima kasih untuk file tambahannya, saya akan mencoba mengubahnya menjadi lib dan memposting di github.
bk138
Saya menduga Anda harus meletakkan extendedViewPager dan extendedPagerTabStrip di XML untuk aktivitas Anda, bukan? Contoh di atas mencari R.id.viewpager
Patrick
2
Hai, kami telah mengumpulkan implementasi asli sciroccos dan menambahkan penguraian XML serta deteksi otomatis dari bilah tindakan yang mungkin ada. Semuanya sekarang menjadi proyek perpustakaan bersama dengan aplikasi contoh dan dijelaskan di coboltforge.com/2012/07/… . Terima kasih kepada @Scirocco untuk ide awalnya!
bk138
1
Saya menerapkan metode ini dan berfungsi di Android 4.1, tetapi di Android 2.3 tidak? apakah itu dibangun hanya untuk versi android yang lebih tinggi?
Iulia Barbu
21

Ada beberapa upaya untuk melakukan ini, namun saya belum menemukan lib atau kode sumber tentang cara mengimplementasikannya dengan sukses dengan actionbar di semua level api. Satu lib yang menjanjikan ada di sini

https://github.com/jfeinstein10/SlidingMenu

berikut adalah video dari aplikasi contoh .

di sini adalah tautan aplikasi Google Play .

Ini berfungsi dengan ActionbarSherlock. Anda harus membangun perpustakaan SlidingMenu dengan ABS untuk membuatnya berfungsi. Berfungsi dan tampak hebat!

Patrick
sumber
2
Sementara kode di atas umumnya akan berfungsi, saya dapat mengatakan tanpa ragu bahwa perpustakaan ini adalah solusi drop-in yang bagus untuk masalah ini. Ini benar-benar mulai tumbuh pada saya sebagai solusi siap pakai untuk menerapkan side-nav.
hwrdprkns
Setuju bahwa pustaka ini sangat membantu kami - sangat mudah digunakan, menyediakan banyak opsi konfigurasi, berfungsi pada banyak level API, dan berfungsi baik dengan ActionBarSherlock!
greg7gkb
8

Melakukan pembulatan dari implementasi asli dan menambahkan parsing XML serta autodetectionyang mungkin ada actionbar, sehingga berfungsi dengan native serta bilah tindakan dukungan seperti ActionBarSherlock.

Semuanya sekarang menjadi proyek perpustakaan bersama dengan aplikasi contoh dan dijelaskan di Sliding Menu untuk android Terima kasih kepada scirocco untuk ide dan kode awal!

Tangkapan Layar LibSlideMenu

bk138
sumber
Saya perlu mengatur menu slide sebagai layar pertama. Yaitu ketika pengguna masuk ke aplikasi, dia akan melihat menu slide terlebih dahulu. Adakah solusi untuk itu?
Sujiz
1
setAsShown () ditambahkan dengan github.com/bk138/LibSlideMenu/commit/… harus melakukan triknya.
bk138
Pekerjaan yang baik! Saya ingin menambahkan item sub menu (misalnya, periksa aplikasi facebook). Jadi saat memilih item menu dengan sub item, menu harus dianimasikan ke kanan. Adakah tips untuk menerapkan ini?
Luciano
@Luizje: Saya kira Anda harus menggunakan tampilan yang mirip seperti SlideMenu, tetapi lebih kecil dan menggunakan animasi untuk itu. Saya akan senang untuk menggabungkan patch apa pun yang mungkin Anda miliki :-)
bk138
7

Jika Anda menggunakan API level yang lebih tinggi dari 11, Anda dapat menggunakan pendekatan yang lebih sederhana yang terinspirasi oleh jawaban yang diberikan oleh @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);

Idenya di sini adalah menggunakan ValueAnimatoryang mengubah dan tidak hanya menganimasikan tata letak utama dengan bilah Tindakan, sehingga Anda dapat berinteraksi dengan tampilan yang diperbesar yang ingin Anda gunakan sebagai panel geser. Anda harus mengganti nilai hardcode dengan sesuatu yang berguna untuk aplikasi Anda.

Saya harap ini membantu :)

Medo
sumber
6

Nah saat ini saya sedang mengerjakan sebuah proyek dan menemukan menu Sliding, saya mencari di Google tetapi sangat kecewa melihat bahwa tidak ada yang memberikan beberapa kode atau petunjuk tentang cara mulai membuat menu geser, tetapi setiap orang telah memberikan tautan ke beberapa proyek / perpustakaan github untuk digunakan, saya memutuskan untuk melakukannya sendiri dan akhirnya saya memiliki Menu Geser yang Siap ...

Saya telah menghabiskan dua hari untuk itu

1. pada pembuatan animasi sliding

2. untuk membuatnya bekerja dengan semua resolusi layar

Ini sangat mudah dan sederhana setelah Anda mendapatkan ide tentang Animasi , saya telah membaca beberapa di mana, tidak masuk akal untuk menemukan kembali Roda (orang-orang yang merujuk ke kode sumber github dari menu geser), tetapi saya percaya bahwa Anda harus setidaknya sekali cobalah membuatnya sendiri sehingga Anda mendapatkan gambaran bagaimana sebenarnya itu bekerja dan berfungsi: P

jadi ini adalah gambaran bagaimana menu geser saya akan bekerja

1. Temukan.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>

masukkan deskripsi gambar di sini

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>

masukkan deskripsi gambar di sini

Dalam find.xml saya telah menyertakan filter.xml pada awalnya yang tidak terlihat

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

}

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

}

Berikut adalah animasinya 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>

3. slide_lain_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.out_luncur_lain.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>

Ini dia Menu Geser yang berfungsi dan berfungsi lengkap, dan Anda dapat menyesuaikannya untuk memenuhi kebutuhan Anda, jika ada yang masih memiliki masalah pengaturan, jangan ragu untuk bertanya, saya merasa senang untuk membantu Anda :)

Muhammad Babar
sumber
4
Meskipun saya bukan penggemar penemuan kembali roda , saya menghargai jawaban yang dipikirkan dengan matang dan lengkap yang Anda berikan di sini.
hwrdprkns
@hwrdprkns itu lelucon ... yang ingin saya katakan adalah bahwa setiap orang harus mengadopsi perilaku belajar & melaksanakan :)
Muhammad Babar
@hwrdprkns +1 untuk postingan yang bagus tentang penemuan kembali roda
Muhammad Babar
5

Saya telah membuat solusi saya sendiri untuk menggeser tampilan dan menampilkan menu di bawahnya, karena banyak solusi lain yang tampaknya tidak berfungsi pada versi Android yang lebih lama atau tidak memiliki instruksi yang tepat tentang cara membuatnya berfungsi.

Solusi saya memiliki beberapa fitur berikut:

  • Memberikan dukungan untuk menggeser pandangan untuk menampilkan menu yang terletak di bawahnya
  • Baik menu dan tampilan di atas dapat berupa Tampilan kustom apa pun
  • Didukung pada versi Android lama (diuji untuk bekerja setidaknya pada Android 2.2)
  • Bekerja dengan proyek PhoneGap / Cordova

Solusinya menggunakan tata letak kustom, yang disebut SlidingMenuLayout, yang Anda diharapkan untuk menambahkan 2 tampilan. Tampilan pertama yang Anda tambahkan adalah menu, yang kedua adalah tampilan utama.

Cara termudah untuk menambahkan layout ke proyek Anda yang sudah ada adalah dengan mengganti setContentView()metode Activity Anda :

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

Dalam contoh ini, MenuViewadalah tampilan yang akan menampilkan menu. Terserah Anda untuk mengimplementasikan tampilan ini.
Terakhir, Anda dapat menambahkan tombol (biasanya di sudut kiri atas tampilan utama Anda), yang memanggil openMenu()atau closeMenu()pada tata letak yang sesuai.
Kode untuk SlidingMenuLayoutditemukan di halaman proyek GitHub .

arendjr
sumber
Hai, Saya menyukai solusi Anda, saya sedang mengerjakan ponsel 2.2, ini menggeser tata letak "utama" tetapi juga menampilkan tata letak "menu" bahkan ketika saya menutup "menu". Ada alasan kenapa?
Veer
Saya mengalami masalah yang sama, cukup pastikan bahwa tata letak "utama" memiliki warna latar belakang dan akan berfungsi dengan baik.
iTech
3

Bagi Anda yang menggunakan pustaka SlidingMenu ( https://github.com/jfeinstein10/SlidingMenu ) ada cara untuk memasukkannya dan tampaknya berhasil! Dengan bantuan @Scirocco, masukkan ini onCreateke dalam aktivitas Anda:

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

pada dasarnya apa yang dilakukannya adalah mengganti tampilan linearlayoutdalam dekorasi dengan sebagai slidingmenugantinya.

Perhatikan: Saya hanya mengujinya dengan ringan tetapi tampaknya berhasil.

Hirschen
sumber
0
    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;
    }

}

ini kelasku meluas SlidingPaneLayout. Bisa meluncur dengan actio

pengguna2212515
sumber
Saya telah mencoba mengganti tag <android.support.v4.widget.SlidingPaneLayout> di layout xml dengan kelas Anda, tetapi tidak ada yang berubah. Masih meluncur tanpa actionbar. Apakah Anda melakukan hal lain dan tidak menyebutkan di sini? Terima kasih!
Amir Uval