欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android仿QQ6.0主頁面?zhèn)然Ч?/h1>
 更新時間:2016年11月02日 10:11:51   作者:z240336124  
這篇文章主要為大家詳細介紹了Android仿QQ6.0主頁面?zhèn)然Ч?具有一定的參考價值,感興趣的小伙伴們可以參考一下

1.概述

  最近一直都在帶實習(xí)生做項目,發(fā)現(xiàn)自己好久沒有寫博客了,這幾天更新會比較頻繁,今天玩QQ的時候發(fā)現(xiàn)QQ主頁菜單滑動效果早就變了,實在忍不住晚上就來實現(xiàn)一下了!

2.實現(xiàn) 

  2.1. 實現(xiàn)的方式多種多樣
  2.1.1 自定義ViewGroup ,處理其onTouch事件
  2.1.2 FrameLayout + 手勢處理類GestureDetector
  2.2.3 使用Google自帶的DrawerLayout 對其進行修改
  2.2.4 繼承自水平滾動HorizontalScrollView
大家可以看一下這個http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0909/6612.html,這種方式繼承自ViewGroup,個人覺得還行但是還是比較繁瑣要處理的東西也比較多,那么我就用最后一種2.2.4的方式實現(xiàn),有人說直接去網(wǎng)上下載一個源代碼就可以了,這我就只能GG了。

  2.3. 自定義SlidingMenu extends HorizontalScrollView 然后寫好布局文件這個和ScrollView的用法一樣,只不過是橫向滾動的

/**
 * description:
 * 仿QQ5.0主頁面?zhèn)然淖远╒iew
 * Created by 曾輝 on 2016/11/1.
 * QQ:240336124
 * Email: 240336124@qq.com
 * Version:1.0
 */
public class SlidingMenu extends HorizontalScrollView {
 public SlidingMenu(Context context) {
 super(context);
 }

 public SlidingMenu(Context context, AttributeSet attrs) {
 super(context, attrs);
 }

 public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 }
}

2.4. 運行起來之后發(fā)現(xiàn)布局不對,完全亂了明明都是match_parent可是就是不行那么我們就需要用代碼指定菜單和內(nèi)容的寬度:

菜單的寬度 = 屏幕的寬度 - 自定義的右邊留出的寬度
內(nèi)容的寬度 = 屏幕的寬度

/**
 * description:
 * 仿QQ5.0主頁面?zhèn)然淖远╒iew
 * Created by 曾輝 on 2016/11/1.
 * QQ:240336124
 * Email: 240336124@qq.com
 * Version:1.0
 */
public class SlidingMenu extends HorizontalScrollView {
 private View mMenuView;
 private View mContentView;
 private int mMenuWidth;

 public SlidingMenu(Context context) {
 this(context, null);
 }

 public SlidingMenu(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
 }

 public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 // 獲取自定義的右邊留出的寬度
 TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.SlidingMenu);
 float rightPadding = array.getDimension(
  R.styleable.SlidingMenu_rightPadding,dip2px(50));
 // 計算菜單的寬度 = 屏幕的寬度 - 自定義右邊留出的寬度
 mMenuWidth = (int) (getScreenWidth() - rightPadding);
 array.recycle();
 }

 /**
 * 把dip 轉(zhuǎn)成像素
 */
 private float dip2px(int dip) {
 return TypedValue.applyDimension(
  TypedValue.COMPLEX_UNIT_DIP,dip,getResources().getDisplayMetrics());
 }


 @Override
 protected void onFinishInflate() {
 super.onFinishInflate();

 // 1.獲取根View也就是外層的LinearLayout
 ViewGroup container = (ViewGroup) this.getChildAt(0);

 int containerChildCount = container.getChildCount();
 if(containerChildCount>2){
  // 里面只允許放置兩個布局 一個是Menu(菜單布局) 一個是Content(主頁內(nèi)容布局)
  throw new IllegalStateException("SlidingMenu 根布局LinearLayout下面只允許兩個布局,菜單布局和主頁內(nèi)容布局");
 }

 // 2.獲取菜單和內(nèi)容布局
 mMenuView = container.getChildAt(0);
 mContentView = container.getChildAt(1);

 // 3.指定內(nèi)容和菜單布局的寬度
 // 3.1 菜單的寬度 = 屏幕的寬度 - 自定義的右邊留出的寬度
 mMenuView.getLayoutParams().width = mMenuWidth;
 // 3.2 內(nèi)容的寬度 = 屏幕的寬度
 mContentView.getLayoutParams().width = getScreenWidth();
 }

 /**
 * 獲取屏幕的寬度
 */
 public int getScreenWidth() {
 Resources resources = this.getResources();
 DisplayMetrics dm = resources.getDisplayMetrics();
 return dm.widthPixels;
 }
}

目前的效果就是可以滑動,并且菜單和主頁面內(nèi)容的布局寬度正常

  2.5 接下來一開始就讓菜單滑動到關(guān)閉狀態(tài),手指滑動抬起判斷菜單打開和關(guān)閉并做相應(yīng)的處理 onLayout() onTouch() smoothScrollTo(),當手指快速的時候切換菜單的狀態(tài)利用GestureDetector 手勢處理類:

 /**
 * description:
 * 仿QQ5.0主頁面?zhèn)然淖远╒iew
 * Created by 曾輝 on 2016/11/1.
 * QQ:240336124
 * Email: 240336124@qq.com
 * Version:1.0
 */
public class SlidingMenu extends HorizontalScrollView {
 private View mMenuView;
 private View mContentView;
 private int mMenuWidth;
 // 手勢處理類 主要用來處理手勢快速滑動
 private GestureDetector mGestureDetector;

 // 菜單是否打開
 private boolean mMenuIsOpen = false;

 public SlidingMenu(Context context) {
 this(context, null);
 }

 public SlidingMenu(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
 }

 public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 // 獲取自定義的右邊留出的寬度
 TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SlidingMenu);
 float rightPadding = array.getDimension(
  R.styleable.SlidingMenu_rightPadding, dip2px(50));
 // 計算菜單的寬度 = 屏幕的寬度 - 自定義右邊留出的寬度
 mMenuWidth = (int) (getScreenWidth() - rightPadding);
 array.recycle();

 // 實例化手勢處理類
 mGestureDetector = new GestureDetector(context,new GestureListener());
 }

 /**
 * 把dip 轉(zhuǎn)成像素
 */
 private float dip2px(int dip) {
 return TypedValue.applyDimension(
  TypedValue.COMPLEX_UNIT_DIP, dip, getResources().getDisplayMetrics());
 }


 @Override
 protected void onFinishInflate() {
 super.onFinishInflate();

 // 1.獲取根View也就是外層的LinearLayout
 ViewGroup container = (ViewGroup) this.getChildAt(0);

 int containerChildCount = container.getChildCount();
 if (containerChildCount > 2) {
  // 里面只允許放置兩個布局 一個是Menu(菜單布局) 一個是Content(主頁內(nèi)容布局)
  throw new IllegalStateException("SlidingMenu 根布局LinearLayout下面只允許兩個布局,菜單布局和主頁內(nèi)容布局");
 }

 // 2.獲取菜單和內(nèi)容布局
 mMenuView = container.getChildAt(0);
 mContentView = container.getChildAt(1);

 // 3.指定內(nèi)容和菜單布局的寬度
 // 3.1 菜單的寬度 = 屏幕的寬度 - 自定義的右邊留出的寬度
 mMenuView.getLayoutParams().width = mMenuWidth;
 // 3.2 內(nèi)容的寬度 = 屏幕的寬度
 mContentView.getLayoutParams().width = getScreenWidth();
 }

 @Override
 public boolean onTouchEvent(MotionEvent ev) {

 // 處理手指快速滑動
 if(mGestureDetector.onTouchEvent(ev)){
  return mGestureDetector.onTouchEvent(ev);
 }

 switch (ev.getAction()) {
  case MotionEvent.ACTION_UP:
  // 手指抬起獲取滾動的位置
  int currentScrollX = getScrollX();
  if (currentScrollX > mMenuWidth / 2) {
   // 關(guān)閉菜單
   closeMenu();
  } else {
   // 打開菜單
   openMenu();
  }
  return false;
 }
 return super.onTouchEvent(ev);
 }

 /**
 * 打開菜單
 */
 private void openMenu() {
 smoothScrollTo(0, 0);
 mMenuIsOpen = true;
 }

 /**
 * 關(guān)閉菜單
 */
 private void closeMenu() {
 smoothScrollTo(mMenuWidth, 0);
 mMenuIsOpen = false;
 }

 @Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
 super.onLayout(changed, l, t, r, b);
 // 布局指定后會從新擺放子布局,當其擺放完畢后,讓菜單滾動到不可見狀態(tài)
 if (changed) {
  scrollTo(mMenuWidth, 0);
 }
 }

 /**
 * 獲取屏幕的寬度
 */
 public int getScreenWidth() {
 Resources resources = this.getResources();
 DisplayMetrics dm = resources.getDisplayMetrics();
 return dm.widthPixels;
 }


 private class GestureListener extends GestureDetector.SimpleOnGestureListener{
 @Override
 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
  // 當手指快速滑動時候回調(diào)的方法
  Log.e("TAG",velocityX+"");
  // 如果菜單打開 并且是向左快速滑動 切換菜單的狀態(tài)
  if(mMenuIsOpen){
  if(velocityX<-500){
   toggleMenu();
   return true;
  }
  }else{
  // 如果菜單關(guān)閉 并且是向右快速滑動 切換菜單的狀態(tài)
  if(velocityX>500){
   toggleMenu();
   return true;
  }
  }

  return false;
 }
 }

 /**
 * 切換菜單的狀態(tài)
 */
 private void toggleMenu() {
 if(mMenuIsOpen){
  closeMenu();
 }else{
  openMenu();
 }
 }
}

到了這一步之后我們就可以切換菜單了,并且處理了手指快速滑動,迫不及待的看下效果

2.6. 實現(xiàn)菜單左邊抽屜樣式的動畫效果,監(jiān)聽滾動回調(diào)的方法onScrollChanged() 這個就非常簡單了一句話就搞定,效果就不看了一起看終極效果吧

@Override
 protected void onScrollChanged(int l, int t, int oldl, int oldt) {
 super.onScrollChanged(l, t, oldl, oldt);

 // l 是 當前滾動的x距離 在滾動的時候會不斷反復(fù)的回調(diào)這個方法
 Log.e(TAG,l+"");

 mMenuView.setTranslationX(l*0.8f);
 }

2.7. 實現(xiàn)菜單右邊菜單的陰影透明度效果,這個打算在主頁面內(nèi)容布局上面加一層陰影,用ImageView即可,那么我們的內(nèi)容View就需要換了

/**
 * description:
 * 仿QQ5.0主頁面?zhèn)然淖远╒iew
 * Created by 曾輝 on 2016/11/1.
 * QQ:240336124
 * Email: 240336124@qq.com
 * Version:1.0
 */
public class SlidingMenu extends HorizontalScrollView {
 private static final String TAG = "HorizontalScrollView";
 private Context mContext;

 // 4.給菜單和內(nèi)容View指定寬高 - 左邊菜單View
 private View mMenuView;

 // 4.給菜單和內(nèi)容View指定寬高 - 菜單的寬度
 private int mMenuWidth;
 // 5.3 手勢處理類 主要用來處理手勢快速滑動
 private GestureDetector mGestureDetector;
 // 5.3 菜單是否打開
 private boolean mMenuIsOpen = false;

 // 7(4). 主頁面內(nèi)容View的布局包括陰影ImageView
 private ViewGroup mContentView;
 // 7.給內(nèi)容添加陰影效果 - 陰影的ImageView
 private ImageView mShadowIv;

 public SlidingMenu(Context context) {
 this(context, null);
 }

 public SlidingMenu(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
 }

 public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 //4.1 計算左邊菜單的寬度
 //4.1.1 獲取自定義的右邊留出的寬度
 TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SlidingMenu);
 float rightPadding = array.getDimension(
  R.styleable.SlidingMenu_rightPadding, dip2px(50));
 // 4.1.2 計算菜單的寬度 = 屏幕的寬度 - 自定義右邊留出的寬度
 mMenuWidth = (int) (getScreenWidth() - rightPadding);
 array.recycle();

 // 5.3 實例化手勢處理類
 mGestureDetector = new GestureDetector(context,new GestureListener());

 this.mContext = context;
 }

 /**
 * 把dip 轉(zhuǎn)成像素
 */
 private float dip2px(int dip) {
 return TypedValue.applyDimension(
  TypedValue.COMPLEX_UNIT_DIP, dip, getResources().getDisplayMetrics());
 }


 @Override
 protected void onFinishInflate() {
 super.onFinishInflate();
 // 4.2 指定菜單和內(nèi)容View的寬度
 // 4.2.1.獲取根View也就是外層的LinearLayout
 ViewGroup container = (ViewGroup) this.getChildAt(0);

 int containerChildCount = container.getChildCount();
 if (containerChildCount > 2) {
  // 里面只允許放置兩個布局 一個是Menu(菜單布局) 一個是Content(主頁內(nèi)容布局)
  throw new IllegalStateException("SlidingMenu 根布局LinearLayout下面只允許兩個布局,菜單布局和主頁內(nèi)容布局");
 }

 // 4.2.2.獲取菜單和內(nèi)容布局
 mMenuView = container.getChildAt(0);

 // 7.給內(nèi)容添加陰影效果
 // 7.1 先new一個主內(nèi)容布局用來放 陰影和LinearLayout原來的內(nèi)容布局
 mContentView = new FrameLayout(mContext);
 ViewGroup.LayoutParams contentParams = new ViewGroup.LayoutParams(
  ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);

 // 7.2 獲取原來的內(nèi)容布局,并把原來的內(nèi)容布局從LinearLayout中異常
 View oldContentView = container.getChildAt(1);
 container.removeView(oldContentView);

 // 7.3 把原來的內(nèi)容View 和 陰影加到我們新創(chuàng)建的內(nèi)容布局中
 mContentView.addView(oldContentView);
 // 7.3.1 創(chuàng)建陰影ImageView
 mShadowIv = new ImageView(mContext);
 mShadowIv.setBackgroundColor(Color.parseColor("#99000000"));
 mContentView.addView(mShadowIv);

 // 7.4 把包含陰影的新的內(nèi)容View 添加到 LinearLayout中
 container.addView(mContentView);

 // 4.2.3.指定內(nèi)容和菜單布局的寬度
 // 4.2.3.1 菜單的寬度 = 屏幕的寬度 - 自定義的右邊留出的寬度
 mMenuView.getLayoutParams().width = mMenuWidth;
 // 4.2.3.2 內(nèi)容的寬度 = 屏幕的寬度
 mContentView.getLayoutParams().width = getScreenWidth();
 }

 /**
 * 5.處理手指抬起和快速滑動切換菜單
 */
 @Override
 public boolean onTouchEvent(MotionEvent ev) {
 // 5.3 處理手指快速滑動
 if(mGestureDetector.onTouchEvent(ev)){
  return mGestureDetector.onTouchEvent(ev);
 }

 switch (ev.getAction()) {
  case MotionEvent.ACTION_UP:
  // 5.1 手指抬起獲取滾動的位置
  int currentScrollX = getScrollX();
  if (currentScrollX > mMenuWidth / 2) {
   // 5.1.1 關(guān)閉菜單
   closeMenu();
  } else {
   // 5.1.2 打開菜單
   openMenu();
  }
  return false;
 }
 return super.onTouchEvent(ev);
 }

 @Override
 protected void onScrollChanged(int l, int t, int oldl, int oldt) {
 super.onScrollChanged(l, t, oldl, oldt);

 // l 是 當前滾動的x距離 在滾動的時候會不斷反復(fù)的回調(diào)這個方法
 Log.e(TAG,l+"");
 // 6. 實現(xiàn)菜單左邊抽屜樣式的動畫效果
 mMenuView.setTranslationX(l*0.8f);

 // 7.給內(nèi)容添加陰影效果 - 計算梯度值
 float gradientValue = l * 1f / mMenuWidth;// 這是 1 - 0 變化的值

 // 7.給內(nèi)容添加陰影效果 - 給陰影的View指定透明度 0 - 1 變化的值
 float shadowAlpha = 1 - gradientValue;
 mShadowIv.setAlpha(shadowAlpha);
 }

 /**
 * 5.1.2 打開菜單
 */
 private void openMenu() {
 smoothScrollTo(0, 0);
 mMenuIsOpen = true;
 }

 /**
 * 5.1.1 關(guān)閉菜單
 */
 private void closeMenu() {
 smoothScrollTo(mMenuWidth, 0);
 mMenuIsOpen = false;
 }

 @Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
 super.onLayout(changed, l, t, r, b);
 // 布局指定后會從新擺放子布局,當其擺放完畢后,讓菜單滾動到不可見狀態(tài)
 if (changed) {
  scrollTo(mMenuWidth, 0);
 }
 }

 /**
 * 獲取屏幕的寬度
 */
 public int getScreenWidth() {
 Resources resources = this.getResources();
 DisplayMetrics dm = resources.getDisplayMetrics();
 return dm.widthPixels;
 }


 /**
 * 5.3 處理手指快速滑動
 */
 private class GestureListener extends GestureDetector.SimpleOnGestureListener{
 @Override
 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
  // 當手指快速滑動時候回調(diào)的方法
  Log.e(TAG,velocityX+"");
  // 5.3.1 如果菜單打開 并且是向左快速滑動 切換菜單的狀態(tài)
  if(mMenuIsOpen){
  if(velocityX<0){
   toggleMenu();
   return true;
  }
  }else{
  // 5.3.2 如果菜單關(guān)閉 并且是向右快速滑動 切換菜單的狀態(tài)
  if(velocityX>0){
   toggleMenu();
   return true;
  }
  }
  return false;
 }
 }

 /**
 * 切換菜單的狀態(tài)
 */
 private void toggleMenu() {
 if(mMenuIsOpen){
  closeMenu();
 }else{
  openMenu();
 }
 }
}

我們來看一下最后的效果吧,最終代碼量不是很多啦,需要的請下載源碼,如果是實現(xiàn)QQ5.0或是酷狗的側(cè)滑效果可以自己改改。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android手勢密碼的實現(xiàn)

    Android手勢密碼的實現(xiàn)

    這篇文章主要介紹了Android手勢密碼的實現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2016-04-04
  • Android利用GridView實現(xiàn)單選功能

    Android利用GridView實現(xiàn)單選功能

    這篇文章主要為大家詳細介紹了Android利用GridView實現(xiàn)單選功能的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • sqlite查詢結(jié)果在listview中展示的實現(xiàn)

    sqlite查詢結(jié)果在listview中展示的實現(xiàn)

    下面小編就為大家?guī)硪黄猻qlite查詢結(jié)果在listview中展示的實現(xiàn)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • Android事件處理的兩種方式詳解

    Android事件處理的兩種方式詳解

    事件是一種有用來收集用戶與應(yīng)用程序互動數(shù)據(jù)的互動組件,如按鍵或觸摸屏等放置事件,因為每個事件從Android框架維護事件隊列先入先出(FIFO)基礎(chǔ)上的隊列??梢栽诔绦蛑胁东@這些事件,按要求并采取適當?shù)膭幼?/div> 2023-02-02
  • Android studio實現(xiàn)簡單的計算器

    Android studio實現(xiàn)簡單的計算器

    這篇文章主要為大家詳細介紹了Android studio實現(xiàn)簡單的計算器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • Android自定義shape的使用示例

    Android自定義shape的使用示例

    本文主要介紹自定義shape(定義矩形、定義邊框顏色、定義圓角弧度),具體代碼如下,感興趣的各位可以參考下哈,希望對大家有所幫助
    2013-06-06
  • 深入理解Kotlin的泛型系統(tǒng)

    深入理解Kotlin的泛型系統(tǒng)

    Kotlin 泛型即 “參數(shù)化類型”,將類型參數(shù)化,可以用在類,接口,方法上。下面 這篇文章主要給大家介紹了關(guān)于Kotlin泛型系統(tǒng)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下。
    2017-12-12
  • android 修改launcher行數(shù)和列數(shù)的方法

    android 修改launcher行數(shù)和列數(shù)的方法

    這篇文章主要介紹了android 修改launcher行數(shù)和列數(shù)的方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-07-07
  • Android IPC機制利用Messenger實現(xiàn)跨進程通信

    Android IPC機制利用Messenger實現(xiàn)跨進程通信

    這篇文章主要介紹了Android IPC機制中 Messager 實現(xiàn)跨進程通信的知識,對Android學(xué)習(xí)通信知識非常重要,需要的同學(xué)可以參考下
    2016-07-07
  • 基于Android開發(fā)支持表情的實現(xiàn)詳解

    基于Android開發(fā)支持表情的實現(xiàn)詳解

    本篇文章是對在Android開發(fā)中支持表情的實現(xiàn)代碼進行了介紹。需要的朋友參考下
    2013-05-05

最新評論