Android實(shí)現(xiàn)3種側(cè)滑效果(仿qq側(cè)滑、抽屜側(cè)滑、普通側(cè)滑)
自己實(shí)現(xiàn)了一下側(cè)滑的三種方式(注釋都寫代碼里了)
本文Demo下載地址:Andriod側(cè)滑
本文實(shí)現(xiàn)所需框架:nineoldandroids下載地址:nineoldandroids
1.普通側(cè)滑:
主要是基于HorizontalScrollView做的:示例代碼如下
主要布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:gaoyu="http://schemas.android.com/apk/res/gaoyu.com.myapplication" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_qqsideslip" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="gaoyu.com.myapplication.sideslip.QQSideslipActivity"> <!--xmlns:gaoyu自定義命名空間 原有到res+包名--> <gaoyu.com.myapplication.sideslip.SlidingMenu_qq android:id="@+id/SlMenu_sideslip" android:layout_width="wrap_content" android:layout_height="fill_parent" gaoyu:rightPadding="100dp"> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal"> <include layout="@layout/sideslip_menu" /> <!--這個(gè)LinearLayout就是content--> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/sliding"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClick_sideslip_qq" android:text="切換菜單" /> </LinearLayout> </LinearLayout> </gaoyu.com.myapplication.sideslip.SlidingMenu_qq> </RelativeLayout>
菜單的布局
<?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" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_centerInParent="true"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/iv_sideslip1" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginTop="20dp" android:layout_marginBottom="20dp" android:layout_marginLeft="20dp" android:src="@drawable/icon"/> <TextView android:layout_centerVertical="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/iv_sideslip1" android:layout_marginLeft="20dp" android:text="第一個(gè)item"/> </RelativeLayout> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/iv_sideslip2" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginTop="20dp" android:layout_marginBottom="20dp" android:layout_marginLeft="20dp" android:src="@drawable/icon"/> <TextView android:layout_centerVertical="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/iv_sideslip2" android:layout_marginLeft="20dp" android:text="第二個(gè)item"/> </RelativeLayout><RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/iv_sideslip3" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginTop="20dp" android:layout_marginBottom="20dp" android:layout_marginLeft="20dp" android:src="@drawable/icon"/> <TextView android:layout_centerVertical="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/iv_sideslip3" android:layout_marginLeft="20dp" android:text="第三個(gè)item"/> </RelativeLayout><RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/iv_sideslip4" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginTop="20dp" android:layout_marginBottom="20dp" android:layout_marginLeft="20dp" android:src="@drawable/icon"/> <TextView android:layout_centerVertical="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/iv_sideslip4" android:layout_marginLeft="20dp" android:text="第四個(gè)item"/> </RelativeLayout><RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/iv_sideslip5" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginTop="20dp" android:layout_marginBottom="20dp" android:layout_marginLeft="20dp" android:src="@drawable/icon"/> <TextView android:layout_centerVertical="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/iv_sideslip5" android:layout_marginLeft="20dp" android:text="第五個(gè)item"/> </RelativeLayout> </LinearLayout> </RelativeLayout>
定義view類
public class SlidingMenu_qq extends HorizontalScrollView { private LinearLayout mWapper; private ViewGroup mMenu; private ViewGroup mContent; //menu的寬度 private int mMenuWidth; //屏幕的寬度(內(nèi)容區(qū)的寬度就是屏幕寬度) private int mScreenWdith; //菜單與右邊的距離50dp private int mMenuRightPidding = 50; //調(diào)用一次 private boolean once; //標(biāo)識(shí)狀態(tài) private boolean isOPen; /** * 未使用自定義屬性時(shí)調(diào)用 * 由于設(shè)置了attr所以... * * @param context * @param attrs */ public SlidingMenu_qq(Context context, AttributeSet attrs) { //調(diào)用三個(gè)參數(shù)的構(gòu)造方法 this(context, attrs, 0); //獲取屏幕寬度(窗口管理器) /*WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); //展示度量 DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); mScreenWdith = outMetrics.widthPixels; //把dp轉(zhuǎn)換成px mMenuRightPidding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources().getDisplayMetrics()); */ } /** * 當(dāng)實(shí)現(xiàn)自定義屬性時(shí)會(huì)執(zhí)行三個(gè)參數(shù)的方法 * * @param context * @param attrs * @param defStyleAttr */ public SlidingMenu_qq(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //獲取自定義的屬性 TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SlidingMenu_qq, defStyleAttr, 0); //自定義屬性個(gè)數(shù) int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.SlidingMenu_qq_rightPadding: //設(shè)置默認(rèn)值是50dp mMenuRightPidding = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources().getDisplayMetrics())); break; } } //釋放一下 a.recycle(); //獲取屏幕寬度(窗口管理器) WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); //展示度量 DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); mScreenWdith = outMetrics.widthPixels; } /** * new 一個(gè)TextView時(shí)傳一個(gè)上下文 * * @param context */ public SlidingMenu_qq(Context context) { //調(diào)用兩個(gè)參數(shù)的構(gòu)造方法 super(context, null); } /** * 設(shè)置HorizontalScrollView子VIew的寬和高 * 設(shè)置HorizontalScrollView自己的寬和高 * * @param widthMeasureSpec * @param heightMeasureSpec */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //設(shè)置循環(huán)之調(diào)用一次 if (!once) { //HorizontalScrollView 內(nèi)部只能有一個(gè)元素 所以直接get(0)就行就是那個(gè)Linerlayout mWapper mWapper = (LinearLayout) getChildAt(0); //獲取mWapper里的第一個(gè)元素menu mMenu = (ViewGroup) mWapper.getChildAt(0); //獲取mWapper里的第二個(gè)元素content mContent = (ViewGroup) mWapper.getChildAt(1); //菜單和內(nèi)容寬度 mMenuWidth = mMenu.getLayoutParams().width = mScreenWdith - mMenuRightPidding; mContent.getLayoutParams().width = mScreenWdith; //由于子對(duì)象被設(shè)置了,mWapper就先不用了 once = true; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } /** * 通過設(shè)置偏移量 將menu隱藏 * @param changed * @param l * @param t * @param r * @param b */ @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); //限制多次調(diào)用 if (changed) { //x為正滾動(dòng)條向右 內(nèi)容向左(移動(dòng)mMenuWidth 正好將菜單隱藏) this.scrollTo(mMenuWidth, 0); } } /** * 判斷將菜單滑出來多少了 * * @param ev * @return */ @Override public boolean onTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_UP: //隱藏在左邊的寬度 int scrollX = getScrollX(); if (scrollX >= mMenuWidth / 2) { //scrollTo也行但是動(dòng)畫效果不好 (隱藏) this.smoothScrollTo(mMenuWidth, 0); //代表菜單隱藏 isOPen = false; } else { this.smoothScrollTo(0, 0); //表菜單打開 isOPen = true; } return true; } return super.onTouchEvent(ev); } /** * 打開菜單 */ public void openMenu() { //已經(jīng)打開 if (isOPen) return; this.smoothScrollTo(0, 0); isOPen = true; } /** * 關(guān)閉菜單 */ public void closeMenu() { //正在打開 if (!isOPen) return; this.smoothScrollTo(mMenuWidth, 0); isOPen = false; } /** * 切換菜單 */ public void toggle(){ if (isOPen){ closeMenu(); }else { openMenu(); } } }
2.抽屜側(cè)滑(添加此方法)
/** * 實(shí)現(xiàn)抽屜滑動(dòng) * l隱藏在左邊的寬度 * 后邊是變化梯度 */ @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); float scale = l*1.0f/mMenuWidth;//1~0梯度的值 //調(diào)用屬性動(dòng)畫 ViewHelper.setTranslationX(mMenu,mMenuWidth*scale); }
3.qq5.0側(cè)滑,實(shí)現(xiàn)這個(gè)方法
/** * 實(shí)現(xiàn)仿qq5.0 * l等于隱藏在左邊的寬度(越來越?。? * 后邊是變化梯度 */ @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); float scale = l * 1.0f / mMenuWidth;//1~0梯度的值 //調(diào)用屬性動(dòng)畫 //菜單的縮放操作 float leftScale = 1.0f-scale*0.3f; //透明度 float leftAlpha = 0.6f + 0.4f*(1-scale); ViewHelper.setTranslationX(mMenu, mMenuWidth * scale*0.8f); ViewHelper.setScaleX(mMenu,leftScale); ViewHelper.setScaleY(mMenu,leftScale); ViewHelper.setAlpha(mMenu,leftAlpha); //內(nèi)容區(qū)域不斷縮小 float rightScale = 0.7f+0.3f*scale; //橫向縱向縮放(不更改縮放中心點(diǎn)就全隱藏了) ViewHelper.setPivotX(mContent,0); ViewHelper.setPivotY(mContent,mContent.getHeight()/2); ViewHelper.setScaleX(mContent,rightScale); ViewHelper.setScaleY(mContent,rightScale); }
更多學(xué)習(xí)內(nèi)容,可以點(diǎn)擊《Android側(cè)滑效果匯總》學(xué)習(xí)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android解決viewpager嵌套滑動(dòng)沖突并保留側(cè)滑菜單功能
- Android仿微信聯(lián)系人列表字母?jìng)?cè)滑控件
- Android_UI 仿QQ側(cè)滑菜單效果的實(shí)現(xiàn)
- Android 仿京東側(cè)滑篩選實(shí)例代碼
- android RecyclerView側(cè)滑菜單,滑動(dòng)刪除,長(zhǎng)按拖拽,下拉刷新上拉加載
- Android recyclerview實(shí)現(xiàn)拖拽排序和側(cè)滑刪除
- android的RecyclerView實(shí)現(xiàn)拖拽排序和側(cè)滑刪除示例
- Android側(cè)滑導(dǎo)航欄的實(shí)例代碼
- Android 側(cè)滑關(guān)閉Activity的實(shí)例
相關(guān)文章
android開發(fā)教程之開機(jī)啟動(dòng)服務(wù)service示例
如果開機(jī)啟動(dòng)一個(gè)Activity,開機(jī)首先看的界面,是你的程序界面,如果為了,開機(jī)后也啟動(dòng)你的程序,但是不顯示自己程序的界面,就要用Service服務(wù),下面是開機(jī)啟動(dòng)服務(wù)service示例2014-03-03Android實(shí)現(xiàn)多維商品屬性SKU選擇
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)多維商品屬性SKU選擇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10Android中對(duì)RecyclerView Adapter封裝解析
本篇文章主要介紹了Android中對(duì)RecyclerView Adapter封裝解析。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06Android性能調(diào)優(yōu)利器StrictMode應(yīng)用分析
StrictMode意思為嚴(yán)格模式,是用來檢測(cè)程序中違例情況的開發(fā)者工具。最常用的場(chǎng)景就是檢測(cè)主線程中本地磁盤和網(wǎng)絡(luò)讀寫等耗時(shí)的操作。這篇文章給大家介紹Android性能調(diào)優(yōu)利器StrictMode應(yīng)用分析,感興趣的朋友一起看看吧2018-01-01Android使用socket創(chuàng)建簡(jiǎn)單TCP連接的方法
這篇文章主要介紹了Android使用socket創(chuàng)建簡(jiǎn)單TCP連接的方法,結(jié)合實(shí)例形式詳細(xì)分析了Android使用socket創(chuàng)建TCP連接的具體步驟與實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-04-04解決在eclipse中將android項(xiàng)目生成apk并且給apk簽名的實(shí)現(xiàn)方法詳解
本篇文章是對(duì)在eclipse中將android項(xiàng)目生成apk并且給apk簽名的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05Android Camera2 實(shí)現(xiàn)預(yù)覽功能
最近在做一些關(guān)于人臉識(shí)別的項(xiàng)目,需要用到 Android 相機(jī)的預(yù)覽功能。今天小編通過本文給大家分享Android Camera2 實(shí)現(xiàn)預(yù)覽功能,感興趣的朋友跟隨小編一起看看吧2018-11-11Android讀取手機(jī)通訊錄聯(lián)系人到自己項(xiàng)目
這篇文章主要為大家詳細(xì)介紹了Android讀取手機(jī)通訊錄聯(lián)系人到自己項(xiàng)目,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07Android RecyclerView添加搜索過濾器的示例代碼
本篇文章主要介紹了Android RecyclerView添加搜索過濾器的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01Android中dip、dp、sp、pt和px的區(qū)別詳解
本篇文章是對(duì)Android中dip、dp、sp、pt和px的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06