溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android3D如何實現(xiàn)滑動菜單

發(fā)布時間:2021-04-16 13:41:53 來源:億速云 閱讀:166 作者:小新 欄目:移動開發(fā)

這篇文章主要介紹了Android3D如何實現(xiàn)滑動菜單,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

首先來講一下這次的實現(xiàn)原理吧,其實傳統(tǒng)的滑動菜單功能就是把菜單部分放在了下面,主布局放在了上面,然后根據(jù)手指滑動的距離來偏移主布局,讓菜單部分得以顯示出來就行了。不過我們這次既然要做推拉門式的立體效果,就需要將傳統(tǒng)的思維稍微轉變一下,可以先讓菜單部分隱藏掉,但卻復制一個菜單的鏡像并生成一張圖片,然后在手指滑動的時候對這張圖片進行三維操作,讓它產生推拉門式的效果,等滑動操作結束的時候,才讓真正的菜單顯示出來,然后將這個圖片隱藏。原理示意圖如下所示:

Android3D如何實現(xiàn)滑動菜單

那么下面我們就開始動手實現(xiàn)吧,首先新建一個Android項目,起名叫做ThreeDSlidingLayoutDemo。

然后新建一個Image3dView類繼承自View,用于生成鏡像圖片,以及完成三維操作,代碼如下所示:

public class Image3dView extends View { 
 
 /** 
 * 源視圖,用于生成圖片對象。 
 */ 
 private View sourceView; 
 
 /** 
 * 根據(jù)傳入的源視圖生成的圖片對象。 
 */ 
 private Bitmap sourceBitmap; 
 
 /** 
 * 源視圖的寬度。 
 */ 
 private float sourceWidth; 
 
 /** 
 * Matrix對象,用于對圖片進行矩陣操作。 
 */ 
 private Matrix matrix = new Matrix(); 
 
 /** 
 * Camera對象,用于對圖片進行三維操作。 
 */ 
 private Camera camera = new Camera(); 
 
 /** 
 * Image3dView的構造函數(shù) 
 * 
 * @param context 
 * @param attrs 
 */ 
 public Image3dView(Context context, AttributeSet attrs) { 
 super(context, attrs); 
 } 
 
 /** 
 * 提供外部接口,允許向Image3dView傳入源視圖。 
 * 
 * @param view 
 *  傳入的源視圖 
 */ 
 public void setSourceView(View view) { 
 sourceView = view; 
 sourceWidth = sourceView.getWidth(); 
 } 
 
 /** 
 * 清除掉緩存的圖片對象。 
 */ 
 public void clearSourceBitmap() { 
 if (sourceBitmap != null) { 
  sourceBitmap = null; 
 } 
 } 
 
 @Override 
 protected void onDraw(Canvas canvas) { 
 super.onDraw(canvas); 
 if (sourceBitmap == null) { 
  getSourceBitmap(); 
 } 
 // 計算圖片需要旋轉的角度 
 float degree = 90 - (90 / sourceWidth) * getWidth(); 
 camera.save(); 
 camera.rotateY(degree); 
 camera.getMatrix(matrix); 
 camera.restore(); 
 // 將旋轉的中心點移動到屏幕左邊緣的中間位置 
 matrix.preTranslate(0, -getHeight() / 2); 
 matrix.postTranslate(0, getHeight() / 2); 
 canvas.drawBitmap(sourceBitmap, matrix, null); 
 } 
 
 /** 
 * 獲取源視圖對應的圖片對象。 
 */ 
 private void getSourceBitmap() { 
 if (sourceView != null) { 
  sourceView.setDrawingCacheEnabled(true); 
  sourceView.layout(0, 0, sourceView.getWidth(), sourceView.getHeight()); 
  sourceView.buildDrawingCache(); 
  sourceBitmap = sourceView.getDrawingCache(); 
 } 
 } 
 
}

可以看到,Image3dView中提供了一個setSourceView()方法,用于傳遞源視圖進來,我們稍后復制鏡像就是對它進行復制。然后在onDraw()方法里對sourceBitmap進行判斷,如果為空,則去調用getSourceBitmap()方法來生成一張鏡像圖片,getSourceBitmap()方法的細節(jié)大家自己去看。在獲得了鏡像圖片之后,接下來就是要計算圖片的旋轉角度了,這里根據(jù)Image3dView當前的寬度和源視圖的總寬度進行對比,按比例算出旋轉的角度。然后調用Camera的rotateY()方法,讓圖片團練Y軸進行旋轉,并將旋轉的中心點移動到屏幕左邊緣的中間位置,這幾行代碼我們在上篇文章中已經見過了,算是挺熟悉了吧!最后調用Canvas的drawBitmap()方法把圖片繪制出來。

完成了Image3dView之后,接著我們要開始編寫滑動菜單部分的代碼,其實這次的代碼和之前的滑動菜單代碼大同小異,看過我前面文章的朋友,這次理解起來一定會輕而易舉。新建ThreeDSlidingLayout類,代碼如下所示:

public class ThreeDSlidingLayout extends RelativeLayout implements OnTouchListener { 
 
 /** 
 * 滾動顯示和隱藏左側布局時,手指滑動需要達到的速度。 
 */ 
 public static final int SNAP_VELOCITY = 200; 
 
 /** 
 * 滑動狀態(tài)的一種,表示未進行任何滑動。 
 */ 
 public static final int DO_NOTHING = 0; 
 
 /** 
 * 滑動狀態(tài)的一種,表示正在滑出左側菜單。 
 */ 
 public static final int SHOW_MENU = 1; 
 
 /** 
 * 滑動狀態(tài)的一種,表示正在隱藏左側菜單。 
 */ 
 public static final int HIDE_MENU = 2; 
 
 /** 
 * 記錄當前的滑動狀態(tài) 
 */ 
 private int slideState; 
 
 /** 
 * 屏幕寬度值。 
 */ 
 private int screenWidth; 
 
 /** 
 * 右側布局最多可以滑動到的左邊緣。 
 */ 
 private int leftEdge = 0; 
 
 /** 
 * 右側布局最多可以滑動到的右邊緣。 
 */ 
 private int rightEdge = 0; 
 
 /** 
 * 在被判定為滾動之前用戶手指可以移動的最大值。 
 */ 
 private int touchSlop; 
 
 /** 
 * 記錄手指按下時的橫坐標。 
 */ 
 private float xDown; 
 
 /** 
 * 記錄手指按下時的縱坐標。 
 */ 
 private float yDown; 
 
 /** 
 * 記錄手指移動時的橫坐標。 
 */ 
 private float xMove; 
 
 /** 
 * 記錄手指移動時的縱坐標。 
 */ 
 private float yMove; 
 
 /** 
 * 記錄手機抬起時的橫坐標。 
 */ 
 private float xUp; 
 
 /** 
 * 左側布局當前是顯示還是隱藏。只有完全顯示或隱藏時才會更改此值,滑動過程中此值無效。 
 */ 
 private boolean isLeftLayoutVisible; 
 
 /** 
 * 是否正在滑動。 
 */ 
 private boolean isSliding; 
 
 /** 
 * 是否已加載過一次layout,這里onLayout中的初始化只需加載一次 
 */ 
 private boolean loadOnce; 
 
 /** 
 * 左側布局對象。 
 */ 
 private View leftLayout; 
 
 /** 
 * 右側布局對象。 
 */ 
 private View rightLayout; 
 
 /** 
 * 在滑動過程中展示的3D視圖 
 */ 
 private Image3dView image3dView; 
 
 /** 
 * 用于監(jiān)聽側滑事件的View。 
 */ 
 private View mBindView; 
 
 /** 
 * 左側布局的參數(shù),通過此參數(shù)來重新確定左側布局的寬度,以及更改leftMargin的值。 
 */ 
 private MarginLayoutParams leftLayoutParams; 
 
 /** 
 * 右側布局的參數(shù),通過此參數(shù)來重新確定右側布局的寬度。 
 */ 
 private MarginLayoutParams rightLayoutParams; 
 
 /** 
 * 3D視圖的參數(shù),通過此參數(shù)來重新確定3D視圖的寬度。 
 */ 
 private ViewGroup.LayoutParams image3dViewParams; 
 
 /** 
 * 用于計算手指滑動的速度。 
 */ 
 private VelocityTracker mVelocityTracker; 
 
 /** 
 * 重寫SlidingLayout的構造函數(shù),其中獲取了屏幕的寬度。 
 * 
 * @param context 
 * @param attrs 
 */ 
 public ThreeDSlidingLayout(Context context, AttributeSet attrs) { 
 super(context, attrs); 
 WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 
 screenWidth = wm.getDefaultDisplay().getWidth(); 
 touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 
 } 
 
 /** 
 * 綁定監(jiān)聽側滑事件的View,即在綁定的View進行滑動才可以顯示和隱藏左側布局。 
 * 
 * @param bindView 
 *  需要綁定的View對象。 
 */ 
 public void setScrollEvent(View bindView) { 
 mBindView = bindView; 
 mBindView.setOnTouchListener(this); 
 } 
 
 /** 
 * 將屏幕滾動到左側布局界面,滾動速度設定為10. 
 */ 
 public void scrollToLeftLayout() { 
 image3dView.clearSourceBitmap(); 
 new ScrollTask().execute(-10); 
 } 
 
 /** 
 * 將屏幕滾動到右側布局界面,滾動速度設定為-10. 
 */ 
 public void scrollToRightLayout() { 
 image3dView.clearSourceBitmap(); 
 new ScrollTask().execute(10); 
 } 
 
 /** 
 * 左側布局是否完全顯示出來,或完全隱藏,滑動過程中此值無效。 
 * 
 * @return 左側布局完全顯示返回true,完全隱藏返回false。 
 */ 
 public boolean isLeftLayoutVisible() { 
 return isLeftLayoutVisible; 
 } 
 
 /** 
 * 在onLayout中重新設定左側布局和右側布局的參數(shù)。 
 */ 
 @Override 
 protected void onLayout(boolean changed, int l, int t, int r, int b) { 
 super.onLayout(changed, l, t, r, b); 
 if (changed && !loadOnce) { 
  // 獲取左側布局對象 
  leftLayout = findViewById(R.id.menu); 
  leftLayoutParams = (MarginLayoutParams) leftLayout.getLayoutParams(); 
  rightEdge = -leftLayoutParams.width; 
  // 獲取右側布局對象 
  rightLayout = findViewById(R.id.content); 
  rightLayoutParams = (MarginLayoutParams) rightLayout.getLayoutParams(); 
  rightLayoutParams.width = screenWidth; 
  rightLayout.setLayoutParams(rightLayoutParams); 
  // 獲取3D視圖對象 
  image3dView = (Image3dView) findViewById(R.id.image_3d_view); 
  // 將左側布局傳入3D視圖中作為生成源 
  image3dView.setSourceView(leftLayout); 
  loadOnce = true; 
 } 
 } 
 
 @Override 
 public boolean onTouch(View v, MotionEvent event) { 
 createVelocityTracker(event); 
 switch (event.getAction()) { 
 case MotionEvent.ACTION_DOWN: 
  // 手指按下時,記錄按下時的橫坐標 
  xDown = event.getRawX(); 
  yDown = event.getRawY(); 
  slideState = DO_NOTHING; 
  break; 
 case MotionEvent.ACTION_MOVE: 
  // 手指移動時,對比按下時的橫坐標,計算出移動的距離,來調整右側布局的leftMargin值,從而顯示和隱藏左側布局 
  xMove = event.getRawX(); 
  yMove = event.getRawY(); 
  int moveDistanceX = (int) (xMove - xDown); 
  int moveDistanceY = (int) (yMove - yDown); 
  checkSlideState(moveDistanceX, moveDistanceY); 
  switch (slideState) { 
  case SHOW_MENU: 
  rightLayoutParams.rightMargin = -moveDistanceX; 
  onSlide(); 
  break; 
  case HIDE_MENU: 
  rightLayoutParams.rightMargin = rightEdge - moveDistanceX; 
  onSlide(); 
  break; 
  default: 
  break; 
  } 
  break; 
 case MotionEvent.ACTION_UP: 
  xUp = event.getRawX(); 
  int upDistanceX = (int) (xUp - xDown); 
  if (isSliding) { 
  // 手指抬起時,進行判斷當前手勢的意圖 
  switch (slideState) { 
  case SHOW_MENU: 
   if (shouldScrollToLeftLayout()) { 
   scrollToLeftLayout(); 
   } else { 
   scrollToRightLayout(); 
   } 
   break; 
  case HIDE_MENU: 
   if (shouldScrollToRightLayout()) { 
   scrollToRightLayout(); 
   } else { 
   scrollToLeftLayout(); 
   } 
   break; 
  default: 
   break; 
  } 
  } else if (upDistanceX < touchSlop && isLeftLayoutVisible) { 
  scrollToRightLayout(); 
  } 
  recycleVelocityTracker(); 
  break; 
 } 
 if (v.isEnabled()) { 
  if (isSliding) { 
  unFocusBindView(); 
  return true; 
  } 
  if (isLeftLayoutVisible) { 
  return true; 
  } 
  return false; 
 } 
 return true; 
 } 
 
 /** 
 * 執(zhí)行滑動過程中的邏輯操作,如邊界檢查,改變偏移值,可見性檢查等。 
 */ 
 private void onSlide() { 
 checkSlideBorder(); 
 rightLayout.setLayoutParams(rightLayoutParams); 
 image3dView.clearSourceBitmap(); 
 image3dViewParams = image3dView.getLayoutParams(); 
 image3dViewParams.width = -rightLayoutParams.rightMargin; 
 // 滑動的同時改變3D視圖的大小 
 image3dView.setLayoutParams(image3dViewParams); 
 // 保證在滑動過程中3D視圖可見,左側布局不可見 
 showImage3dView(); 
 } 
 
 /** 
 * 根據(jù)手指移動的距離,判斷當前用戶的滑動意圖,然后給slideState賦值成相應的滑動狀態(tài)值。 
 * 
 * @param moveDistanceX 
 *  橫向移動的距離 
 * @param moveDistanceY 
 *  縱向移動的距離 
 */ 
 private void checkSlideState(int moveDistanceX, int moveDistanceY) { 
 if (isLeftLayoutVisible) { 
  if (!isSliding && Math.abs(moveDistanceX) >= touchSlop && moveDistanceX < 0) { 
  isSliding = true; 
  slideState = HIDE_MENU; 
  } 
 } else if (!isSliding && Math.abs(moveDistanceX) >= touchSlop && moveDistanceX > 0 
  && Math.abs(moveDistanceY) < touchSlop) { 
  isSliding = true; 
  slideState = SHOW_MENU; 
 } 
 } 
 
 /** 
 * 在滑動過程中檢查左側菜單的邊界值,防止綁定布局滑出屏幕。 
 */ 
 private void checkSlideBorder() { 
 if (rightLayoutParams.rightMargin > leftEdge) { 
  rightLayoutParams.rightMargin = leftEdge; 
 } else if (rightLayoutParams.rightMargin < rightEdge) { 
  rightLayoutParams.rightMargin = rightEdge; 
 } 
 } 
 
 /** 
 * 判斷是否應該滾動將左側布局展示出來。如果手指移動距離大于屏幕的1/2,或者手指移動速度大于SNAP_VELOCITY, 
 * 就認為應該滾動將左側布局展示出來。 
 * 
 * @return 如果應該滾動將左側布局展示出來返回true,否則返回false。 
 */ 
 private boolean shouldScrollToLeftLayout() { 
 return xUp - xDown > leftLayoutParams.width / 2 || getScrollVelocity() > SNAP_VELOCITY; 
 } 
 
 /** 
 * 判斷是否應該滾動將右側布局展示出來。如果手指移動距離加上leftLayoutPadding大于屏幕的1/2, 
 * 或者手指移動速度大于SNAP_VELOCITY, 就認為應該滾動將右側布局展示出來。 
 * 
 * @return 如果應該滾動將右側布局展示出來返回true,否則返回false。 
 */ 
 private boolean shouldScrollToRightLayout() { 
 return xDown - xUp > leftLayoutParams.width / 2 || getScrollVelocity() > SNAP_VELOCITY; 
 } 
 
 /** 
 * 創(chuàng)建VelocityTracker對象,并將觸摸事件加入到VelocityTracker當中。 
 * 
 * @param event 
 *  右側布局監(jiān)聽控件的滑動事件 
 */ 
 private void createVelocityTracker(MotionEvent event) { 
 if (mVelocityTracker == null) { 
  mVelocityTracker = VelocityTracker.obtain(); 
 } 
 mVelocityTracker.addMovement(event); 
 } 
 
 /** 
 * 獲取手指在右側布局的監(jiān)聽View上的滑動速度。 
 * 
 * @return 滑動速度,以每秒鐘移動了多少像素值為單位。 
 */ 
 private int getScrollVelocity() { 
 mVelocityTracker.computeCurrentVelocity(1000); 
 int velocity = (int) mVelocityTracker.getXVelocity(); 
 return Math.abs(velocity); 
 } 
 
 /** 
 * 回收VelocityTracker對象。 
 */ 
 private void recycleVelocityTracker() { 
 mVelocityTracker.recycle(); 
 mVelocityTracker = null; 
 } 
 
 /** 
 * 使用可以獲得焦點的控件在滑動的時候失去焦點。 
 */ 
 private void unFocusBindView() { 
 if (mBindView != null) { 
  mBindView.setPressed(false); 
  mBindView.setFocusable(false); 
  mBindView.setFocusableInTouchMode(false); 
 } 
 } 
 
 /** 
 * 保證此時讓左側布局不可見,3D視圖可見,從而讓滑動過程中產生3D的效果。 
 */ 
 private void showImage3dView() { 
 if (image3dView.getVisibility() != View.VISIBLE) { 
  image3dView.setVisibility(View.VISIBLE); 
 } 
 if (leftLayout.getVisibility() != View.INVISIBLE) { 
  leftLayout.setVisibility(View.INVISIBLE); 
 } 
 } 
 
 class ScrollTask extends AsyncTask<Integer, Integer, Integer> { 
 
 @Override 
 protected Integer doInBackground(Integer... speed) { 
  int rightMargin = rightLayoutParams.rightMargin; 
  // 根據(jù)傳入的速度來滾動界面,當滾動到達左邊界或右邊界時,跳出循環(huán)。 
  while (true) { 
  rightMargin = rightMargin + speed[0]; 
  if (rightMargin < rightEdge) { 
   rightMargin = rightEdge; 
   break; 
  } 
  if (rightMargin > leftEdge) { 
   rightMargin = leftEdge; 
   break; 
  } 
  publishProgress(rightMargin); 
  // 為了要有滾動效果產生,每次循環(huán)使線程睡眠5毫秒,這樣肉眼才能夠看到滾動動畫。 
  sleep(5); 
  } 
  if (speed[0] > 0) { 
  isLeftLayoutVisible = false; 
  } else { 
  isLeftLayoutVisible = true; 
  } 
  isSliding = false; 
  return rightMargin; 
 } 
 
 @Override 
 protected void onProgressUpdate(Integer... rightMargin) { 
  rightLayoutParams.rightMargin = rightMargin[0]; 
  rightLayout.setLayoutParams(rightLayoutParams); 
  image3dViewParams = image3dView.getLayoutParams(); 
  image3dViewParams.width = -rightLayoutParams.rightMargin; 
  image3dView.setLayoutParams(image3dViewParams); 
  showImage3dView(); 
  unFocusBindView(); 
 } 
 
 @Override 
 protected void onPostExecute(Integer rightMargin) { 
  rightLayoutParams.rightMargin = rightMargin; 
  rightLayout.setLayoutParams(rightLayoutParams); 
  image3dViewParams = image3dView.getLayoutParams(); 
  image3dViewParams.width = -rightLayoutParams.rightMargin; 
  image3dView.setLayoutParams(image3dViewParams); 
  if (isLeftLayoutVisible) { 
  // 保證在滑動結束后左側布局可見,3D視圖不可見。 
  image3dView.setVisibility(View.INVISIBLE); 
  leftLayout.setVisibility(View.VISIBLE); 
  } 
 } 
 } 
 
 /** 
 * 使當前線程睡眠指定的毫秒數(shù)。 
 * 
 * @param millis 
 *  指定當前線程睡眠多久,以毫秒為單位 
 */ 
 private void sleep(long millis) { 
 try { 
  Thread.sleep(millis); 
 } catch (InterruptedException e) { 
  e.printStackTrace(); 
 } 
 } 
}

代碼比較長,我還是帶著大家來理一下思路。首先在onLayout方法中,我們分別初始化了左側布局對象、右側布局對象和Image3dView對象,這三個對象稍后都要配置到Activity布局里面的。在onLayout()方法的最后,調用了Image3dView的setSourceView()方法,并將左側布局對象傳了進去,說明我們后面就要對它進行鏡像復制。

當手指在界面上拖動來顯示左側布局的時候,就會進入到onTouch()方法中,這里會調用checkSlideState()方法來檢查滑動的狀態(tài),以判斷用戶是想要顯示左側布局還是隱藏左側布局,然后根據(jù)手指滑動的距離對右側布局進行偏移,就可以實現(xiàn)基本的滑動效果了。接下來是重點內容,這里會根據(jù)右側布局的偏移量來改變Image3dView的寬度,當Image3dView大小發(fā)生改變時,當然會調用onDraw()方法來進行重繪,此時我們編寫的三維旋轉邏輯就可以得到執(zhí)行了,于是就會產生立體的推拉門式效果。注意,在整個的滑動過程中,真正的左側布局一直都是不可見的,我們所看到的只是它的一張鏡像圖片。

當手指離開屏幕后,會根據(jù)當前的移動距離來決定是顯示左側布局還是隱藏左側布局,并會調用scrollToLeftLayout()方法或scrollToRightLayout()方法來完成后續(xù)的滾動操作。當整個滾動操作完成之后,才會將真正的左側布局顯示出來,再把鏡像圖片隱藏掉,這樣用戶就可以點擊左側布局上按鈕之類的東西了。

接著我們需要在Activity的布局文件當中去引用這個三維滑動菜單框架,打開或新建activity_main.xml作為程序的主布局文件,代碼如下所示:

<com.example.slidinglayout3d.ThreeDSlidingLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 xmlns:tools="http://schemas.android.com/tools" 
 android:id="@+id/slidingLayout" 
 android:layout_width="fill_parent" 
 android:layout_height="fill_parent" > 
 
 <RelativeLayout 
 android:id="@+id/menu" 
 android:layout_width="270dip" 
 android:layout_height="fill_parent" 
 android:layout_alignParentLeft="true" 
 android:background="#00ccff" 
 android:visibility="invisible" > 
 
 <LinearLayout 
  android:layout_width="match_parent" 
  android:layout_height="wrap_content" 
  android:layout_centerInParent="true" 
  android:orientation="vertical" > 
 
  <TextView 
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content" 
  android:layout_gravity="center_horizontal" 
  android:text="This is menu" 
  android:textColor="#000000" 
  android:textSize="28sp" /> 
 
  <Button 
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content" 
  android:layout_gravity="center_horizontal" 
  android:text="Test Button" /> 
 </LinearLayout> 
 </RelativeLayout> 
 
 <LinearLayout 
 android:id="@+id/content" 
 android:layout_width="320dip" 
 android:layout_height="fill_parent" 
 android:layout_alignParentRight="true" 
 android:background="#e9e9e9" 
 android:orientation="vertical" 
 android:visibility="visible" > 
 
 <Button 
  android:id="@+id/menuButton" 
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content" 
  android:text="Menu" /> 
 
 <ListView 
  android:id="@+id/contentList" 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  android:cacheColorHint="#00000000" > 
 </ListView> 
 </LinearLayout> 
 
 <com.example.slidinglayout3d.Image3dView 
 android:id="@+id/image_3d_view" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:layout_alignParentLeft="true" 
 android:visibility="invisible" /> 
 
</com.example.slidinglayout3d.ThreeDSlidingLayout>

可以看到,在最外層的ThreeDSlidingLayout布局里面,我們放入了三個直接子布局,第一個RelativeLayout也就是左側布局了,里面簡單地放了一個TextView和一個按鈕。第二個LinearLayout是右側布局,里面放入了一個按鈕和一個ListView,都是用于顯示左側布局而準備的。第三個是Image3dView,當然是用于在滑動過程中顯示左側布局的鏡像圖片了。

最后,打開或新建MainActivity作為程序的主Activity,在里面加入如下代碼:

public class MainActivity extends Activity { 
 
 /** 
 * 側滑布局對象,用于通過手指滑動將左側的菜單布局進行顯示或隱藏。 
 */ 
 private ThreeDSlidingLayout slidingLayout; 
 
 /** 
 * menu按鈕,點擊按鈕展示左側布局,再點擊一次隱藏左側布局。 
 */ 
 private Button menuButton; 
 
 /** 
 * 放在content布局中的ListView。 
 */ 
 private ListView contentListView; 
 
 /** 
 * 作用于contentListView的適配器。 
 */ 
 private ArrayAdapter<String> contentListAdapter; 
 
 /** 
 * 用于填充contentListAdapter的數(shù)據(jù)源。 
 */ 
 private String[] contentItems = { "Content Item 1", "Content Item 2", "Content Item 3", 
  "Content Item 4", "Content Item 5", "Content Item 6", "Content Item 7", 
  "Content Item 8", "Content Item 9", "Content Item 10", "Content Item 11", 
  "Content Item 12", "Content Item 13", "Content Item 14", "Content Item 15", 
  "Content Item 16" }; 
 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
 super.onCreate(savedInstanceState); 
 setContentView(R.layout.activity_main); 
 slidingLayout = (ThreeDSlidingLayout) findViewById(R.id.slidingLayout); 
 menuButton = (Button) findViewById(R.id.menuButton); 
 contentListView = (ListView) findViewById(R.id.contentList); 
 contentListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, 
  contentItems); 
 contentListView.setAdapter(contentListAdapter); 
 // 將監(jiān)聽滑動事件綁定在contentListView上 
 slidingLayout.setScrollEvent(contentListView); 
 menuButton.setOnClickListener(new OnClickListener() { 
  @Override 
  public void onClick(View v) { 
  if (slidingLayout.isLeftLayoutVisible()) { 
   slidingLayout.scrollToRightLayout(); 
  } else { 
   slidingLayout.scrollToLeftLayout(); 
  } 
  } 
 }); 
 contentListView.setOnItemClickListener(new OnItemClickListener() { 
  @Override 
  public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
  String text = contentItems[position]; 
  Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show(); 
  } 
 }); 
 } 
}

這些代碼應該都非常簡單和眼熟了吧,和以前滑動菜單中的代碼完全一樣,調用ThreeDSlidingLayout的setScrollEvent方法,將ListView作為綁定布局傳入,這樣就可以通過拖動ListView來顯示或隱藏左側布局。并且在按鈕的點擊事件里也加入了顯示和隱藏左側布局的邏輯。

好了,這樣所有的編碼工作就已經完成了,讓我們來運行一下吧,效果如下圖所示:

Android3D如何實現(xiàn)滑動菜單

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Android3D如何實現(xiàn)滑動菜單”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業(yè)資訊頻道,更多相關知識等著你來學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI